[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:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
117
indra/llinventory/llinventorysettings.cpp
Normal file
117
indra/llinventory/llinventorysettings.cpp
Normal 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();
|
||||
}
|
||||
56
indra/llinventory/llinventorysettings.h
Normal file
56
indra/llinventory/llinventorysettings.h
Normal 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
|
||||
41
indra/llinventory/llinvtranslationbrdg.h
Normal file
41
indra/llinventory/llinvtranslationbrdg.h
Normal 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
|
||||
@@ -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;
|
||||
|
||||
758
indra/llinventory/llsettingsbase.cpp
Normal file
758
indra/llinventory/llsettingsbase.cpp
Normal 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;
|
||||
}
|
||||
538
indra/llinventory/llsettingsbase.h
Normal file
538
indra/llinventory/llsettingsbase.h
Normal 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 ¶m) 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
|
||||
891
indra/llinventory/llsettingsdaycycle.cpp
Normal file
891
indra/llinventory/llsettingsdaycycle.cpp
Normal 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;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
156
indra/llinventory/llsettingsdaycycle.h
Normal file
156
indra/llinventory/llsettingsdaycycle.h
Normal 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
|
||||
1692
indra/llinventory/llsettingssky.cpp
Normal file
1692
indra/llinventory/llsettingssky.cpp
Normal file
File diff suppressed because it is too large
Load Diff
361
indra/llinventory/llsettingssky.h
Normal file
361
indra/llinventory/llsettingssky.h
Normal 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
|
||||
303
indra/llinventory/llsettingswater.cpp
Normal file
303
indra/llinventory/llsettingswater.cpp
Normal 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;
|
||||
}
|
||||
249
indra/llinventory/llsettingswater.h
Normal file
249
indra/llinventory/llsettingswater.h
Normal 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
|
||||
@@ -87,6 +87,7 @@ set(llmath_HEADER_FILES
|
||||
raytrace.h
|
||||
v2math.h
|
||||
v3color.h
|
||||
v3colorutil.h
|
||||
v3dmath.h
|
||||
v3math.h
|
||||
v4color.h
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
115
indra/llmath/v3colorutil.h
Normal 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
|
||||
Reference in New Issue
Block a user