[EEP] Add all the new llinventory windlight settings files

Also add v3colorutil.h
Also update LLQuaternion and its LLSD pieces
This commit is contained in:
Lirusaito
2019-03-24 21:36:41 -04:00
parent fdffe2e06a
commit 28c814e4ef
18 changed files with 5341 additions and 10 deletions

View File

@@ -31,16 +31,7 @@
#include "lldictionary.h"
#include "llinventorytype.h"
#include "llsingleton.h"
class LLTranslationBridge
{
public:
// clang needs this to be happy
virtual ~LLTranslationBridge() {}
virtual std::string getString(const std::string &xml_desc) = 0;
};
#include "llinvtranslationbrdg.h"
class LLWearableType
{

View File

@@ -21,12 +21,17 @@ set(llinventory_SOURCE_FILES
llfoldertype.cpp
llinventory.cpp
llinventorydefines.cpp
llinventorysettings.cpp
llinventorytype.cpp
lllandmark.cpp
llnotecard.cpp
llparcel.cpp
llpermissions.cpp
llsaleinfo.cpp
llsettingsbase.cpp
llsettingsdaycycle.cpp
llsettingssky.cpp
llsettingswater.cpp
lltransactionflags.cpp
lluserrelations.cpp
)
@@ -39,7 +44,9 @@ set(llinventory_HEADER_FILES
llfoldertype.h
llinventory.h
llinventorydefines.h
llinventorysettings.h
llinventorytype.h
llinvtranslationbrdg.h
lllandmark.h
llnotecard.h
llparcel.h
@@ -47,6 +54,10 @@ set(llinventory_HEADER_FILES
llpermissions.h
llpermissionsflags.h
llsaleinfo.h
llsettingsbase.h
llsettingsdaycycle.h
llsettingssky.h
llsettingswater.h
lltransactionflags.h
lltransactiontypes.h
lluserrelations.h

View File

@@ -0,0 +1,117 @@
/**
* @file llinventorysettings.cpp
* @author optional
* @brief A base class for asset based settings groups.
*
* $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 "linden_common.h"
#include "llinventorysettings.h"
#include "llinventorytype.h"
#include "llinventorydefines.h"
#include "lldictionary.h"
#include "llsingleton.h"
#include "llinvtranslationbrdg.h"
//=========================================================================
namespace {
LLTranslationBridge::ptr_t sTranslator;
}
//=========================================================================
struct SettingsEntry : public LLDictionaryEntry
{
SettingsEntry(const std::string &name,
const std::string& default_new_name,
LLInventoryType::EIconName iconName) :
LLDictionaryEntry(name),
mDefaultNewName(default_new_name),
mLabel(name),
mIconName(iconName)
{
std::string transdname = sTranslator->getString(mLabel);
if (!transdname.empty())
{
mLabel = transdname;
}
}
std::string mLabel;
std::string mDefaultNewName; //keep mLabel for backward compatibility
LLInventoryType::EIconName mIconName;
};
class LLSettingsDictionary : public LLSingleton<LLSettingsDictionary>,
public LLDictionary<LLSettingsType::type_e, SettingsEntry>
{
friend class LLSingleton<LLSettingsDictionary>; \
LLSettingsDictionary();
void initSingleton();
};
LLSettingsDictionary::LLSettingsDictionary()
{
}
void LLSettingsDictionary::initSingleton()
{
addEntry(LLSettingsType::ST_SKY, new SettingsEntry("sky", "New Sky", LLInventoryType::ICONNAME_SETTINGS_SKY));
addEntry(LLSettingsType::ST_WATER, new SettingsEntry("water", "New Water", LLInventoryType::ICONNAME_SETTINGS_WATER));
addEntry(LLSettingsType::ST_DAYCYCLE, new SettingsEntry("day", "New Day", LLInventoryType::ICONNAME_SETTINGS_DAY));
addEntry(LLSettingsType::ST_NONE, new SettingsEntry("none", "New Settings", LLInventoryType::ICONNAME_SETTINGS));
addEntry(LLSettingsType::ST_INVALID, new SettingsEntry("invalid", "New Settings", LLInventoryType::ICONNAME_SETTINGS));
}
//=========================================================================
LLSettingsType::type_e LLSettingsType::fromInventoryFlags(U32 flags)
{
return (LLSettingsType::type_e)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK);
}
LLInventoryType::EIconName LLSettingsType::getIconName(LLSettingsType::type_e type)
{
const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type);
if (!entry)
return getIconName(ST_INVALID);
return entry->mIconName;
}
std::string LLSettingsType::getDefaultName(LLSettingsType::type_e type)
{
const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type);
if (!entry)
return getDefaultName(ST_INVALID);
return entry->mDefaultNewName;
}
void LLSettingsType::initClass(LLTranslationBridge::ptr_t &trans)
{
sTranslator = trans;
}
void LLSettingsType::cleanupClass()
{
sTranslator.reset();
}

View File

@@ -0,0 +1,56 @@
/**
* @file llinventorysettings.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $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$
*/
#ifndef LL_INVENTORY_SETTINGS_H
#define LL_INVENTORY_SETTINGS_H
#include "llinventorytype.h"
#include "llinvtranslationbrdg.h"
class LLSettingsType
{
public:
enum type_e
{
ST_SKY = 0,
ST_WATER = 1,
ST_DAYCYCLE = 2,
ST_INVALID = 255,
ST_NONE = -1
};
static type_e fromInventoryFlags(U32 flags);
static LLInventoryType::EIconName getIconName(type_e type);
static std::string getDefaultName(type_e type);
static void initClass(LLTranslationBridge::ptr_t &trans);
static void cleanupClass();
};
#endif

View File

@@ -0,0 +1,41 @@
/**
* @file llinvtranslationbrdg.h
* @brief Translation adapter for inventory.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
*/
#ifndef LL_TRANSLATIONBRDG_H
#define LL_TRANSLATIONBRDG_H
class LLTranslationBridge
{
public:
typedef std::shared_ptr<LLTranslationBridge> ptr_t;
// clang needs this to be happy
virtual ~LLTranslationBridge() {}
virtual std::string getString(const std::string &xml_desc) = 0;
};
#endif

View File

@@ -40,6 +40,7 @@
#include "llpermissions.h"
#include "lltimer.h"
#include "v3math.h"
#include "llsettingsdaycycle.h"
// Grid out of which parcels taken is stepped every 4 meters.
const F32 PARCEL_GRID_STEP_METERS = 4.f;

View File

@@ -0,0 +1,758 @@
/**
* @file llsettingsbase.cpp
* @author optional
* @brief A base class for asset based settings groups.
*
* $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 "llsettingsbase.h"
#include "llmath.h"
#include <algorithm>
#include "llsdserialize.h"
//=========================================================================
namespace
{
const LLSettingsBase::TrackPosition BREAK_POINT = 0.5;
}
const LLSettingsBase::TrackPosition LLSettingsBase::INVALID_TRACKPOS(-1.0);
//=========================================================================
std::ostream &operator <<(std::ostream& os, LLSettingsBase &settings)
{
LLSDSerialize::serialize(settings.getSettings(), os, LLSDSerialize::LLSD_NOTATION);
return os;
}
//=========================================================================
const std::string LLSettingsBase::SETTING_ID("id");
const std::string LLSettingsBase::SETTING_NAME("name");
const std::string LLSettingsBase::SETTING_HASH("hash");
const std::string LLSettingsBase::SETTING_TYPE("type");
const std::string LLSettingsBase::SETTING_ASSETID("asset_id");
const std::string LLSettingsBase::SETTING_FLAGS("flags");
const U32 LLSettingsBase::FLAG_NOCOPY(0x01 << 0);
const U32 LLSettingsBase::FLAG_NOMOD(0x01 << 1);
const U32 LLSettingsBase::FLAG_NOTRANS(0x01 << 2);
const U32 LLSettingsBase::Validator::VALIDATION_PARTIAL(0x01 << 0);
//=========================================================================
LLSettingsBase::LLSettingsBase():
mSettings(LLSD::emptyMap()),
mDirty(true),
mAssetID(),
mBlendedFactor(0.0)
{
}
LLSettingsBase::LLSettingsBase(const LLSD setting) :
mSettings(setting),
mDirty(true),
mAssetID(),
mBlendedFactor(0.0)
{
}
//=========================================================================
void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F64 mix)
{
mSettings = interpolateSDMap(mSettings, other.mSettings, other.getParameterMap(), mix);
setDirtyFlag(true);
}
LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) const
{
LLSD newSettings;
for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it)
{
std::string key_name = (*it).first;
LLSD value = (*it).second;
LLSD::Type setting_type = value.type();
switch (setting_type)
{
case LLSD::TypeMap:
newSettings[key_name] = combineSDMaps(value, LLSD());
break;
case LLSD::TypeArray:
newSettings[key_name] = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
{
newSettings[key_name].append(*ita);
}
break;
//case LLSD::TypeInteger:
//case LLSD::TypeReal:
//case LLSD::TypeBoolean:
//case LLSD::TypeString:
//case LLSD::TypeUUID:
//case LLSD::TypeURI:
//case LLSD::TypeDate:
//case LLSD::TypeBinary:
default:
newSettings[key_name] = value;
break;
}
}
if (!other.isUndefined())
{
for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
{
std::string key_name = (*it).first;
LLSD value = (*it).second;
LLSD::Type setting_type = value.type();
switch (setting_type)
{
case LLSD::TypeMap:
newSettings[key_name] = combineSDMaps(value, LLSD());
break;
case LLSD::TypeArray:
newSettings[key_name] = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
{
newSettings[key_name].append(*ita);
}
break;
//case LLSD::TypeInteger:
//case LLSD::TypeReal:
//case LLSD::TypeBoolean:
//case LLSD::TypeString:
//case LLSD::TypeUUID:
//case LLSD::TypeURI:
//case LLSD::TypeDate:
//case LLSD::TypeBinary:
default:
newSettings[key_name] = value;
break;
}
}
}
return newSettings;
}
LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, F64 mix) const
{
LLSD newSettings;
stringset_t skip = getSkipInterpolateKeys();
stringset_t slerps = getSlerpKeys();
for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it)
{
std::string key_name = (*it).first;
LLSD value = (*it).second;
if (skip.find(key_name) != skip.end())
continue;
LLSD other_value;
if (other.has(key_name))
{
other_value = other[key_name];
}
else
{
parammapping_t::const_iterator def_iter = defaults.find(key_name);
if (def_iter != defaults.end())
{
other_value = def_iter->second.getDefaultValue();
}
else if (value.type() == LLSD::TypeMap)
{
// interpolate in case there are defaults inside (part of legacy)
other_value = LLSDMap();
}
else
{
// The other or defaults does not contain this setting, keep the original value
// TODO: Should I blend this out instead?
newSettings[key_name] = value;
continue;
}
}
newSettings[key_name] = interpolateSDValue(key_name, value, other_value, defaults, mix, slerps);
}
// Special handling cases
// Flags
if (settings.has(SETTING_FLAGS))
{
U32 flags = (U32)settings[SETTING_FLAGS].asInteger();
if (other.has(SETTING_FLAGS))
flags |= (U32)other[SETTING_FLAGS].asInteger();
newSettings[SETTING_FLAGS] = LLSD::Integer(flags);
}
// Now add anything that is in other but not in the settings
for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
{
std::string key_name = (*it).first;
if (skip.find(key_name) != skip.end())
continue;
if (settings.has(key_name))
continue;
parammapping_t::const_iterator def_iter = defaults.find(key_name);
if (def_iter != defaults.end())
{
// Blend against default value
newSettings[key_name] = interpolateSDValue(key_name, def_iter->second.getDefaultValue(), (*it).second, defaults, mix, slerps);
}
else if ((*it).second.type() == LLSD::TypeMap)
{
// interpolate in case there are defaults inside (part of legacy)
newSettings[key_name] = interpolateSDValue(key_name, LLSDMap(), (*it).second, defaults, mix, slerps);
}
// else do nothing when no known defaults
// TODO: Should I blend this out instead?
}
// Note: writes variables from skip list, bug?
for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
{
// TODO: Should I blend this in instead?
if (skip.find((*it).first) == skip.end())
continue;
if (!settings.has((*it).first))
continue;
newSettings[(*it).first] = (*it).second;
}
return newSettings;
}
LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD &value, const LLSD &other_value, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const
{
LLSD new_value;
LLSD::Type setting_type = value.type();
if (other_value.type() != setting_type)
{
// The data type mismatched between this and other. Hard switch when we pass the break point
// but issue a warning.
LL_WARNS("SETTINGS") << "Setting lerp between mismatched types for '" << key_name << "'." << LL_ENDL;
new_value = (mix > BREAK_POINT) ? other_value : value;
}
switch (setting_type)
{
case LLSD::TypeInteger:
// lerp between the two values rounding the result to the nearest integer.
new_value = LLSD::Integer(llroundf(lerp(value.asReal(), other_value.asReal(), mix)));
break;
case LLSD::TypeReal:
// lerp between the two values.
new_value = LLSD::Real(lerp(value.asReal(), other_value.asReal(), mix));
break;
case LLSD::TypeMap:
// deep copy.
new_value = interpolateSDMap(value, other_value, defaults, mix);
break;
case LLSD::TypeArray:
{
LLSD new_array(LLSD::emptyArray());
if (slerps.find(key_name) != slerps.end())
{
LLQuaternion a(value);
LLQuaternion b(other_value);
LLQuaternion q = slerp(mix, a, b);
new_array = q.getValue();
}
else
{ // TODO: We could expand this to inspect the type and do a deep lerp based on type.
// for now assume a heterogeneous array of reals.
size_t len = std::max(value.size(), other_value.size());
for (size_t i = 0; i < len; ++i)
{
new_array[i] = lerp(value[i].asReal(), other_value[i].asReal(), mix);
}
}
new_value = new_array;
}
break;
case LLSD::TypeUUID:
new_value = value.asUUID();
break;
// case LLSD::TypeBoolean:
// case LLSD::TypeString:
// case LLSD::TypeURI:
// case LLSD::TypeBinary:
// case LLSD::TypeDate:
default:
// atomic or unknown data types. Lerping between them does not make sense so switch at the break.
new_value = (mix > BREAK_POINT) ? other_value : value;
break;
}
return new_value;
}
LLSettingsBase::stringset_t LLSettingsBase::getSkipInterpolateKeys() const
{
static stringset_t skipSet;
if (skipSet.empty())
{
skipSet.insert(SETTING_FLAGS);
skipSet.insert(SETTING_HASH);
}
return skipSet;
}
LLSD LLSettingsBase::getSettings() const
{
return mSettings;
}
LLSD LLSettingsBase::cloneSettings() const
{
return combineSDMaps(getSettings(), LLSD());
}
size_t LLSettingsBase::getHash() const
{ // get a shallow copy of the LLSD filtering out values to not include in the hash
LLSD hash_settings = llsd_shallow(getSettings(),
LLSDMap(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false)("*", true));
boost::hash<LLSD> hasher;
return hasher(hash_settings);
}
bool LLSettingsBase::validate()
{
validation_list_t validations = getValidationList();
if (!mSettings.has(SETTING_TYPE))
{
mSettings[SETTING_TYPE] = getSettingsType();
}
LLSD result = LLSettingsBase::settingValidation(mSettings, validations);
if (result["errors"].size() > 0)
{
LL_WARNS("SETTINGS") << "Validation errors: " << result["errors"] << LL_ENDL;
}
if (result["warnings"].size() > 0)
{
LL_DEBUGS("SETTINGS") << "Validation warnings: " << result["warnings"] << LL_ENDL;
}
return result["success"].asBoolean();
}
LLSD LLSettingsBase::settingValidation(LLSD &settings, validation_list_t &validations, bool partial)
{
static Validator validateName(SETTING_NAME, false, LLSD::TypeString, boost::bind(&Validator::verifyStringLength, _1, 32));
static Validator validateId(SETTING_ID, false, LLSD::TypeUUID);
static Validator validateHash(SETTING_HASH, false, LLSD::TypeInteger);
static Validator validateType(SETTING_TYPE, false, LLSD::TypeString);
static Validator validateAssetId(SETTING_ASSETID, false, LLSD::TypeUUID);
static Validator validateFlags(SETTING_FLAGS, false, LLSD::TypeInteger);
stringset_t validated;
stringset_t strip;
bool isValid(true);
LLSD errors(LLSD::emptyArray());
LLSD warnings(LLSD::emptyArray());
U32 flags(0);
if (partial)
flags |= Validator::VALIDATION_PARTIAL;
// Fields common to all settings.
if (!validateName.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'name'.") );
isValid = false;
}
validated.insert(validateName.getName());
if (!validateId.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'id'.") );
isValid = false;
}
validated.insert(validateId.getName());
if (!validateHash.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'hash'.") );
isValid = false;
}
validated.insert(validateHash.getName());
if (!validateAssetId.verify(settings, flags))
{
errors.append(LLSD::String("Invalid asset Id"));
isValid = false;
}
validated.insert(validateAssetId.getName());
if (!validateType.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'type'.") );
isValid = false;
}
validated.insert(validateType.getName());
if (!validateFlags.verify(settings, flags))
{
errors.append(LLSD::String("Unable to validate 'flags'."));
isValid = false;
}
validated.insert(validateFlags.getName());
// Fields for specific settings.
for (validation_list_t::iterator itv = validations.begin(); itv != validations.end(); ++itv)
{
#ifdef VALIDATION_DEBUG
LLSD oldvalue;
if (settings.has((*itv).getName()))
{
oldvalue = llsd_clone(mSettings[(*itv).getName()]);
}
#endif
if (!(*itv).verify(settings, flags))
{
std::stringstream errtext;
errtext << "Settings LLSD fails validation and could not be corrected for '" << (*itv).getName() << "'!\n";
errors.append( errtext.str() );
isValid = false;
}
validated.insert((*itv).getName());
#ifdef VALIDATION_DEBUG
if (!oldvalue.isUndefined())
{
if (!compare_llsd(settings[(*itv).getName()], oldvalue))
{
LL_WARNS("SETTINGS") << "Setting '" << (*itv).getName() << "' was changed: " << oldvalue << " -> " << settings[(*itv).getName()] << LL_ENDL;
}
}
#endif
}
// strip extra entries
for (LLSD::map_const_iterator itm = settings.beginMap(); itm != settings.endMap(); ++itm)
{
if (validated.find((*itm).first) == validated.end())
{
std::stringstream warntext;
warntext << "Stripping setting '" << (*itm).first << "'";
warnings.append( warntext.str() );
strip.insert((*itm).first);
}
}
for (stringset_t::iterator its = strip.begin(); its != strip.end(); ++its)
{
settings.erase(*its);
}
return LLSDMap("success", LLSD::Boolean(isValid))
("errors", errors)
("warnings", warnings);
}
//=========================================================================
bool LLSettingsBase::Validator::verify(LLSD &data, U32 flags)
{
if (!data.has(mName) || (data.has(mName) && data[mName].isUndefined()))
{
if ((flags & VALIDATION_PARTIAL) != 0) // we are doing a partial validation. Do no attempt to set a default if missing (or fail even if required)
return true;
if (!mDefault.isUndefined())
{
data[mName] = mDefault;
return true;
}
if (mRequired)
LL_WARNS("SETTINGS") << "Missing required setting '" << mName << "' with no default." << LL_ENDL;
return !mRequired;
}
if (data[mName].type() != mType)
{
LL_WARNS("SETTINGS") << "Setting '" << mName << "' is incorrect type." << LL_ENDL;
return false;
}
if (!mVerify.empty() && !mVerify(data[mName]))
{
LL_WARNS("SETTINGS") << "Setting '" << mName << "' fails validation." << LL_ENDL;
return false;
}
return true;
}
bool LLSettingsBase::Validator::verifyColor(LLSD &value)
{
return (value.size() == 3 || value.size() == 4);
}
bool LLSettingsBase::Validator::verifyVector(LLSD &value, S32 length)
{
return (value.size() == length);
}
bool LLSettingsBase::Validator::verifyVectorNormalized(LLSD &value, S32 length)
{
if (value.size() != length)
return false;
LLSD newvector;
switch (length)
{
case 2:
{
LLVector2 vect(value);
if (is_approx_equal(vect.normalize(), 1.0f))
return true;
newvector = vect.getValue();
break;
}
case 3:
{
LLVector3 vect(value);
if (is_approx_equal(vect.normalize(), 1.0f))
return true;
newvector = vect.getValue();
break;
}
case 4:
{
LLVector4 vect(value);
if (is_approx_equal(vect.normalize(), 1.0f))
return true;
newvector = vect.getValue();
break;
}
default:
return false;
}
return true;
}
bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals)
{
for (S32 index = 0; index < value.size(); ++index)
{
if (minvals[index].asString() != "*")
{
if (minvals[index].asReal() > value[index].asReal())
{
value[index] = minvals[index].asReal();
}
}
if (maxvals[index].asString() != "*")
{
if (maxvals[index].asReal() < value[index].asReal())
{
value[index] = maxvals[index].asReal();
}
}
}
return true;
}
bool LLSettingsBase::Validator::verifyQuaternion(LLSD &value)
{
return (value.size() == 4);
}
bool LLSettingsBase::Validator::verifyQuaternionNormal(LLSD &value)
{
if (value.size() != 4)
return false;
LLQuaternion quat(value);
if (is_approx_equal(quat.normalize(), 1.0f))
return true;
LLSD newquat = quat.getValue();
for (S32 index = 0; index < 4; ++index)
{
value[index] = newquat[index];
}
return true;
}
bool LLSettingsBase::Validator::verifyFloatRange(LLSD &value, LLSD range)
{
F64 real = value.asReal();
F64 clampedval = llclamp(LLSD::Real(real), range[0].asReal(), range[1].asReal());
if (is_approx_equal(clampedval, real))
return true;
value = LLSD::Real(clampedval);
return true;
}
bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range)
{
S32 ival = value.asInteger();
S32 clampedval = llclamp(LLSD::Integer(ival), range[0].asInteger(), range[1].asInteger());
if (clampedval == ival)
return true;
value = LLSD::Integer(clampedval);
return true;
}
bool LLSettingsBase::Validator::verifyStringLength(LLSD &value, S32 length)
{
std::string sval = value.asString();
if (!sval.empty())
{
sval = sval.substr(0, length);
value = LLSD::String(sval);
}
return true;
}
//=========================================================================
void LLSettingsBlender::update(const LLSettingsBase::BlendFactor& blendf)
{
F64 res = setBlendFactor(blendf);
if ((res >= 0.0001) && (res < 1.0))
mTarget->update();
}
F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_in)
{
LLSettingsBase::TrackPosition blendf = blendf_in;
if (blendf >= 1.0)
{
triggerComplete();
return 1.0;
}
blendf = llclamp(blendf, 0.0f, 1.0f);
if (mTarget)
{
mTarget->replaceSettings(mInitial->getSettings());
if (!mFinal || (mInitial == mFinal) || (blendf == 0.0))
{ // this is a trivial blend. Results will be identical to the initial.
return blendf;
}
mTarget->blend(mFinal, blendf);
}
else
{
LL_WARNS("SETTINGS") << "No target for settings blender." << LL_ENDL;
}
return blendf;
}
void LLSettingsBlender::triggerComplete()
{
if (mTarget)
mTarget->replaceSettings(mFinal->getSettings());
LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon
mTarget->update();
mOnFinished(shared_from_this());
}
//-------------------------------------------------------------------------
const LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::MIN_BLEND_DELTA(0.001);
LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const
{
return LLSettingsBase::BlendFactor(fmod((F64)spanpos, (F64)spanlen) / (F64)spanlen);
}
bool LLSettingsBlenderTimeDelta::applyTimeDelta(const LLSettingsBase::Seconds& timedelta)
{
mTimeSpent += timedelta;
mTimeDeltaPassed += timedelta;
if (mTimeSpent > mBlendSpan)
{
mIgnoreTimeDelta = false;
triggerComplete();
return false;
}
if ((mTimeDeltaPassed < mTimeDeltaThreshold) && (!mIgnoreTimeDelta))
{
return false;
}
LLSettingsBase::BlendFactor blendf = calculateBlend(mTimeSpent, mBlendSpan);
mTimeDeltaPassed = LLSettingsBase::Seconds(0.0);
if (fabs(mLastBlendF - blendf) < mBlendFMinDelta)
{
return false;
}
mLastBlendF = blendf;
update(blendf);
return true;
}

View File

@@ -0,0 +1,538 @@
/**
* @file llsettingsbase.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $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$
*/
#ifndef LL_SETTINGS_BASE_H
#define LL_SETTINGS_BASE_H
#include <string>
#include <map>
#include <vector>
#include <boost/signals2.hpp>
#include "llsd.h"
#include "llsdutil.h"
#include "v2math.h"
#include "v3math.h"
#include "v4math.h"
#include "llquaternion.h"
#include "v4color.h"
#include "v3color.h"
#include "llunits.h"
#include "llinventorysettings.h"
#define PTR_NAMESPACE std
#define SETTINGS_OVERRIDE override
class LLSettingsBase :
public PTR_NAMESPACE::enable_shared_from_this<LLSettingsBase>,
private boost::noncopyable
{
friend class LLEnvironment;
friend class LLSettingsDay;
friend std::ostream &operator <<(std::ostream& os, LLSettingsBase &settings);
protected:
LOG_CLASS(LLSettingsBase);
public:
typedef F64Seconds Seconds;
typedef F64 BlendFactor;
typedef F32 TrackPosition; // 32-bit as these are stored in LLSD as such
static const TrackPosition INVALID_TRACKPOS;
static const std::string SETTING_ID;
static const std::string SETTING_NAME;
static const std::string SETTING_HASH;
static const std::string SETTING_TYPE;
static const std::string SETTING_ASSETID;
static const std::string SETTING_FLAGS;
static const U32 FLAG_NOCOPY;
static const U32 FLAG_NOMOD;
static const U32 FLAG_NOTRANS;
class DefaultParam
{
public:
DefaultParam(S32 key, const LLSD& value) : mShaderKey(key), mDefaultValue(value) {}
DefaultParam() : mShaderKey(-1) {}
S32 getShaderKey() const { return mShaderKey; }
const LLSD getDefaultValue() const { return mDefaultValue; }
private:
S32 mShaderKey;
LLSD mDefaultValue;
};
// Contains settings' names (map key), related shader id-key and default
// value for revert in case we need to reset shader (no need to search each time)
typedef std::map<std::string, DefaultParam> parammapping_t;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsBase> ptr_t;
virtual ~LLSettingsBase() { };
//---------------------------------------------------------------------
virtual std::string getSettingsType() const = 0;
virtual LLSettingsType::type_e getSettingsTypeValue() const = 0;
//---------------------------------------------------------------------
// Settings status
inline bool hasSetting(const std::string &param) const { return mSettings.has(param); }
virtual bool isDirty() const { return mDirty; }
virtual bool isVeryDirty() const { return mReplaced; }
inline void setDirtyFlag(bool dirty) { mDirty = dirty; clearAssetId(); }
size_t getHash() const; // Hash will not include Name, ID or a previously stored Hash
inline LLUUID getId() const
{
return getValue(SETTING_ID).asUUID();
}
inline std::string getName() const
{
return getValue(SETTING_NAME).asString();
}
inline void setName(std::string val)
{
setValue(SETTING_NAME, val);
}
inline LLUUID getAssetId() const
{
if (mSettings.has(SETTING_ASSETID))
return mSettings[SETTING_ASSETID].asUUID();
return LLUUID();
}
inline U32 getFlags() const
{
if (mSettings.has(SETTING_FLAGS))
return static_cast<U32>(mSettings[SETTING_FLAGS].asInteger());
return 0;
}
inline void setFlags(U32 value)
{
setLLSD(SETTING_FLAGS, LLSD::Integer(value));
}
inline bool getFlag(U32 flag) const
{
if (mSettings.has(SETTING_FLAGS))
return ((U32)mSettings[SETTING_FLAGS].asInteger() & flag) == flag;
return false;
}
inline void setFlag(U32 flag)
{
U32 flags((mSettings.has(SETTING_FLAGS)) ? (U32)mSettings[SETTING_FLAGS].asInteger() : 0);
flags |= flag;
if (flags)
mSettings[SETTING_FLAGS] = LLSD::Integer(flags);
else
mSettings.erase(SETTING_FLAGS);
}
inline void clearFlag(U32 flag)
{
U32 flags((mSettings.has(SETTING_FLAGS)) ? (U32)mSettings[SETTING_FLAGS].asInteger() : 0);
flags &= ~flag;
if (flags)
mSettings[SETTING_FLAGS] = LLSD::Integer(flags);
else
mSettings.erase(SETTING_FLAGS);
}
virtual void replaceSettings(LLSD settings)
{
mBlendedFactor = 0.0;
setDirtyFlag(true);
mReplaced = true;
mSettings = settings;
}
virtual LLSD getSettings() const;
//---------------------------------------------------------------------
//
inline void setLLSD(const std::string &name, const LLSD &value)
{
mSettings[name] = value;
mDirty = true;
if (name != SETTING_ASSETID)
clearAssetId();
}
inline void setValue(const std::string &name, const LLSD &value)
{
setLLSD(name, value);
}
inline LLSD getValue(const std::string &name, const LLSD &deflt = LLSD()) const
{
if (!mSettings.has(name))
return deflt;
return mSettings[name];
}
inline void setValue(const std::string &name, F32 v)
{
setLLSD(name, LLSD::Real(v));
}
inline void setValue(const std::string &name, const LLVector2 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLVector3 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLVector4 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLQuaternion &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLColor3 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLColor4 &value)
{
setValue(name, value.getValue());
}
inline BlendFactor getBlendFactor() const
{
return mBlendedFactor;
}
// Note this method is marked const but may modify the settings object.
// (note the internal const cast). This is so that it may be called without
// special consideration from getters.
inline void update() const
{
if ((!mDirty) && (!mReplaced))
return;
(const_cast<LLSettingsBase *>(this))->updateSettings();
}
virtual void blend(const ptr_t &end, BlendFactor blendf) = 0;
virtual bool validate();
virtual ptr_t buildDerivedClone() const = 0;
class Validator
{
public:
static const U32 VALIDATION_PARTIAL;
typedef boost::function<bool(LLSD &)> verify_pr;
Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr(), LLSD defval = LLSD()) :
mName(name),
mRequired(required),
mType(type),
mVerify(verify),
mDefault(defval)
{ }
std::string getName() const { return mName; }
bool isRequired() const { return mRequired; }
LLSD::Type getType() const { return mType; }
bool verify(LLSD &data, U32 flags);
// Some basic verifications
static bool verifyColor(LLSD &value);
static bool verifyVector(LLSD &value, S32 length);
static bool verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals);
static bool verifyVectorNormalized(LLSD &value, S32 length);
static bool verifyQuaternion(LLSD &value);
static bool verifyQuaternionNormal(LLSD &value);
static bool verifyFloatRange(LLSD &value, LLSD range);
static bool verifyIntegerRange(LLSD &value, LLSD range);
static bool verifyStringLength(LLSD &value, S32 length);
private:
std::string mName;
bool mRequired;
LLSD::Type mType;
verify_pr mVerify;
LLSD mDefault;
};
typedef std::vector<Validator> validation_list_t;
static LLSD settingValidation(LLSD &settings, validation_list_t &validations, bool partial = false);
inline void setAssetId(LLUUID value)
{ // note that this skips setLLSD
mSettings[SETTING_ASSETID] = value;
}
inline void clearAssetId()
{
if (mSettings.has(SETTING_ASSETID))
mSettings.erase(SETTING_ASSETID);
}
// Calculate any custom settings that may need to be cached.
virtual void updateSettings() { mDirty = false; mReplaced = false; }
protected:
LLSettingsBase();
LLSettingsBase(const LLSD setting);
static LLSD settingValidation(LLSD settings);
typedef std::set<std::string> stringset_t;
// combining settings objects. Customize for specific setting types
virtual void lerpSettings(const LLSettingsBase &other, BlendFactor mix);
// combining settings maps where it can based on mix rate
// @settings initial value (mix==0)
// @other target value (mix==1)
// @defaults list of default values for legacy fields and (re)setting shaders
// @mix from 0 to 1, ratio or rate of transition from initial 'settings' to 'other'
// return interpolated and combined LLSD map
LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, BlendFactor mix) const;
LLSD interpolateSDValue(const std::string& name, const LLSD &value, const LLSD &other, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const;
/// when lerping between settings, some may require special handling.
/// Get a list of these key to be skipped by the default settings lerp.
/// (handling should be performed in the override of lerpSettings.
virtual stringset_t getSkipInterpolateKeys() const;
// A list of settings that represent quaternions and should be slerped
// rather than lerped.
virtual stringset_t getSlerpKeys() const { return stringset_t(); }
virtual validation_list_t getValidationList() const = 0;
// Apply any settings that need special handling.
virtual void applySpecial(void *) { };
virtual parammapping_t getParameterMap() const { return parammapping_t(); }
LLSD mSettings;
bool mIsValid;
LLAssetID mAssetID;
LLSD cloneSettings() const;
inline void setBlendFactor(BlendFactor blendfactor)
{
mBlendedFactor = blendfactor;
}
void replaceWith(LLSettingsBase::ptr_t other)
{
replaceSettings(other->cloneSettings());
setBlendFactor(other->getBlendFactor());
}
private:
bool mDirty;
bool mReplaced; // super dirty!
LLSD combineSDMaps(const LLSD &first, const LLSD &other) const;
BlendFactor mBlendedFactor;
};
class LLSettingsBlender : public PTR_NAMESPACE::enable_shared_from_this<LLSettingsBlender>
{
LOG_CLASS(LLSettingsBlender);
public:
typedef PTR_NAMESPACE::shared_ptr<LLSettingsBlender> ptr_t;
typedef boost::signals2::signal<void(const ptr_t )> finish_signal_t;
typedef boost::signals2::connection connection_t;
LLSettingsBlender(const LLSettingsBase::ptr_t &target,
const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting) :
mOnFinished(),
mTarget(target),
mInitial(initsetting),
mFinal(endsetting)
{
if (mInitial && mTarget)
mTarget->replaceSettings(mInitial->getSettings());
if (!mFinal)
mFinal = mInitial;
}
virtual ~LLSettingsBlender() {}
virtual void reset( LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::TrackPosition&)
{
// note: the 'span' reset parameter is unused by the base class.
if (!mInitial)
LL_WARNS("BLENDER") << "Reseting blender with empty initial setting. Expect badness in the future." << LL_ENDL;
mInitial = initsetting;
mFinal = endsetting;
if (!mFinal)
mFinal = mInitial;
if (mTarget)
mTarget->replaceSettings(mInitial->getSettings());
}
LLSettingsBase::ptr_t getTarget() const
{
return mTarget;
}
LLSettingsBase::ptr_t getInitial() const
{
return mInitial;
}
LLSettingsBase::ptr_t getFinal() const
{
return mFinal;
}
connection_t setOnFinished(const finish_signal_t::slot_type &onfinished)
{
return mOnFinished.connect(onfinished);
}
virtual void update(const LLSettingsBase::BlendFactor& blendf);
virtual bool applyTimeDelta(const LLSettingsBase::Seconds& timedelta)
{
llassert(false);
// your derived class needs to implement an override of this func
return false;
}
virtual F64 setBlendFactor(const LLSettingsBase::BlendFactor& position);
virtual void switchTrack(S32 trackno, const LLSettingsBase::TrackPosition& position) { /*NoOp*/ }
protected:
void triggerComplete();
finish_signal_t mOnFinished;
LLSettingsBase::ptr_t mTarget;
LLSettingsBase::ptr_t mInitial;
LLSettingsBase::ptr_t mFinal;
};
class LLSettingsBlenderTimeDelta : public LLSettingsBlender
{
LOG_CLASS(LLSettingsBlenderTimeDelta);
public:
static const LLSettingsBase::BlendFactor MIN_BLEND_DELTA;
LLSettingsBlenderTimeDelta(const LLSettingsBase::ptr_t &target,
const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::Seconds& blend_span) :
LLSettingsBlender(target, initsetting, endsetting),
mBlendSpan(blend_span),
mLastUpdate(0.0f),
mTimeSpent(0.0f),
mTimeDeltaThreshold(0.0f),
mTimeDeltaPassed(0.0f),
mIgnoreTimeDelta(false),
mBlendFMinDelta(MIN_BLEND_DELTA),
mLastBlendF(-1.0f)
{
mTimeStart = LLSettingsBase::Seconds(LLDate::now().secondsSinceEpoch());
mLastUpdate = mTimeStart;
}
virtual ~LLSettingsBlenderTimeDelta()
{
}
virtual void reset(LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::TrackPosition& blend_span) SETTINGS_OVERRIDE
{
LLSettingsBlender::reset(initsetting, endsetting, blend_span);
mBlendSpan = blend_span;
mTimeStart = LLSettingsBase::Seconds(LLDate::now().secondsSinceEpoch());
mLastUpdate = mTimeStart;
mTimeSpent = LLSettingsBase::Seconds(0.0f);
mTimeDeltaPassed = LLSettingsBase::Seconds(0.0f);
mLastBlendF = LLSettingsBase::BlendFactor(-1.0f);
}
virtual bool applyTimeDelta(const LLSettingsBase::Seconds& timedelta) SETTINGS_OVERRIDE;
inline void setTimeDeltaThreshold(const LLSettingsBase::Seconds time)
{
mTimeDeltaThreshold = time;
mTimeDeltaPassed = time + LLSettingsBase::Seconds(1.0); // take the next update call.
}
inline LLSettingsBase::Seconds getTimeDeltaThreshold() const
{
return mTimeDeltaThreshold;
}
inline void setIgnoreTimeDeltaThreshold(bool val) { mIgnoreTimeDelta = val; }
inline bool getIgnoreTimeDeltaThreshold() const { return mIgnoreTimeDelta; }
inline void setTimeSpent(LLSettingsBase::Seconds time) { mTimeSpent = time; }
protected:
LLSettingsBase::BlendFactor calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const;
LLSettingsBase::TrackPosition mBlendSpan;
LLSettingsBase::Seconds mLastUpdate;
LLSettingsBase::Seconds mTimeSpent;
LLSettingsBase::Seconds mTimeStart;
LLSettingsBase::Seconds mTimeDeltaThreshold;
LLSettingsBase::Seconds mTimeDeltaPassed;
bool mIgnoreTimeDelta;
LLSettingsBase::BlendFactor mBlendFMinDelta;
LLSettingsBase::BlendFactor mLastBlendF;
};
#endif

View File

@@ -0,0 +1,891 @@
/**
* @file llsettingsdaycycle.cpp
* @author optional
* @brief A base class for asset based settings groups.
*
* $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 "llsettingsdaycycle.h"
#include "llerror.h"
#include <algorithm>
#include <boost/make_shared.hpp>
#include "llfasttimer.h"
#include "v3colorutil.h"
#include "llsettingssky.h"
#include "llsettingswater.h"
#include "llframetimer.h"
//=========================================================================
namespace
{
LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment");
LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment");
template<typename T>
inline T get_wrapping_distance(T begin, T end)
{
if (begin < end)
{
return end - begin;
}
else if (begin > end)
{
return T(1.0) - (begin - end);
}
return 0;
}
LLSettingsDay::CycleTrack_t::iterator get_wrapping_atafter(LLSettingsDay::CycleTrack_t &collection, const LLSettingsBase::TrackPosition& key)
{
if (collection.empty())
return collection.end();
LLSettingsDay::CycleTrack_t::iterator it = collection.upper_bound(key);
if (it == collection.end())
{ // wrap around
it = collection.begin();
}
return it;
}
LLSettingsDay::CycleTrack_t::iterator get_wrapping_atbefore(LLSettingsDay::CycleTrack_t &collection, const LLSettingsBase::TrackPosition& key)
{
if (collection.empty())
return collection.end();
LLSettingsDay::CycleTrack_t::iterator it = collection.lower_bound(key);
if (it == collection.end())
{ // all keyframes are lower, take the last one.
--it; // we know the range is not empty
}
else if ((*it).first > key)
{ // the keyframe we are interested in is smaller than the found.
if (it == collection.begin())
it = collection.end();
--it;
}
return it;
}
}
//=========================================================================
const std::string LLSettingsDay::SETTING_KEYID("key_id");
const std::string LLSettingsDay::SETTING_KEYNAME("key_name");
const std::string LLSettingsDay::SETTING_KEYKFRAME("key_keyframe");
const std::string LLSettingsDay::SETTING_KEYHASH("key_hash");
const std::string LLSettingsDay::SETTING_TRACKS("tracks");
const std::string LLSettingsDay::SETTING_FRAMES("frames");
const LLSettingsDay::Seconds LLSettingsDay::MINIMUM_DAYLENGTH(14400); // 4 hours
const LLSettingsDay::Seconds LLSettingsDay::DEFAULT_DAYLENGTH(14400); // 4 hours
const LLSettingsDay::Seconds LLSettingsDay::MAXIMUM_DAYLENGTH(604800); // 7 days
const LLSettingsDay::Seconds LLSettingsDay::MINIMUM_DAYOFFSET(0);
const LLSettingsDay::Seconds LLSettingsDay::DEFAULT_DAYOFFSET(57600); // +16 hours == -8 hours (SLT time offset)
const LLSettingsDay::Seconds LLSettingsDay::MAXIMUM_DAYOFFSET(86400); // 24 hours
const S32 LLSettingsDay::TRACK_WATER(0); // water track is 0
const S32 LLSettingsDay::TRACK_GROUND_LEVEL(1);
const S32 LLSettingsDay::TRACK_MAX(5); // 5 tracks, 4 skys, 1 water
const S32 LLSettingsDay::FRAME_MAX(56);
const F32 LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR(0.02501f);
const LLUUID LLSettingsDay::DEFAULT_ASSET_ID("78751d18-6c51-3c43-2887-3654cd427a42");
// Minimum value to prevent multislider in edit floaters from eating up frames that 'encroach' on one another's space
static const F32 DEFAULT_MULTISLIDER_INCREMENT(0.005f);
//=========================================================================
LLSettingsDay::LLSettingsDay(const LLSD &data) :
LLSettingsBase(data),
mInitialized(false)
{
mDayTracks.resize(TRACK_MAX);
}
LLSettingsDay::LLSettingsDay() :
LLSettingsBase(),
mInitialized(false)
{
mDayTracks.resize(TRACK_MAX);
}
//=========================================================================
LLSD LLSettingsDay::getSettings() const
{
LLSD settings(LLSD::emptyMap());
if (mSettings.has(SETTING_NAME))
settings[SETTING_NAME] = mSettings[SETTING_NAME];
if (mSettings.has(SETTING_ID))
settings[SETTING_ID] = mSettings[SETTING_ID];
if (mSettings.has(SETTING_ASSETID))
settings[SETTING_ASSETID] = mSettings[SETTING_ASSETID];
settings[SETTING_TYPE] = getSettingsType();
std::map<std::string, LLSettingsBase::ptr_t> in_use;
LLSD tracks(LLSD::emptyArray());
for (CycleList_t::const_iterator itTrack = mDayTracks.begin(); itTrack != mDayTracks.end(); ++itTrack)
{
LLSD trackout(LLSD::emptyArray());
for (CycleTrack_t::const_iterator itFrame = (*itTrack).begin(); itFrame != (*itTrack).end(); ++itFrame)
{
F32 frame = (*itFrame).first;
LLSettingsBase::ptr_t data = (*itFrame).second;
size_t datahash = data->getHash();
std::stringstream keyname;
keyname << datahash;
trackout.append(LLSD(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(frame))(SETTING_KEYNAME, keyname.str())));
in_use[keyname.str()] = data;
}
tracks.append(trackout);
}
settings[SETTING_TRACKS] = tracks;
LLSD frames(LLSD::emptyMap());
for (std::map<std::string, LLSettingsBase::ptr_t>::iterator itFrame = in_use.begin(); itFrame != in_use.end(); ++itFrame)
{
LLSD framesettings = llsd_clone((*itFrame).second->getSettings(),
LLSDMap("*", true)(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false));
frames[(*itFrame).first] = framesettings;
}
settings[SETTING_FRAMES] = frames;
return settings;
}
bool LLSettingsDay::initialize(bool validate_frames)
{
LLSD tracks = mSettings[SETTING_TRACKS];
LLSD frames = mSettings[SETTING_FRAMES];
// save for later...
LLUUID assetid;
if (mSettings.has(SETTING_ASSETID))
{
assetid = mSettings[SETTING_ASSETID].asUUID();
}
std::map<std::string, LLSettingsBase::ptr_t> used;
for (LLSD::map_const_iterator itFrame = frames.beginMap(); itFrame != frames.endMap(); ++itFrame)
{
std::string name = (*itFrame).first;
LLSD data = (*itFrame).second;
LLSettingsBase::ptr_t keyframe;
if (data[SETTING_TYPE].asString() == "sky")
{
keyframe = buildSky(data);
}
else if (data[SETTING_TYPE].asString() == "water")
{
keyframe = buildWater(data);
}
else
{
LL_WARNS("DAYCYCLE") << "Unknown child setting type '" << data[SETTING_TYPE].asString() << "' named '" << name << "'" << LL_ENDL;
}
if (!keyframe)
{
LL_WARNS("DAYCYCLE") << "Invalid frame data" << LL_ENDL;
continue;
}
used[name] = keyframe;
}
bool haswater(false);
bool hassky(false);
for (S32 i = 0; (i < tracks.size()) && (i < TRACK_MAX); ++i)
{
mDayTracks[i].clear();
LLSD curtrack = tracks[i];
for (LLSD::array_const_iterator it = curtrack.beginArray(); it != curtrack.endArray(); ++it)
{
LLSettingsBase::TrackPosition keyframe = LLSettingsBase::TrackPosition((*it)[SETTING_KEYKFRAME].asReal());
keyframe = llclamp(keyframe, 0.0f, 1.0f);
LLSettingsBase::ptr_t setting;
if ((*it).has(SETTING_KEYNAME))
{
std::string key_name = (*it)[SETTING_KEYNAME];
if (i == TRACK_WATER)
{
setting = used[key_name];
if (setting && setting->getSettingsType() != "water")
{
LL_WARNS("DAYCYCLE") << "Water track referencing " << setting->getSettingsType() << " frame at " << keyframe << "." << LL_ENDL;
setting.reset();
}
}
else
{
setting = used[key_name];
if (setting && setting->getSettingsType() != "sky")
{
LL_WARNS("DAYCYCLE") << "Sky track #" << i << " referencing " << setting->getSettingsType() << " frame at " << keyframe << "." << LL_ENDL;
setting.reset();
}
}
}
if (setting)
{
if (i == TRACK_WATER)
haswater |= true;
else
hassky |= true;
if (validate_frames && mDayTracks[i].size() > 0)
{
// check if we hit close to anything in the list
LLSettingsDay::CycleTrack_t::value_type frame = getSettingsNearKeyframe(keyframe, i, DEFAULT_FRAME_SLOP_FACTOR);
if (frame.second)
{
// figure out direction of search
LLSettingsBase::TrackPosition found = frame.first;
LLSettingsBase::TrackPosition new_frame = keyframe;
F32 total_frame_shift = 0;
// We consider frame DEFAULT_FRAME_SLOP_FACTOR away as still encroaching, so add minimum increment
F32 move_factor = DEFAULT_FRAME_SLOP_FACTOR + DEFAULT_MULTISLIDER_INCREMENT;
bool move_forward = true;
if ((new_frame < found && (found - new_frame) <= DEFAULT_FRAME_SLOP_FACTOR)
|| (new_frame > found && (new_frame - found) > DEFAULT_FRAME_SLOP_FACTOR))
{
move_forward = false;
}
if (move_forward)
{
CycleTrack_t::iterator iter = mDayTracks[i].find(found);
new_frame = found; // for total_frame_shift
while (total_frame_shift < 1)
{
// calculate shifted position from previous found point
total_frame_shift += move_factor + (found >= new_frame ? found : found + 1) - new_frame;
new_frame = found + move_factor;
if (new_frame > 1) new_frame--;
// we know that current point is too close, go for next one
iter++;
if (iter == mDayTracks[i].end())
{
iter = mDayTracks[i].begin();
}
if (((iter->first >= (new_frame - DEFAULT_MULTISLIDER_INCREMENT)) && ((new_frame + DEFAULT_FRAME_SLOP_FACTOR) >= iter->first))
|| ((iter->first < new_frame) && ((new_frame + DEFAULT_FRAME_SLOP_FACTOR) >= (iter->first + 1))))
{
// we are encroaching at new point as well
found = iter->first;
}
else // (new_frame + DEFAULT_FRAME_SLOP_FACTOR < iter->first)
{
//we found clear spot
break;
}
}
}
else
{
CycleTrack_t::reverse_iterator iter = mDayTracks[i].rbegin();
while (iter->first != found)
{
iter++;
}
new_frame = found; // for total_frame_shift
while (total_frame_shift < 1)
{
// calculate shifted position from current found point
total_frame_shift += move_factor + new_frame - (found <= new_frame ? found : found - 1);
new_frame = found - move_factor;
if (new_frame < 0) new_frame++;
// we know that current point is too close, go for next one
iter++;
if (iter == mDayTracks[i].rend())
{
iter = mDayTracks[i].rbegin();
}
if ((iter->first <= (new_frame + DEFAULT_MULTISLIDER_INCREMENT) && (new_frame - DEFAULT_FRAME_SLOP_FACTOR) <= iter->first)
|| ((iter->first > new_frame) && ((new_frame - DEFAULT_FRAME_SLOP_FACTOR) <= (iter->first - 1))))
{
// we are encroaching at new point as well
found = iter->first;
}
else // (new_frame - DEFAULT_FRAME_SLOP_FACTOR > iter->first)
{
//we found clear spot
break;
}
}
}
if (total_frame_shift >= 1)
{
LL_WARNS("SETTINGS") << "Could not fix frame position, adding as is to position: " << keyframe << LL_ENDL;
}
else
{
// Mark as new position
keyframe = new_frame;
}
}
}
mDayTracks[i][keyframe] = setting;
}
}
}
if (!haswater || !hassky)
{
LL_WARNS("DAYCYCLE") << "Must have at least one water and one sky frame!" << LL_ENDL;
return false;
}
// these are no longer needed and just take up space now.
mSettings.erase(SETTING_TRACKS);
mSettings.erase(SETTING_FRAMES);
if (!assetid.isNull())
{
mSettings[SETTING_ASSETID] = assetid;
}
mInitialized = true;
return true;
}
//=========================================================================
LLSD LLSettingsDay::defaults()
{
static LLSD dfltsetting;
if (dfltsetting.size() == 0)
{
dfltsetting[SETTING_NAME] = "_default_";
dfltsetting[SETTING_TYPE] = "daycycle";
LLSD frames(LLSD::emptyMap());
LLSD waterTrack;
LLSD skyTrack;
const U32 FRAME_COUNT = 8;
const F32 FRAME_STEP = 1.0f / F32(FRAME_COUNT);
F32 time = 0.0f;
for (U32 i = 0; i < FRAME_COUNT; i++)
{
std::string name("_default_");
name += ('a' + i);
std::string water_frame_name("water:");
std::string sky_frame_name("sky:");
water_frame_name += name;
sky_frame_name += name;
waterTrack[SETTING_KEYKFRAME] = time;
waterTrack[SETTING_KEYNAME] = water_frame_name;
skyTrack[SETTING_KEYKFRAME] = time;
skyTrack[SETTING_KEYNAME] = sky_frame_name;
frames[water_frame_name] = LLSettingsWater::defaults(time);
frames[sky_frame_name] = LLSettingsSky::defaults(time);
time += FRAME_STEP;
}
LLSD tracks;
tracks.append(LLSDArray(waterTrack));
tracks.append(LLSDArray(skyTrack));
dfltsetting[SETTING_TRACKS] = tracks;
dfltsetting[SETTING_FRAMES] = frames;
}
return dfltsetting;
}
void LLSettingsDay::blend(const LLSettingsBase::ptr_t &other, F64 mix)
{
LL_ERRS("DAYCYCLE") << "Day cycles are not blendable!" << LL_ENDL;
}
namespace
{
bool validateDayCycleTrack(LLSD &value)
{
// Trim extra tracks.
while (value.size() > LLSettingsDay::TRACK_MAX)
{
value.erase(value.size() - 1);
}
S32 framecount(0);
for (LLSD::array_iterator track = value.beginArray(); track != value.endArray(); ++track)
{
S32 index = 0;
while (index < (*track).size())
{
LLSD& elem = (*track)[index];
++framecount;
if (index >= LLSettingsDay::FRAME_MAX)
{
(*track).erase(index);
continue;
}
if (!elem.has(LLSettingsDay::SETTING_KEYKFRAME))
{
(*track).erase(index);
continue;
}
if (!elem[LLSettingsDay::SETTING_KEYKFRAME].isReal())
{
(*track).erase(index);
continue;
}
if (!elem.has(LLSettingsDay::SETTING_KEYNAME) &&
!elem.has(LLSettingsDay::SETTING_KEYID))
{
(*track).erase(index);
continue;
}
LLSettingsBase::TrackPosition frame = elem[LLSettingsDay::SETTING_KEYKFRAME].asReal();
if ((frame < 0.0) || (frame > 1.0))
{
frame = llclamp(frame, 0.0f, 1.0f);
elem[LLSettingsDay::SETTING_KEYKFRAME] = frame;
}
++index;
}
}
int waterTracks = value[0].size();
int skyTracks = framecount - waterTracks;
if (waterTracks < 1)
{
LL_WARNS("SETTINGS") << "Missing water track" << LL_ENDL;
return false;
}
if (skyTracks < 1)
{
LL_WARNS("SETTINGS") << "Missing sky tracks" << LL_ENDL;
return false;
}
return true;
}
bool validateDayCycleFrames(LLSD &value)
{
bool hasSky(false);
bool hasWater(false);
for (LLSD::map_iterator itf = value.beginMap(); itf != value.endMap(); ++itf)
{
LLSD frame = (*itf).second;
std::string ftype = frame[LLSettingsBase::SETTING_TYPE];
if (ftype == "sky")
{
LLSettingsSky::validation_list_t valid_sky = LLSettingsSky::validationList();
LLSD res_sky = LLSettingsBase::settingValidation(frame, valid_sky);
if (res_sky["success"].asInteger() == 0)
{
LL_WARNS("SETTINGS") << "Sky setting named '" << (*itf).first << "' validation failed!: " << res_sky << LL_ENDL;
LL_WARNS("SETTINGS") << "Sky: " << frame << LL_ENDL;
continue;
}
hasSky |= true;
}
else if (ftype == "water")
{
LLSettingsWater::validation_list_t valid_h2o = LLSettingsWater::validationList();
LLSD res_h2o = LLSettingsBase::settingValidation(frame, valid_h2o);
if (res_h2o["success"].asInteger() == 0)
{
LL_WARNS("SETTINGS") << "Water setting named '" << (*itf).first << "' validation failed!: " << res_h2o << LL_ENDL;
LL_WARNS("SETTINGS") << "Water: " << frame << LL_ENDL;
continue;
}
hasWater |= true;
}
else
{
LL_WARNS("SETTINGS") << "Unknown settings block of type '" << ftype << "' named '" << (*itf).first << "'" << LL_ENDL;
return false;
}
}
if (!hasSky)
{
LL_WARNS("SETTINGS") << "No skies defined." << LL_ENDL;
return false;
}
if (!hasWater)
{
LL_WARNS("SETTINGS") << "No waters defined." << LL_ENDL;
return false;
}
return true;
}
}
LLSettingsDay::validation_list_t LLSettingsDay::getValidationList() const
{
return LLSettingsDay::validationList();
}
LLSettingsDay::validation_list_t LLSettingsDay::validationList()
{
static validation_list_t validation;
if (validation.empty())
{
validation.push_back(Validator(SETTING_TRACKS, true, LLSD::TypeArray,
&validateDayCycleTrack));
validation.push_back(Validator(SETTING_FRAMES, true, LLSD::TypeMap,
&validateDayCycleFrames));
}
return validation;
}
LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrack(S32 track)
{
static CycleTrack_t emptyTrack;
if (mDayTracks.size() <= track)
return emptyTrack;
return mDayTracks[track];
}
const LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrackConst(S32 track) const
{
static CycleTrack_t emptyTrack;
if (mDayTracks.size() <= track)
return emptyTrack;
return mDayTracks[track];
}
bool LLSettingsDay::clearCycleTrack(S32 track)
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to clear track (#" << track << ") out of range!" << LL_ENDL;
return false;
}
mDayTracks[track].clear();
clearAssetId();
setDirtyFlag(true);
return true;
}
bool LLSettingsDay::replaceCycleTrack(S32 track, const CycleTrack_t &source)
{
if (source.empty())
{
LL_WARNS("DAYCYCLE") << "Attempt to copy an empty track." << LL_ENDL;
return false;
}
{
LLSettingsBase::ptr_t first((*source.begin()).second);
std::string setting_type = first->getSettingsType();
if (((setting_type == "water") && (track != 0)) ||
((setting_type == "sky") && (track == 0)))
{
LL_WARNS("DAYCYCLE") << "Attempt to copy track missmatch" << LL_ENDL;
return false;
}
}
if (!clearCycleTrack(track))
return false;
mDayTracks[track] = source;
return true;
}
bool LLSettingsDay::isTrackEmpty(S32 track) const
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to test track (#" << track << ") out of range!" << LL_ENDL;
return true;
}
return mDayTracks[track].empty();
}
//=========================================================================
void LLSettingsDay::startDayCycle()
{
if (!mInitialized)
{
LL_WARNS("DAYCYCLE") << "Attempt to start day cycle on uninitialized object." << LL_ENDL;
return;
}
}
void LLSettingsDay::updateSettings()
{
}
//=========================================================================
LLSettingsDay::KeyframeList_t LLSettingsDay::getTrackKeyframes(S32 trackno)
{
if ((trackno < 0) || (trackno >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
return KeyframeList_t();
}
KeyframeList_t keyframes;
CycleTrack_t &track = mDayTracks[trackno];
keyframes.reserve(track.size());
for (CycleTrack_t::iterator it = track.begin(); it != track.end(); ++it)
{
keyframes.push_back((*it).first);
}
return keyframes;
}
bool LLSettingsDay::moveTrackKeyframe(S32 trackno, const LLSettingsBase::TrackPosition& old_frame, const LLSettingsBase::TrackPosition& new_frame)
{
if ((trackno < 0) || (trackno >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
return false;
}
if (old_frame == new_frame)
{
return false;
}
CycleTrack_t &track = mDayTracks[trackno];
CycleTrack_t::iterator iter = track.find(old_frame);
if (iter != track.end())
{
LLSettingsBase::ptr_t base = iter->second;
track.erase(iter);
track[llclamp(new_frame, 0.0f, 1.0f)] = base;
track[new_frame] = base;
return true;
}
return false;
}
bool LLSettingsDay::removeTrackKeyframe(S32 trackno, const LLSettingsBase::TrackPosition& frame)
{
if ((trackno < 0) || (trackno >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
return false;
}
CycleTrack_t &track = mDayTracks[trackno];
CycleTrack_t::iterator iter = track.find(frame);
if (iter != track.end())
{
LLSettingsBase::ptr_t base = iter->second;
track.erase(iter);
return true;
}
return false;
}
void LLSettingsDay::setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, const LLSettingsBase::TrackPosition& keyframe)
{
setSettingsAtKeyframe(water, keyframe, TRACK_WATER);
}
LLSettingsWater::ptr_t LLSettingsDay::getWaterAtKeyframe(const LLSettingsBase::TrackPosition& keyframe) const
{
LLSettingsBase* p = getSettingsAtKeyframe(keyframe, TRACK_WATER).get();
return LLSettingsWater::ptr_t((LLSettingsWater*)p);
}
void LLSettingsDay::setSkyAtKeyframe(const LLSettingsSky::ptr_t &sky, const LLSettingsBase::TrackPosition& keyframe, S32 track)
{
if ((track < 1) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
return;
}
setSettingsAtKeyframe(sky, keyframe, track);
}
LLSettingsSky::ptr_t LLSettingsDay::getSkyAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const
{
if ((track < 1) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
return LLSettingsSky::ptr_t();
}
return PTR_NAMESPACE::dynamic_pointer_cast<LLSettingsSky>(getSettingsAtKeyframe(keyframe, track));
}
void LLSettingsDay::setSettingsAtKeyframe(const LLSettingsBase::ptr_t &settings, const LLSettingsBase::TrackPosition& keyframe, S32 track)
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set track (#" << track << ") out of range!" << LL_ENDL;
return;
}
std::string type = settings->getSettingsType();
if ((track == TRACK_WATER) && (type != "water"))
{
LL_WARNS("DAYCYCLE") << "Attempt to add frame of type '" << type << "' to water track!" << LL_ENDL;
llassert(type == "water");
return;
}
else if ((track != TRACK_WATER) && (type != "sky"))
{
LL_WARNS("DAYCYCLE") << "Attempt to add frame of type '" << type << "' to sky track!" << LL_ENDL;
llassert(type == "sky");
return;
}
mDayTracks[track][llclamp(keyframe, 0.0f, 1.0f)] = settings;
setDirtyFlag(true);
}
LLSettingsBase::ptr_t LLSettingsDay::getSettingsAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
return LLSettingsBase::ptr_t();
}
// todo: better way to identify keyframes?
CycleTrack_t::const_iterator iter = mDayTracks[track].find(keyframe);
if (iter != mDayTracks[track].end())
{
return iter->second;
}
return LLSettingsBase::ptr_t();
}
LLSettingsDay::CycleTrack_t::value_type LLSettingsDay::getSettingsNearKeyframe(const LLSettingsBase::TrackPosition &keyframe, S32 track, F32 fudge) const
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to get track (#" << track << ") out of range!" << LL_ENDL;
return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
}
if (mDayTracks[track].empty())
{
LL_INFOS("DAYCYCLE") << "Empty track" << LL_ENDL;
return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
}
TrackPosition startframe(keyframe - fudge);
if (startframe < 0.0f)
startframe = 1.0f + startframe;
CycleTrack_t::iterator it = get_wrapping_atafter(const_cast<CycleTrack_t &>(mDayTracks[track]), startframe);
F32 dist = get_wrapping_distance(startframe, (*it).first);
if (dist <= (fudge * 2.0f))
return (*it);
return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
}
LLSettingsBase::TrackPosition LLSettingsDay::getUpperBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe)
{
return get_wrapping_atafter(mDayTracks[track], keyframe)->first;
}
LLSettingsBase::TrackPosition LLSettingsDay::getLowerBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe)
{
return get_wrapping_atbefore(mDayTracks[track], keyframe)->first;
}
LLSettingsDay::TrackBound_t LLSettingsDay::getBoundingEntries(LLSettingsDay::CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe)
{
return TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe));
}
LLUUID LLSettingsDay::GetDefaultAssetId()
{
return DEFAULT_ASSET_ID;
}
//=========================================================================

View File

@@ -0,0 +1,156 @@
/**
* @file llsettingsdaycycle.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $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$
*/
#ifndef LL_SETTINGS_DAYCYCLE_H
#define LL_SETTINGS_DAYCYCLE_H
#include "llsettingsbase.h"
class LLSettingsWater;
class LLSettingsSky;
// These are alias for LLSettingsWater::ptr_t and LLSettingsSky::ptr_t respectively.
// Here for definitions only.
typedef PTR_NAMESPACE::shared_ptr<LLSettingsWater> LLSettingsWaterPtr_t;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> LLSettingsSkyPtr_t;
class LLSettingsDay : public LLSettingsBase
{
public:
// 32-bit as LLSD only supports that width at present
typedef S32Seconds Seconds;
static const std::string SETTING_KEYID;
static const std::string SETTING_KEYNAME;
static const std::string SETTING_KEYKFRAME;
static const std::string SETTING_KEYHASH;
static const std::string SETTING_TRACKS;
static const std::string SETTING_FRAMES;
static const Seconds MINIMUM_DAYLENGTH;
static const Seconds DEFAULT_DAYLENGTH;
static const Seconds MAXIMUM_DAYLENGTH;
static const Seconds MINIMUM_DAYOFFSET;
static const Seconds DEFAULT_DAYOFFSET;
static const Seconds MAXIMUM_DAYOFFSET;
static const S32 TRACK_WATER;
static const S32 TRACK_GROUND_LEVEL;
static const S32 TRACK_MAX;
static const S32 FRAME_MAX;
static const F32 DEFAULT_FRAME_SLOP_FACTOR;
static const LLUUID DEFAULT_ASSET_ID;
typedef std::map<LLSettingsBase::TrackPosition, LLSettingsBase::ptr_t> CycleTrack_t;
typedef std::vector<CycleTrack_t> CycleList_t;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsDay> ptr_t;
typedef PTR_NAMESPACE::weak_ptr<LLSettingsDay> wptr_t;
typedef std::vector<LLSettingsBase::TrackPosition> KeyframeList_t;
typedef std::pair<CycleTrack_t::iterator, CycleTrack_t::iterator> TrackBound_t;
//---------------------------------------------------------------------
LLSettingsDay(const LLSD &data);
virtual ~LLSettingsDay() { };
bool initialize(bool validate_frames = false);
virtual ptr_t buildClone() const = 0;
virtual ptr_t buildDeepCloneAndUncompress() const = 0;
virtual LLSD getSettings() const SETTINGS_OVERRIDE;
virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_DAYCYCLE; }
//---------------------------------------------------------------------
virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("daycycle"); }
// Settings status
virtual void blend(const LLSettingsBase::ptr_t &other, F64 mix) SETTINGS_OVERRIDE;
static LLSD defaults();
//---------------------------------------------------------------------
KeyframeList_t getTrackKeyframes(S32 track);
bool moveTrackKeyframe(S32 track, const LLSettingsBase::TrackPosition& old_frame, const LLSettingsBase::TrackPosition& new_frame);
bool removeTrackKeyframe(S32 track, const LLSettingsBase::TrackPosition& frame);
void setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, const LLSettingsBase::TrackPosition& keyframe);
LLSettingsWaterPtr_t getWaterAtKeyframe(const LLSettingsBase::TrackPosition& keyframe) const;
void setSkyAtKeyframe(const LLSettingsSkyPtr_t &sky, const LLSettingsBase::TrackPosition& keyframe, S32 track);
LLSettingsSkyPtr_t getSkyAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const;
void setSettingsAtKeyframe(const LLSettingsBase::ptr_t &settings, const LLSettingsBase::TrackPosition& keyframe, S32 track);
LLSettingsBase::ptr_t getSettingsAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const;
CycleTrack_t::value_type getSettingsNearKeyframe(const LLSettingsBase::TrackPosition &keyframe, S32 track, F32 fudge) const;
//---------------------------------------------------------------------
void startDayCycle();
virtual LLSettingsSkyPtr_t getDefaultSky() const = 0;
virtual LLSettingsWaterPtr_t getDefaultWater() const = 0;
virtual LLSettingsSkyPtr_t buildSky(LLSD) const = 0;
virtual LLSettingsWaterPtr_t buildWater(LLSD) const = 0;
void setInitialized(bool value = true) { mInitialized = value; }
CycleTrack_t & getCycleTrack(S32 track);
const CycleTrack_t & getCycleTrackConst(S32 track) const;
bool clearCycleTrack(S32 track);
bool replaceCycleTrack(S32 track, const CycleTrack_t &source);
bool isTrackEmpty(S32 track) const;
virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
static validation_list_t validationList();
virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
LLSettingsBase::TrackPosition getUpperBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe);
LLSettingsBase::TrackPosition getLowerBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe);
static LLUUID GetDefaultAssetId();
protected:
LLSettingsDay();
virtual void updateSettings() SETTINGS_OVERRIDE;
bool mInitialized;
private:
CycleList_t mDayTracks;
LLSettingsBase::Seconds mLastUpdateTime;
void parseFromLLSD(LLSD &data);
static CycleTrack_t::iterator getEntryAtOrBefore(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
static CycleTrack_t::iterator getEntryAtOrAfter(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
TrackBound_t getBoundingEntries(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,361 @@
/**
* @file llsettingssky.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $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$
*/
#ifndef LL_SETTINGS_SKY_H
#define LL_SETTINGS_SKY_H
#include "llsettingsbase.h"
#include "v4coloru.h"
const F32 EARTH_RADIUS = 6.370e6f;
const F32 SUN_RADIUS = 695.508e6f;
const F32 SUN_DIST = 149598.260e6f;
const F32 MOON_RADIUS = 1.737e6f;
const F32 MOON_DIST = 384.400e6f;
class LLSettingsSky: public LLSettingsBase
{
public:
static const std::string SETTING_AMBIENT;
static const std::string SETTING_BLOOM_TEXTUREID;
static const std::string SETTING_RAINBOW_TEXTUREID;
static const std::string SETTING_HALO_TEXTUREID;
static const std::string SETTING_BLUE_DENSITY;
static const std::string SETTING_BLUE_HORIZON;
static const std::string SETTING_DENSITY_MULTIPLIER;
static const std::string SETTING_DISTANCE_MULTIPLIER;
static const std::string SETTING_HAZE_DENSITY;
static const std::string SETTING_HAZE_HORIZON;
static const std::string SETTING_CLOUD_COLOR;
static const std::string SETTING_CLOUD_POS_DENSITY1;
static const std::string SETTING_CLOUD_POS_DENSITY2;
static const std::string SETTING_CLOUD_SCALE;
static const std::string SETTING_CLOUD_SCROLL_RATE;
static const std::string SETTING_CLOUD_SHADOW;
static const std::string SETTING_CLOUD_TEXTUREID;
static const std::string SETTING_CLOUD_VARIANCE;
static const std::string SETTING_DOME_OFFSET;
static const std::string SETTING_DOME_RADIUS;
static const std::string SETTING_GAMMA;
static const std::string SETTING_GLOW;
static const std::string SETTING_LIGHT_NORMAL;
static const std::string SETTING_MAX_Y;
static const std::string SETTING_MOON_ROTATION;
static const std::string SETTING_MOON_SCALE;
static const std::string SETTING_MOON_TEXTUREID;
static const std::string SETTING_MOON_BRIGHTNESS;
static const std::string SETTING_STAR_BRIGHTNESS;
static const std::string SETTING_SUNLIGHT_COLOR;
static const std::string SETTING_SUN_ROTATION;
static const std::string SETTING_SUN_SCALE;
static const std::string SETTING_SUN_TEXTUREID;
static const std::string SETTING_PLANET_RADIUS;
static const std::string SETTING_SKY_BOTTOM_RADIUS;
static const std::string SETTING_SKY_TOP_RADIUS;
static const std::string SETTING_SUN_ARC_RADIANS;
static const std::string SETTING_MIE_ANISOTROPY_FACTOR;
static const std::string SETTING_RAYLEIGH_CONFIG;
static const std::string SETTING_MIE_CONFIG;
static const std::string SETTING_ABSORPTION_CONFIG;
static const std::string KEY_DENSITY_PROFILE;
static const std::string SETTING_DENSITY_PROFILE_WIDTH;
static const std::string SETTING_DENSITY_PROFILE_EXP_TERM;
static const std::string SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR;
static const std::string SETTING_DENSITY_PROFILE_LINEAR_TERM;
static const std::string SETTING_DENSITY_PROFILE_CONSTANT_TERM;
static const std::string SETTING_SKY_MOISTURE_LEVEL;
static const std::string SETTING_SKY_DROPLET_RADIUS;
static const std::string SETTING_SKY_ICE_LEVEL;
static const std::string SETTING_LEGACY_HAZE;
static const LLUUID DEFAULT_ASSET_ID;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> ptr_t;
//---------------------------------------------------------------------
LLSettingsSky(const LLSD &data);
virtual ~LLSettingsSky() { };
virtual ptr_t buildClone() const = 0;
//---------------------------------------------------------------------
virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("sky"); }
virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_SKY; }
// Settings status
virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE;
virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE;
void replaceWithSky(LLSettingsSky::ptr_t pother);
static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f);
F32 getPlanetRadius() const;
F32 getSkyBottomRadius() const;
F32 getSkyTopRadius() const;
F32 getSunArcRadians() const;
F32 getMieAnisotropy() const;
F32 getSkyMoistureLevel() const;
F32 getSkyDropletRadius() const;
F32 getSkyIceLevel() const;
// Return first (only) profile layer represented in LLSD
LLSD getRayleighConfig() const;
LLSD getMieConfig() const;
LLSD getAbsorptionConfig() const;
// Return entire LLSDArray of profile layers represented in LLSD
LLSD getRayleighConfigs() const;
LLSD getMieConfigs() const;
LLSD getAbsorptionConfigs() const;
LLUUID getBloomTextureId() const;
LLUUID getRainbowTextureId() const;
LLUUID getHaloTextureId() const;
void setRayleighConfigs(const LLSD& rayleighConfig);
void setMieConfigs(const LLSD& mieConfig);
void setAbsorptionConfigs(const LLSD& absorptionConfig);
void setPlanetRadius(F32 radius);
void setSkyBottomRadius(F32 radius);
void setSkyTopRadius(F32 radius);
void setSunArcRadians(F32 radians);
void setMieAnisotropy(F32 aniso_factor);
void setSkyMoistureLevel(F32 moisture_level);
void setSkyDropletRadius(F32 radius);
void setSkyIceLevel(F32 ice_level);
//---------------------------------------------------------------------
LLColor3 getAmbientColor() const;
void setAmbientColor(const LLColor3 &val);
LLColor3 getCloudColor() const;
void setCloudColor(const LLColor3 &val);
LLUUID getCloudNoiseTextureId() const;
void setCloudNoiseTextureId(const LLUUID &id);
LLColor3 getCloudPosDensity1() const;
void setCloudPosDensity1(const LLColor3 &val);
LLColor3 getCloudPosDensity2() const;
void setCloudPosDensity2(const LLColor3 &val);
F32 getCloudScale() const;
void setCloudScale(F32 val);
LLVector2 getCloudScrollRate() const;
void setCloudScrollRate(const LLVector2 &val);
void setCloudScrollRateX(F32 val);
void setCloudScrollRateY(F32 val);
F32 getCloudShadow() const;
void setCloudShadow(F32 val);
F32 getCloudVariance() const;
void setCloudVariance(F32 val);
F32 getDomeOffset() const;
F32 getDomeRadius() const;
F32 getGamma() const;
void setGamma(F32 val);
LLColor3 getGlow() const;
void setGlow(const LLColor3 &val);
F32 getMaxY() const;
void setMaxY(F32 val);
LLQuaternion getMoonRotation() const;
void setMoonRotation(const LLQuaternion &val);
F32 getMoonScale() const;
void setMoonScale(F32 val);
LLUUID getMoonTextureId() const;
void setMoonTextureId(LLUUID id);
F32 getMoonBrightness() const;
void setMoonBrightness(F32 brightness_factor);
F32 getStarBrightness() const;
void setStarBrightness(F32 val);
LLColor3 getSunlightColor() const;
void setSunlightColor(const LLColor3 &val);
LLQuaternion getSunRotation() const;
void setSunRotation(const LLQuaternion &val) ;
F32 getSunScale() const;
void setSunScale(F32 val);
LLUUID getSunTextureId() const;
void setSunTextureId(LLUUID id);
//=====================================================================
// transient properties used in animations.
LLUUID getNextSunTextureId() const;
LLUUID getNextMoonTextureId() const;
LLUUID getNextCloudNoiseTextureId() const;
LLUUID getNextBloomTextureId() const;
//=====================================================================
virtual void loadTextures() { };
//=====================================================================
virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
static validation_list_t validationList();
static LLSD translateLegacySettings(const LLSD& legacy);
// LEGACY_ATMOSPHERICS
static LLSD translateLegacyHazeSettings(const LLSD& legacy);
LLColor3 getLightAttenuation(F32 distance) const;
LLColor3 getLightTransmittance() const;
LLColor3 gammaCorrect(const LLColor3& in) const;
LLColor3 getBlueDensity() const;
LLColor3 getBlueHorizon() const;
F32 getHazeDensity() const;
F32 getHazeHorizon() const;
F32 getDensityMultiplier() const;
F32 getDistanceMultiplier() const;
void setBlueDensity(const LLColor3 &val);
void setBlueHorizon(const LLColor3 &val);
void setDensityMultiplier(F32 val);
void setDistanceMultiplier(F32 val);
void setHazeDensity(F32 val);
void setHazeHorizon(F32 val);
// Internal/calculated settings
bool getIsSunUp() const;
bool getIsMoonUp() const;
// determines how much the haze glow effect occurs in rendering
F32 getSunMoonGlowFactor() const;
LLVector3 getLightDirection() const;
LLColor3 getLightDiffuse() const;
LLVector3 getSunDirection() const;
LLVector3 getMoonDirection() const;
LLColor4 getMoonAmbient() const;
LLColor3 getMoonDiffuse() const;
LLColor4 getSunAmbient() const;
LLColor3 getSunDiffuse() const;
LLColor4 getTotalAmbient() const;
virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
static LLUUID GetDefaultAssetId();
static LLUUID GetDefaultSunTextureId();
static LLUUID GetBlankSunTextureId();
static LLUUID GetDefaultMoonTextureId();
static LLUUID GetDefaultCloudNoiseTextureId();
static LLUUID GetDefaultBloomTextureId();
static LLUUID GetDefaultRainbowTextureId();
static LLUUID GetDefaultHaloTextureId();
static LLSD createDensityProfileLayer(
F32 width,
F32 exponential_term,
F32 exponential_scale_factor,
F32 linear_term,
F32 constant_term,
F32 aniso_factor = 0.0f);
static LLSD createSingleLayerDensityProfile(
F32 width,
F32 exponential_term,
F32 exponential_scale_factor,
F32 linear_term,
F32 constant_term,
F32 aniso_factor = 0.0f);
virtual void updateSettings() SETTINGS_OVERRIDE;
protected:
static const std::string SETTING_LEGACY_EAST_ANGLE;
static const std::string SETTING_LEGACY_ENABLE_CLOUD_SCROLL;
static const std::string SETTING_LEGACY_SUN_ANGLE;
LLSettingsSky();
virtual stringset_t getSlerpKeys() const SETTINGS_OVERRIDE;
virtual stringset_t getSkipInterpolateKeys() const SETTINGS_OVERRIDE;
LLUUID mNextSunTextureId;
LLUUID mNextMoonTextureId;
LLUUID mNextCloudTextureId;
LLUUID mNextBloomTextureId;
LLUUID mNextRainbowTextureId;
LLUUID mNextHaloTextureId;
private:
static LLSD rayleighConfigDefault();
static LLSD absorptionConfigDefault();
static LLSD mieConfigDefault();
void calculateHeavenlyBodyPositions() const;
void calculateLightSettings() const;
mutable LLVector3 mSunDirection;
mutable LLVector3 mMoonDirection;
mutable LLVector3 mLightDirection;
static const F32 DOME_RADIUS;
static const F32 DOME_OFFSET;
mutable LLColor4 mMoonAmbient;
mutable LLColor3 mMoonDiffuse;
mutable LLColor4 mSunAmbient;
mutable LLColor3 mSunDiffuse;
mutable LLColor4 mTotalAmbient;
typedef std::map<std::string, S32> mapNameToUniformId_t;
static mapNameToUniformId_t sNameToUniformMapping;
};
#endif

View File

@@ -0,0 +1,303 @@
/**
* @file llsettingswater.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $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 "llsettingswater.h"
#include <algorithm>
#include <boost/make_shared.hpp>
#include "llfasttimer.h"
#include "v3colorutil.h"
#include "imageids.h"
//=========================================================================
namespace
{
LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment");
LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment");
}
//=========================================================================
const std::string LLSettingsWater::SETTING_BLUR_MULTIPLIER("blur_multiplier");
const std::string LLSettingsWater::SETTING_FOG_COLOR("water_fog_color");
const std::string LLSettingsWater::SETTING_FOG_DENSITY("water_fog_density");
const std::string LLSettingsWater::SETTING_FOG_MOD("underwater_fog_mod");
const std::string LLSettingsWater::SETTING_FRESNEL_OFFSET("fresnel_offset");
const std::string LLSettingsWater::SETTING_FRESNEL_SCALE("fresnel_scale");
const std::string LLSettingsWater::SETTING_TRANSPARENT_TEXTURE("transparent_texture");
const std::string LLSettingsWater::SETTING_NORMAL_MAP("normal_map");
const std::string LLSettingsWater::SETTING_NORMAL_SCALE("normal_scale");
const std::string LLSettingsWater::SETTING_SCALE_ABOVE("scale_above");
const std::string LLSettingsWater::SETTING_SCALE_BELOW("scale_below");
const std::string LLSettingsWater::SETTING_WAVE1_DIR("wave1_direction");
const std::string LLSettingsWater::SETTING_WAVE2_DIR("wave2_direction");
const std::string LLSettingsWater::SETTING_LEGACY_BLUR_MULTIPLIER("blurMultiplier");
const std::string LLSettingsWater::SETTING_LEGACY_FOG_COLOR("waterFogColor");
const std::string LLSettingsWater::SETTING_LEGACY_FOG_DENSITY("waterFogDensity");
const std::string LLSettingsWater::SETTING_LEGACY_FOG_MOD("underWaterFogMod");
const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_OFFSET("fresnelOffset");
const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_SCALE("fresnelScale");
const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_MAP("normalMap");
const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_SCALE("normScale");
const std::string LLSettingsWater::SETTING_LEGACY_SCALE_ABOVE("scaleAbove");
const std::string LLSettingsWater::SETTING_LEGACY_SCALE_BELOW("scaleBelow");
const std::string LLSettingsWater::SETTING_LEGACY_WAVE1_DIR("wave1Dir");
const std::string LLSettingsWater::SETTING_LEGACY_WAVE2_DIR("wave2Dir");
const LLUUID LLSettingsWater::DEFAULT_ASSET_ID("59d1a851-47e7-0e5f-1ed7-6b715154f41a");
static const LLUUID DEFAULT_TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
static const LLUUID DEFAULT_OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
//=========================================================================
LLSettingsWater::LLSettingsWater(const LLSD &data) :
LLSettingsBase(data),
mNextNormalMapID()
{
}
LLSettingsWater::LLSettingsWater() :
LLSettingsBase(),
mNextNormalMapID()
{
}
//=========================================================================
LLSD LLSettingsWater::defaults(const LLSettingsBase::TrackPosition& position)
{
static LLSD dfltsetting;
if (dfltsetting.size() == 0)
{
// give the normal scale offset some variability over track time...
F32 normal_scale_offset = (position * 0.5f) - 0.25f;
// Magic constants copied form defaults.xml
dfltsetting[SETTING_BLUR_MULTIPLIER] = LLSD::Real(0.04000f);
dfltsetting[SETTING_FOG_COLOR] = LLColor3(0.0156f, 0.1490f, 0.2509f).getValue();
dfltsetting[SETTING_FOG_DENSITY] = LLSD::Real(2.0f);
dfltsetting[SETTING_FOG_MOD] = LLSD::Real(0.25f);
dfltsetting[SETTING_FRESNEL_OFFSET] = LLSD::Real(0.5f);
dfltsetting[SETTING_FRESNEL_SCALE] = LLSD::Real(0.3999);
dfltsetting[SETTING_TRANSPARENT_TEXTURE] = GetDefaultTransparentTextureAssetId();
dfltsetting[SETTING_NORMAL_MAP] = GetDefaultWaterNormalAssetId();
dfltsetting[SETTING_NORMAL_SCALE] = LLVector3(2.0f + normal_scale_offset, 2.0f + normal_scale_offset, 2.0f + normal_scale_offset).getValue();
dfltsetting[SETTING_SCALE_ABOVE] = LLSD::Real(0.0299f);
dfltsetting[SETTING_SCALE_BELOW] = LLSD::Real(0.2000f);
dfltsetting[SETTING_WAVE1_DIR] = LLVector2(1.04999f, -0.42000f).getValue();
dfltsetting[SETTING_WAVE2_DIR] = LLVector2(1.10999f, -1.16000f).getValue();
dfltsetting[SETTING_TYPE] = "water";
}
return dfltsetting;
}
LLSD LLSettingsWater::translateLegacySettings(LLSD legacy)
{
bool converted_something(false);
LLSD newsettings(defaults());
if (legacy.has(SETTING_LEGACY_BLUR_MULTIPLIER))
{
newsettings[SETTING_BLUR_MULTIPLIER] = LLSD::Real(legacy[SETTING_LEGACY_BLUR_MULTIPLIER].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FOG_COLOR))
{
newsettings[SETTING_FOG_COLOR] = LLColor3(legacy[SETTING_LEGACY_FOG_COLOR]).getValue();
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FOG_DENSITY))
{
newsettings[SETTING_FOG_DENSITY] = LLSD::Real(legacy[SETTING_LEGACY_FOG_DENSITY]);
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FOG_MOD))
{
newsettings[SETTING_FOG_MOD] = LLSD::Real(legacy[SETTING_LEGACY_FOG_MOD].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FRESNEL_OFFSET))
{
newsettings[SETTING_FRESNEL_OFFSET] = LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_OFFSET].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FRESNEL_SCALE))
{
newsettings[SETTING_FRESNEL_SCALE] = LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_SCALE].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_NORMAL_MAP))
{
newsettings[SETTING_NORMAL_MAP] = LLSD::UUID(legacy[SETTING_LEGACY_NORMAL_MAP].asUUID());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_NORMAL_SCALE))
{
newsettings[SETTING_NORMAL_SCALE] = LLVector3(legacy[SETTING_LEGACY_NORMAL_SCALE]).getValue();
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_SCALE_ABOVE))
{
newsettings[SETTING_SCALE_ABOVE] = LLSD::Real(legacy[SETTING_LEGACY_SCALE_ABOVE].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_SCALE_BELOW))
{
newsettings[SETTING_SCALE_BELOW] = LLSD::Real(legacy[SETTING_LEGACY_SCALE_BELOW].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_WAVE1_DIR))
{
newsettings[SETTING_WAVE1_DIR] = LLVector2(legacy[SETTING_LEGACY_WAVE1_DIR]).getValue();
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_WAVE2_DIR))
{
newsettings[SETTING_WAVE2_DIR] = LLVector2(legacy[SETTING_LEGACY_WAVE2_DIR]).getValue();
converted_something |= true;
}
if (!converted_something)
return LLSD();
return newsettings;
}
void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
{
LLSettingsWater::ptr_t other = PTR_NAMESPACE::static_pointer_cast<LLSettingsWater>(end);
if (other)
{
LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, other->getParameterMap(), blendf);
replaceSettings(blenddata);
mNextNormalMapID = other->getNormalMapID();
mNextTransparentTextureID = other->getTransparentTextureID();
}
else
{
LL_WARNS("SETTINGS") << "Could not cast end settings to water. No blend performed." << LL_ENDL;
}
setBlendFactor(blendf);
}
void LLSettingsWater::replaceSettings(LLSD settings)
{
LLSettingsBase::replaceSettings(settings);
mNextNormalMapID.setNull();
mNextTransparentTextureID.setNull();
}
void LLSettingsWater::replaceWithWater(LLSettingsWater::ptr_t other)
{
replaceWith(other);
mNextNormalMapID = other->mNextNormalMapID;
mNextTransparentTextureID = other->mNextTransparentTextureID;
}
LLSettingsWater::validation_list_t LLSettingsWater::getValidationList() const
{
return LLSettingsWater::validationList();
}
LLSettingsWater::validation_list_t LLSettingsWater::validationList()
{
static validation_list_t validation;
if (validation.empty())
{ // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
// copy constructor for LLSDArray. Directly binding the LLSDArray as
// a parameter without first wrapping it in a pure LLSD object will result
// in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
validation.push_back(Validator(SETTING_BLUR_MULTIPLIER, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-0.5f)(0.5f)))));
validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)(1.0f)),
LLSD(LLSDArray(1.0f)(1.0f)(1.0f)(1.0f)))));
validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-10.0f)(10.0f)))));
validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(20.0f)))));
validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_NORMAL_MAP, true, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_NORMAL_SCALE, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)),
LLSD(LLSDArray(10.0f)(10.0f)(10.0f)))));
validation.push_back(Validator(SETTING_SCALE_ABOVE, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(3.0f)))));
validation.push_back(Validator(SETTING_SCALE_BELOW, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(3.0f)))));
validation.push_back(Validator(SETTING_WAVE1_DIR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(-20.0f)(-20.0f)),
LLSD(LLSDArray(20.0f)(20.0f)))));
validation.push_back(Validator(SETTING_WAVE2_DIR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(-20.0f)(-20.0f)),
LLSD(LLSDArray(20.0f)(20.0f)))));
}
return validation;
}
LLUUID LLSettingsWater::GetDefaultAssetId()
{
return DEFAULT_ASSET_ID;
}
LLUUID LLSettingsWater::GetDefaultWaterNormalAssetId()
{
return DEFAULT_WATER_NORMAL;
}
LLUUID LLSettingsWater::GetDefaultTransparentTextureAssetId()
{
return DEFAULT_TRANSPARENT_WATER_TEXTURE;
}
LLUUID LLSettingsWater::GetDefaultOpaqueTextureAssetId()
{
return DEFAULT_OPAQUE_WATER_TEXTURE;
}
F32 LLSettingsWater::getModifiedWaterFogDensity(bool underwater) const
{
F32 fog_density = getWaterFogDensity();
F32 underwater_fog_mod = getFogMod();
if (underwater && underwater_fog_mod > 0.0f)
{
underwater_fog_mod = llclamp(underwater_fog_mod, 0.0f, 10.0f);
fog_density = pow(fog_density, underwater_fog_mod);
}
return fog_density;
}

View File

@@ -0,0 +1,249 @@
/**
* @file llsettingssky.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $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$
*/
#ifndef LL_SETTINGS_WATER_H
#define LL_SETTINGS_WATER_H
#include "llsettingsbase.h"
class LLSettingsWater : public LLSettingsBase
{
public:
static const std::string SETTING_BLUR_MULTIPLIER;
static const std::string SETTING_FOG_COLOR;
static const std::string SETTING_FOG_DENSITY;
static const std::string SETTING_FOG_MOD;
static const std::string SETTING_FRESNEL_OFFSET;
static const std::string SETTING_FRESNEL_SCALE;
static const std::string SETTING_TRANSPARENT_TEXTURE;
static const std::string SETTING_NORMAL_MAP;
static const std::string SETTING_NORMAL_SCALE;
static const std::string SETTING_SCALE_ABOVE;
static const std::string SETTING_SCALE_BELOW;
static const std::string SETTING_WAVE1_DIR;
static const std::string SETTING_WAVE2_DIR;
static const LLUUID DEFAULT_ASSET_ID;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsWater> ptr_t;
//---------------------------------------------------------------------
LLSettingsWater(const LLSD &data);
virtual ~LLSettingsWater() { };
virtual ptr_t buildClone() const = 0;
//---------------------------------------------------------------------
virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("water"); }
virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_WATER; }
// Settings status
virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE;
virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE;
void replaceWithWater(LLSettingsWater::ptr_t other);
static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f);
//---------------------------------------------------------------------
F32 getBlurMultiplier() const
{
return mSettings[SETTING_BLUR_MULTIPLIER].asReal();
}
void setBlurMultiplier(F32 val)
{
setValue(SETTING_BLUR_MULTIPLIER, val);
}
LLColor3 getWaterFogColor() const
{
return LLColor3(mSettings[SETTING_FOG_COLOR]);
}
void setWaterFogColor(LLColor3 val)
{
setValue(SETTING_FOG_COLOR, val);
}
F32 getWaterFogDensity() const
{
return mSettings[SETTING_FOG_DENSITY].asReal();
}
F32 getModifiedWaterFogDensity(bool underwater) const;
void setWaterFogDensity(F32 val)
{
setValue(SETTING_FOG_DENSITY, val);
}
F32 getFogMod() const
{
return mSettings[SETTING_FOG_MOD].asReal();
}
void setFogMod(F32 val)
{
setValue(SETTING_FOG_MOD, val);
}
F32 getFresnelOffset() const
{
return mSettings[SETTING_FRESNEL_OFFSET].asReal();
}
void setFresnelOffset(F32 val)
{
setValue(SETTING_FRESNEL_OFFSET, val);
}
F32 getFresnelScale() const
{
return mSettings[SETTING_FRESNEL_SCALE].asReal();
}
void setFresnelScale(F32 val)
{
setValue(SETTING_FRESNEL_SCALE, val);
}
LLUUID getTransparentTextureID() const
{
return mSettings[SETTING_TRANSPARENT_TEXTURE].asUUID();
}
void setTransparentTextureID(LLUUID val)
{
setValue(SETTING_TRANSPARENT_TEXTURE, val);
}
LLUUID getNormalMapID() const
{
return mSettings[SETTING_NORMAL_MAP].asUUID();
}
void setNormalMapID(LLUUID val)
{
setValue(SETTING_NORMAL_MAP, val);
}
LLVector3 getNormalScale() const
{
return LLVector3(mSettings[SETTING_NORMAL_SCALE]);
}
void setNormalScale(LLVector3 val)
{
setValue(SETTING_NORMAL_SCALE, val);
}
F32 getScaleAbove() const
{
return mSettings[SETTING_SCALE_ABOVE].asReal();
}
void setScaleAbove(F32 val)
{
setValue(SETTING_SCALE_ABOVE, val);
}
F32 getScaleBelow() const
{
return mSettings[SETTING_SCALE_BELOW].asReal();
}
void setScaleBelow(F32 val)
{
setValue(SETTING_SCALE_BELOW, val);
}
LLVector2 getWave1Dir() const
{
return LLVector2(mSettings[SETTING_WAVE1_DIR]);
}
void setWave1Dir(LLVector2 val)
{
setValue(SETTING_WAVE1_DIR, val);
}
LLVector2 getWave2Dir() const
{
return LLVector2(mSettings[SETTING_WAVE2_DIR]);
}
void setWave2Dir(LLVector2 val)
{
setValue(SETTING_WAVE2_DIR, val);
}
//-------------------------------------------
LLUUID getNextNormalMapID() const
{
return mNextNormalMapID;
}
LLUUID getNextTransparentTextureID() const
{
return mNextTransparentTextureID;
}
virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
static validation_list_t validationList();
static LLSD translateLegacySettings(LLSD legacy);
virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
static LLUUID GetDefaultAssetId();
static LLUUID GetDefaultWaterNormalAssetId();
static LLUUID GetDefaultTransparentTextureAssetId();
static LLUUID GetDefaultOpaqueTextureAssetId();
protected:
static const std::string SETTING_LEGACY_BLUR_MULTIPLIER;
static const std::string SETTING_LEGACY_FOG_COLOR;
static const std::string SETTING_LEGACY_FOG_DENSITY;
static const std::string SETTING_LEGACY_FOG_MOD;
static const std::string SETTING_LEGACY_FRESNEL_OFFSET;
static const std::string SETTING_LEGACY_FRESNEL_SCALE;
static const std::string SETTING_LEGACY_NORMAL_MAP;
static const std::string SETTING_LEGACY_NORMAL_SCALE;
static const std::string SETTING_LEGACY_SCALE_ABOVE;
static const std::string SETTING_LEGACY_SCALE_BELOW;
static const std::string SETTING_LEGACY_WAVE1_DIR;
static const std::string SETTING_LEGACY_WAVE2_DIR;
LLSettingsWater();
LLUUID mNextTransparentTextureID;
LLUUID mNextNormalMapID;
};
#endif

View File

@@ -87,6 +87,7 @@ set(llmath_HEADER_FILES
raytrace.h
v2math.h
v3color.h
v3colorutil.h
v3dmath.h
v3math.h
v4color.h

View File

@@ -104,6 +104,11 @@ LLQuaternion::LLQuaternion(const LLVector3 &x_axis,
normalize();
}
LLQuaternion::LLQuaternion(const LLSD &sd)
{
setValue(sd);
}
// Quatizations
void LLQuaternion::quantize16(F32 lower, F32 upper)
{
@@ -860,6 +865,26 @@ void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const
}
}
const LLQuaternion& LLQuaternion::setFromAzimuthAndAltitude(F32 azimuthRadians, F32 altitudeRadians)
{
// euler angle inputs are complements of azimuth/altitude which are measured from zenith
F32 pitch = llclamp(F_PI_BY_TWO - altitudeRadians, 0.0f, F_PI_BY_TWO);
F32 yaw = llclamp(F_PI_BY_TWO - azimuthRadians, 0.0f, F_PI_BY_TWO);
setEulerAngles(0.0f, pitch, yaw);
return *this;
}
void LLQuaternion::getAzimuthAndAltitude(F32 &azimuthRadians, F32 &altitudeRadians)
{
F32 rick_roll;
F32 pitch;
F32 yaw;
getEulerAngles(&rick_roll, &pitch, &yaw);
// make these measured from zenith
altitudeRadians = llclamp(F_PI_BY_TWO - pitch, 0.0f, F_PI_BY_TWO);
azimuthRadians = llclamp(F_PI_BY_TWO - yaw, 0.0f, F_PI_BY_TWO);
}
// quaternion does not need to be normalized
void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const
{

View File

@@ -28,6 +28,7 @@
#define LLQUATERNION_H
#include <iostream>
#include "llsd.h"
#ifndef LLMATH_H //enforce specific include order to avoid tangling inline dependencies
#error "Please include llmath.h first."
@@ -63,6 +64,10 @@ public:
LLQuaternion(const LLVector3 &x_axis,
const LLVector3 &y_axis,
const LLVector3 &z_axis); // Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis]
explicit LLQuaternion(const LLSD &sd); // Initializes Quaternion from LLSD array.
LLSD getValue() const;
void setValue(const LLSD& sd);
BOOL isIdentity() const;
BOOL isNotIdentity() const;
@@ -79,6 +84,7 @@ public:
const LLQuaternion& set(const F32 *q); // Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW])
const LLQuaternion& set(const LLMatrix3 &mat); // Sets Quaternion to mat2quat(mat)
const LLQuaternion& set(const LLMatrix4 &mat); // Sets Quaternion to mat2quat(mat)
const LLQuaternion& setFromAzimuthAndAltitude(F32 azimuth, F32 altitude);
const LLQuaternion& setAngleAxis(F32 angle, F32 x, F32 y, F32 z); // Sets Quaternion to axis_angle2quat(angle, x, y, z)
const LLQuaternion& setAngleAxis(F32 angle, const LLVector3 &vec); // Sets Quaternion to axis_angle2quat(angle, vec)
@@ -100,6 +106,7 @@ public:
void getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const; // returns rotation in radians about axis x,y,z
void getAngleAxis(F32* angle, LLVector3 &vec) const;
void getEulerAngles(F32 *roll, F32* pitch, F32 *yaw) const;
void getAzimuthAndAltitude(F32 &azimuth, F32 &altitude);
F32 normalize(); // Normalizes Quaternion and returns magnitude
F32 normQuat(); // deprecated
@@ -166,6 +173,24 @@ public:
//static U32 mMultCount;
};
inline LLSD LLQuaternion::getValue() const
{
LLSD ret;
ret[0] = mQ[0];
ret[1] = mQ[1];
ret[2] = mQ[2];
ret[3] = mQ[3];
return ret;
}
inline void LLQuaternion::setValue(const LLSD& sd)
{
mQ[0] = sd[0].asReal();
mQ[1] = sd[1].asReal();
mQ[2] = sd[2].asReal();
mQ[3] = sd[3].asReal();
}
// checker
inline BOOL LLQuaternion::isFinite() const
{

115
indra/llmath/v3colorutil.h Normal file
View File

@@ -0,0 +1,115 @@
/**
* @file v3color.h
* @brief LLColor3 class header file.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
*/
#ifndef LL_V3COLORUTIL_H
#define LL_V3COLORUTIL_H
#include "v3color.h"
inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right)
{
return LLColor3(left.mV[0] / right.mV[0],
left.mV[1] / right.mV[1],
left.mV[2] / right.mV[2]);
}
inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right)
{
return LLColor3(left.mV[0] * right.mV[0],
left.mV[1] * right.mV[1],
left.mV[2] * right.mV[2]);
}
inline LLColor3 componentExp(LLColor3 const &v)
{
return LLColor3(exp(v.mV[0]),
exp(v.mV[1]),
exp(v.mV[2]));
}
inline LLColor3 componentPow(LLColor3 const &v, F32 exponent)
{
return LLColor3(pow(v.mV[0], exponent),
pow(v.mV[1], exponent),
pow(v.mV[2], exponent));
}
inline LLColor3 componentSaturate(LLColor3 const &v)
{
return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f),
std::max(std::min(v.mV[1], 1.f), 0.f),
std::max(std::min(v.mV[2], 1.f), 0.f));
}
inline LLColor3 componentSqrt(LLColor3 const &v)
{
return LLColor3(sqrt(v.mV[0]),
sqrt(v.mV[1]),
sqrt(v.mV[2]));
}
inline void componentMultBy(LLColor3 & left, LLColor3 const & right)
{
left.mV[0] *= right.mV[0];
left.mV[1] *= right.mV[1];
left.mV[2] *= right.mV[2];
}
inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
{
return (left + ((right - left) * amount));
}
inline LLColor3 smear(F32 val)
{
return LLColor3(val, val, val);
}
inline F32 color_intens(const LLColor3 &col)
{
return col.mV[0] + col.mV[1] + col.mV[2];
}
inline F32 color_max(const LLColor3 &col)
{
return llmax(col.mV[0], col.mV[1], col.mV[2]);
}
inline F32 color_max(const LLColor4 &col)
{
return llmax(col.mV[0], col.mV[1], col.mV[2]);
}
inline F32 color_min(const LLColor3 &col)
{
return llmin(col.mV[0], col.mV[1], col.mV[2]);
}
#endif