Ansariel 2021-02-15 21:22:24 +01:00
commit fd06acc270
129 changed files with 3323 additions and 769 deletions

View File

@ -22,9 +22,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>aa31ee4c6315cb26bf6e2191b69598f5</string>
<string>1f887cbafc0fe2af1e85783de0f14102</string>
<key>url</key>
<string>http://3p.firestormviewer.org/jemalloc-5.1.0-linux64-190582149.tar.bz2</string>
<string>http://3p.firestormviewer.org/jemalloc-5.2.1-linux64-210451204.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@ -964,11 +964,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>87c4984c2bddcdaf6ca403a06f22ce4e</string>
<string>4f9bf4566934e6e8611ef918186f20c5</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>file:///opt/firestorm/fmodstudio-2.01.07-darwin-210010951.tar.bz2</string>
<string>file:///opt/firestorm/fmodstudio-2.01.08-darwin-210441530.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -978,11 +978,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>d33d848660ca7e4c2de789e325706d24</string>
<string>c8024bad0445af488d355670ba13cc40</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>file:///opt/firestorm/fmodstudio-2.01.07-linux64-203630250.tar.bz2</string>
<string>file:///opt/firestorm/fmodstudio-2.01.08-linux64-210441517.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@ -992,11 +992,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>9e9f303912776014519c18a0205250ee</string>
<string>c27de9c2f8c562551773a80399d6d037</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.07-windows-203561745.tar.bz2</string>
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.08-windows-210431451.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -1006,18 +1006,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>ae336fe814a6867f6449d0401ea7a9e4</string>
<string>29a66f79f7224cc17aa22d047853f7b0</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.07-windows64-203561747.tar.bz2</string>
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.08-windows64-210431454.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>2.01.07</string>
<string>2.01.08</string>
</map>
<key>fontconfig</key>
<map>

View File

@ -401,11 +401,7 @@ inline bool operator!=(const LLVector3d& a, const LLVector3d& b)
// [RLVa:KB] - RlvBehaviourModifierCompMin/Max
inline bool operator<(const LLVector3d& lhs, const LLVector3d& rhs)
{
return (lhs.mdV[0] < rhs.mdV[0]
|| (lhs.mdV[0] == rhs.mdV[0]
&& (lhs.mdV[1] < rhs.mdV[1]
|| ((lhs.mdV[1] == rhs.mdV[1])
&& lhs.mdV[2] < rhs.mdV[2]))));
return std::tie(lhs.mdV[0], lhs.mdV[1], lhs.mdV[2]) < std::tie(rhs.mdV[0], rhs.mdV[1], rhs.mdV[2]);
}
// [/RLVa:KB]

View File

@ -468,6 +468,13 @@ inline LLVector4 operator-(const LLVector4 &a)
return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] );
}
// [RLVa:KB] - RlvBehaviourModifierCompMin/Max
inline bool operator<(const LLVector4& lhs, const LLVector4& rhs)
{
return std::tie(lhs.mV[0], lhs.mV[1], lhs.mV[2], lhs.mV[3]) < std::tie(rhs.mV[0], rhs.mV[1], rhs.mV[2], rhs.mV[3]);
}
// [/RLVa:KB]
inline F32 dist_vec(const LLVector4 &a, const LLVector4 &b)
{
LLVector4 vec = a - b;

View File

@ -632,6 +632,13 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
// returns bool specifying if av_name was filled, false otherwise
bool LLAvatarNameCache::getName(const LLUUID& agent_id, LLAvatarName *av_name)
{
// <FS:Beq> Avoid null entries entering NameCache
// This is a catch-all, better to avoid at call site
if( agent_id.isNull() )
{
return false;
}
// </FS:Beq>
if (mRunning)
{
// ...only do immediate lookups when cache is running

View File

@ -156,9 +156,9 @@ void LLPluginProcessParent::shutdown()
{
EState state = (*it).second->mState;
if (state != STATE_CLEANUP
|| state != STATE_EXITING
|| state != STATE_DONE
|| state != STATE_ERROR)
&& state != STATE_EXITING
&& state != STATE_DONE
&& state != STATE_ERROR)
{
(*it).second->setState(STATE_GOODBYE);
}
@ -920,7 +920,8 @@ void LLPluginProcessParent::poll(F64 timeout)
// }
else
{
LL_WARNS("PluginPoll") << "apr_pollset_poll failed with status " << status << " (" << APR_TO_OS_ERROR(status) << ")" << LL_ENDL;
LL_WARNS("PluginPoll") << "apr_pollset_poll failed with status " << status << " (" << APR_TO_OS_ERROR(status) << ") Rebuild PollSet" << LL_ENDL;
sPollsetNeedsRebuild = true;
}
// </FS:Beq>
}

View File

@ -1355,6 +1355,14 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("sunAngle2");
mReservedUniforms.push_back("camPosLocal");
// [RLVa:KB] - @setsphere
mReservedUniforms.push_back("rlvEffectMode");
mReservedUniforms.push_back("rlvEffectParam1");
mReservedUniforms.push_back("rlvEffectParam2");
mReservedUniforms.push_back("rlvEffectParam3");
mReservedUniforms.push_back("rlvEffectParam4");
mReservedUniforms.push_back("rlvEffectParam5");
// [/RLV:KB]
mReservedUniforms.push_back("gWindDir");
mReservedUniforms.push_back("gSinWaveParams");

View File

@ -210,6 +210,14 @@ public:
WATER_SUN_ANGLE2,
WL_CAMPOSLOCAL,
// [RLVa:KB] - @setsphere
RLV_EFFECT_MODE,
RLV_EFFECT_PARAM1,
RLV_EFFECT_PARAM2,
RLV_EFFECT_PARAM3,
RLV_EFFECT_PARAM4,
RLV_EFFECT_PARAM5,
// [/RLVa:KB]
AVATAR_WIND,
AVATAR_SINWAVE,

View File

@ -44,7 +44,12 @@ enum EFSRegistrarFunctionActionType
FS_RGSTR_ACT_REQUEST_TELEPORT,
FS_RGSTR_CHK_AVATAR_BLOCKED,
FS_RGSTR_CHK_IS_SELF,
FS_RGSTR_CHK_IS_NOT_SELF
FS_RGSTR_CHK_IS_NOT_SELF,
FS_RGSTR_CHK_WAITING_FOR_GROUP_DATA,
FS_RGSTR_CHK_HAVE_GROUP_DATA,
FS_RGSTR_CHK_CAN_LEAVE_GROUP,
FS_RGSTR_CHK_CAN_JOIN_GROUP,
FS_RGSTR_CHK_GROUP_NOT_ACTIVE
};
class FSRegistrarUtils

View File

@ -132,6 +132,7 @@ LLScrollListCtrl::Params::Params()
search_column("search_column", 0),
sort_column("sort_column", -1),
sort_ascending("sort_ascending", true),
sort_lazily("sort_lazily", false), // <FS:Beq> FIRE-30732 deferred sort as a UI property
persist_sort_order("persist_sort_order", false), // <FS:Ansariel> Persists sort order of scroll lists
primary_sort_only("primary_sort_only", false), // <FS:Ansariel> Option to only sort by one column
mouse_wheel_opaque("mouse_wheel_opaque", false),
@ -186,6 +187,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mTotalStaticColumnWidth(0),
mTotalColumnPadding(0),
mSorted(false),
mSortLazily(p.sort_lazily), // <FS:Beq> FIRE-30732 deferred sort configurability
mDirty(false),
mOriginalSelection(-1),
mLastSelected(NULL),
@ -2112,6 +2114,20 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
enable_registrar.add("FS.EnableViewLog", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, uuid, FS_RGSTR_ACT_VIEW_TRANSCRIPT));
// </FS:Ansariel>
// <FS:Zi> FIRE-30725 - Add more group functions to group URL context menu
std::string uuid_str = uuid.asString();
registrar.add("FS.JoinGroup", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + uuid_str + "/groupjoin", true));
registrar.add("FS.LeaveGroup", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + uuid_str + "/groupleave", true));
registrar.add("FS.ActivateGroup", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + uuid_str + "/groupactivate", true));
enable_registrar.add("FS.WaitingForGroupData", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, uuid, FS_RGSTR_CHK_WAITING_FOR_GROUP_DATA));
enable_registrar.add("FS.HaveGroupData", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, uuid, FS_RGSTR_CHK_HAVE_GROUP_DATA));
enable_registrar.add("FS.EnableJoinGroup", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, uuid, FS_RGSTR_CHK_CAN_JOIN_GROUP));
enable_registrar.add("FS.EnableLeaveGroup", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, uuid, FS_RGSTR_CHK_CAN_LEAVE_GROUP));
enable_registrar.add("FS.EnableActivateGroup", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, uuid, FS_RGSTR_CHK_GROUP_NOT_ACTIVE));
// </FS:Zi>
// create the context menu from the XUI file and display it
std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml";
delete mPopupMenu;
@ -2957,7 +2973,9 @@ void LLScrollListCtrl::updateSort() const
// if (hasSortOrder() && !isSorted())
// {
static LLUICachedControl<U32> sortDeferFrameCount("FSSortDeferalFrames");
if ( hasSortOrder() && !isSorted() && ( mLastUpdateFrame > 1 && ( LLFrameTimer::getFrameCount() - mLastUpdateFrame ) >= sortDeferFrameCount ) )
if ( hasSortOrder() && !isSorted() &&
( !mSortLazily || // if deferred sorting is off OR the deferral period has been exceeded
( mLastUpdateFrame > 1 && ( LLFrameTimer::getFrameCount() - mLastUpdateFrame ) >= sortDeferFrameCount ) ) )
// encoding two (unlikely) special values into mLastUpdateFrame 1 means we've sorted and 0 means we've nothing new to do.
// 0 is set after sorting, 1 can be set by a parent for any post sorting action.
{

View File

@ -117,6 +117,7 @@ public:
Optional<S32> search_column,
sort_column;
Optional<bool> sort_ascending;
Optional<bool> sort_lazily; // <FS:Beq> FIRE-30732 deferred sort as a UI property
Optional<bool> persist_sort_order; // <FS:Ansariel> Persists sort order of scroll lists
Optional<bool> primary_sort_only; // <FS:Ansariel> Option to only sort by one column
@ -559,6 +560,8 @@ private:
// <FS:Ansariel> Option to only sort by one column
bool mPrimarySortOnly;
// <FS:Beq> deferred sort as a UI property
bool mSortLazily;
mutable bool mSorted;

View File

@ -2186,6 +2186,18 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
enable_registrar.add("FS.EnableViewLog", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, target_id, FS_RGSTR_ACT_VIEW_TRANSCRIPT));
// </FS:Ansariel>
// <FS:Zi> FIRE-30725 - Add more group functions to group URL context menu
registrar.add("FS.JoinGroup", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/groupjoin", true));
registrar.add("FS.LeaveGroup", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/groupleave", true));
registrar.add("FS.ActivateGroup", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/groupactivate", true));
enable_registrar.add("FS.WaitingForGroupData", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, target_id, FS_RGSTR_CHK_WAITING_FOR_GROUP_DATA));
enable_registrar.add("FS.HaveGroupData", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, target_id, FS_RGSTR_CHK_HAVE_GROUP_DATA));
enable_registrar.add("FS.EnableJoinGroup", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, target_id, FS_RGSTR_CHK_CAN_JOIN_GROUP));
enable_registrar.add("FS.EnableLeaveGroup", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, target_id, FS_RGSTR_CHK_CAN_LEAVE_GROUP));
enable_registrar.add("FS.EnableActivateGroup", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, target_id, FS_RGSTR_CHK_GROUP_NOT_ACTIVE));
// </FS:Zi>
// create and return the context menu from the XUI file
LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());

View File

@ -60,7 +60,7 @@ namespace
// LLWindowMacOSX
//
BOOL LLWindowMacOSX::sUseMultGL = FALSE;
BOOL LLWindowMacOSX::sUseMultGL = TRUE;
// Cross-platform bits:

View File

@ -1454,24 +1454,29 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
LL_INFOS("Window") << "pixel formats done." << LL_ENDL ;
S32 swap_method = 0;
S32 cur_format = num_formats-1;
GLint swap_query = WGL_SWAP_METHOD_ARB;
S32 swap_method = 0;
S32 cur_format = 0;
GLint swap_query = WGL_SWAP_METHOD_ARB;
BOOL found_format = FALSE;
while (!found_format && wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method))
// SL-14705 Fix name tags showing in front of objects with AMD GPUs.
// On AMD hardware we need to iterate from the first pixel format to the end.
// Spec:
// https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_pixel_format.txt
while (wglGetPixelFormatAttribivARB(mhDC, pixel_formats[cur_format], 0, 1, &swap_query, &swap_method))
{
if (swap_method == WGL_SWAP_UNDEFINED_ARB || cur_format <= 0)
if (swap_method == WGL_SWAP_UNDEFINED_ARB)
{
found_format = TRUE;
break;
}
else
else if (cur_format >= (S32)(num_formats - 1))
{
--cur_format;
cur_format = 0;
break;
}
++cur_format;
}
pixel_format = pixel_formats[cur_format];
if (mhDC != 0) // Does The Window Have A Device Context?
@ -2001,7 +2006,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( h_wnd, GWLP_USERDATA );
bool debug_window_proc = gDebugWindowProc || debugLoggingEnabled("Window");
//<FS:Beq> avoid unfortunate sleep during trylock by static check
// bool debug_window_proc = gDebugWindowProc || debugLoggingEnabled("Window");
static auto debug_logging_on = debugLoggingEnabled("Window");
bool debug_window_proc = gDebugWindowProc || debug_logging_on;
//</FS:Beq>
if (NULL != window_imp)

View File

@ -806,6 +806,7 @@ set(viewer_SOURCE_FILES
llviewerwearable.cpp
llviewerwindow.cpp
llviewerwindowlistener.cpp
llvisualeffect.cpp
llvlcomposition.cpp
llvlmanager.cpp
llvoavatar.cpp
@ -851,14 +852,14 @@ set(viewer_SOURCE_FILES
quickprefs.cpp
rlvactions.cpp
rlvenvironment.cpp
rlvhandler.cpp
rlvhelper.cpp
rlvcommon.cpp
rlvlocks.cpp
rlvinventory.cpp
rlveffects.cpp
rlvextensions.cpp
rlvfloaters.cpp
rlvmodifiers.cpp
rlvhandler.cpp
rlvhelper.cpp
rlvinventory.cpp
rlvlocks.cpp
rlvui.cpp
sanitycheck.cpp
streamtitledisplay.cpp
@ -1567,6 +1568,7 @@ set(viewer_HEADER_FILES
llviewerwearable.h
llviewerwindow.h
llviewerwindowlistener.h
llvisualeffect.h
llvlcomposition.h
llvlmanager.h
llvoavatar.h
@ -1609,15 +1611,16 @@ set(viewer_HEADER_FILES
pieslice.h
pipeline.h
rlvactions.h
rlvenvironment.h
rlvdefines.h
rlvhandler.h
rlvhelper.h
rlvcommon.h
rlvlocks.h
rlvinventory.h
rlvdefines.h
rlveffects.h
rlvenvironment.h
rlvextensions.h
rlvfloaters.h
rlvhandler.h
rlvhelper.h
rlvinventory.h
rlvlocks.h
rlvmodifiers.h
rlvui.h
roles_constants.h

View File

@ -63,6 +63,7 @@ AOEngine::AOEngine() :
{
gSavedPerAccountSettings.getControl("UseAO")->getCommitSignal()->connect(boost::bind(&AOEngine::onToggleAOControl, this));
gSavedPerAccountSettings.getControl("UseAOStands")->getCommitSignal()->connect(boost::bind(&AOEngine::onToggleAOStandsControl, this));
gSavedPerAccountSettings.getControl("PauseAO")->getCommitSignal()->connect(boost::bind(&AOEngine::onPauseAO, this));
mRegionChangeConnection = gAgent.addRegionChangedCallback(boost::bind(&AOEngine::onRegionChange, this));
}
@ -117,6 +118,15 @@ void AOEngine::onToggleAOStandsControl()
enableStands(gSavedPerAccountSettings.getBOOL("UseAOStands"));
}
void AOEngine::onPauseAO()
{
// can't use mEnabled here as that gets switched over by enable()
if (gSavedPerAccountSettings.getBOOL("UseAO"))
{
enable(!gSavedPerAccountSettings.getBOOL("PauseAO"));
}
}
void AOEngine::clear(bool from_timer)
{
mOldSets.insert(mOldSets.end(), mSets.begin(), mSets.end());

View File

@ -183,6 +183,8 @@ class AOEngine
void onToggleAOControl();
void onToggleAOStandsControl();
void onPauseAO();
static void onNotecardLoadComplete(LLVFS* vfs, const LLUUID& assetUUID, LLAssetType::EType type,
void* userdata, S32 status, LLExtStat extStatus);
void parseNotecard(const char* buffer);

View File

@ -507,6 +507,8 @@
execute_parameters="fs_posestand"
is_running_function="Floater.IsOpen"
is_running_parameters="fs_posestand"
is_enabled_function="Agent.IsActionAllowed"
is_enabled_parameters="fs_when_not_sitting"
/>
<command name="snapshot_to_disk"
available_in_toybox="true"

View File

@ -1,56 +1,56 @@
<llsd>
<map>
<key>d6fee4de-09af-80b2-72c9-dd5eb509f18c</key>
<key>3481ccd5-cc6c-65ca-c466-dc9df1bf3944</key>
<map>
<key>name</key>
<string>PS_T_Pose</string>
</map>
<key>63db3570-950d-089c-54c5-b406cb32635b</key>
<key>0b4ee516-5dfd-ef4b-4ab6-300bb44cb045</key>
<map>
<key>name</key>
<string>PS_Arms_Down_Legs_together</string>
</map>
<key>46d5043d-6d86-c237-ab9c-c088d5608f37</key>
<key>b23c52ef-0b15-11f2-852d-8fbd33417847</key>
<map>
<key>name</key>
<string>PS_Arms_down_sitting</string>
</map>
<key>767d488a-faa5-aeca-128f-af0b196967f1</key>
<key>e14fee5f-3735-a236-2e26-94f92f366d81</key>
<map>
<key>name</key>
<string>PS_Arms_downward_Legs_apart</string>
</map>
<key>c2a3ba2f-499f-6129-2c43-2085815b3c81</key>
<key>2029d88f-4efc-d72d-18d1-274caf9e9bc0</key>
<map>
<key>name</key>
<string>PS_Arms_downward_Legs_together</string>
</map>
<key>9e6fbfdb-d83e-a590-d59d-571c49002a7c</key>
<key>cff5559e-c915-0b5e-d587-f789b5cc299a</key>
<map>
<key>name</key>
<string>PS_Arms_forward_Legs_apart</string>
</map>
<key>64d9b2e0-a124-b5fa-73f1-8703218f9aa8</key>
<key>23f3163c-183b-dac0-0cdd-7811bcc3b5f1</key>
<map>
<key>name</key>
<string>PS_Arms_forward_Legs_together</string>
</map>
<key>a5b4ae9f-05d2-998f-5ca5-63ac5cfdf595</key>
<key>b2f312aa-2c1e-27b8-50fe-a0fa4ff3df4e</key>
<map>
<key>name</key>
<string>PS_Arms_straight_Legs_apart</string>
</map>
<key>16ca97b1-732d-8964-f044-1575d8bc2f98</key>
<key>c17677b8-9fb2-8d6e-bbbe-219edce64ef4</key>
<map>
<key>name</key>
<string>PS_Arms_straight_sitting</string>
</map>
<key>284ff48c-5f45-8351-c459-020f0bc1cd77</key>
<key>2cfeed25-04f9-caff-f3d2-776cddea5771</key>
<map>
<key>name</key>
<string>PS_Arms_upward_Legs_apart</string>
</map>
<key>76e563a3-6a97-0487-f8dc-70a673fa58d8</key>
<key>6e83f685-2f53-278f-6758-b529327cce09</key>
<map>
<key>name</key>
<string>PS_Arms_upward_Legs_together</string>

View File

@ -353,7 +353,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>2</integer>
<integer>5</integer>
</map>
<key>FSGroupNotifyNoTransparency</key>
<map>
@ -25623,5 +25623,16 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>FSStatusBarTimeFormat</key>
<map>
<key>Comment</key>
<string>Which time format to use for the status bar clock, e.g. 12 Hours, 24 Hours, etc. The default "Language" restores the original behavior of changing the time display mode per language.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>Language</string>
</map>
</map>
</llsd>

View File

@ -744,6 +744,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>PauseAO</key>
<map>
<key>Comment</key>
<string>Pause the viewer side Animation Overrider</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>UseAOStands</key>
<map>
<key>Comment</key>

View File

@ -0,0 +1,167 @@
/**
*
* Copyright (c) 2018-2020, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
#extension GL_ARB_texture_rectangle : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
VARYING vec2 vary_fragcoord;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect depthMap;
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform int rlvEffectMode; // ESphereMode
uniform vec4 rlvEffectParam1; // Sphere origin (in local coordinates)
uniform vec4 rlvEffectParam2; // Min/max dist + min/max value
uniform bvec2 rlvEffectParam3; // Min/max dist extend
uniform vec4 rlvEffectParam4; // Sphere params (=color when using blend)
uniform vec2 rlvEffectParam5; // Blur direction (not used for blend)
#define SPHERE_ORIGIN rlvEffectParam1.xyz
#define SPHERE_DISTMIN rlvEffectParam2.y
#define SPHERE_DISTMAX rlvEffectParam2.w
#define SPHERE_DISTEXTEND rlvEffectParam3
#define SPHERE_VALUEMIN rlvEffectParam2.x
#define SPHERE_VALUEMAX rlvEffectParam2.z
#define SPHERE_PARAMS rlvEffectParam4
#define BLUR_DIRECTION rlvEffectParam5.xy
vec4 getPosition_d(vec2 pos_screen, float depth)
{
vec2 sc = pos_screen.xy * 2.0;
sc /= screen_res;
sc -= vec2(1.0, 1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0 * depth - 1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
vec3 blur13(sampler2DRect source, vec2 tc, vec2 direction)
{
vec4 color = vec4(0.0);
vec2 off1 = vec2(1.411764705882353) * direction;
vec2 off2 = vec2(3.2941176470588234) * direction;
vec2 off3 = vec2(5.176470588235294) * direction;
color += texture2DRect(source, tc) * 0.1964825501511404;
color += texture2DRect(source, tc + off1) * 0.2969069646728344;
color += texture2DRect(source, tc - off1) * 0.2969069646728344;
color += texture2DRect(source, tc + off2) * 0.09447039785044732;
color += texture2DRect(source, tc - off2) * 0.09447039785044732;
color += texture2DRect(source, tc + off3) * 0.010381362401148057;
color += texture2DRect(source, tc - off3) * 0.010381362401148057;
return color.xyz;
}
const float pi = 3.14159265;
// http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
vec3 blurVariable(sampler2DRect source, vec2 tc, float kernelSize, vec2 direction, float strength) {
float numBlurPixelsPerSide = float(kernelSize / 2);
// Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
vec3 incrementalGaussian;
incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * strength);
incrementalGaussian.y = exp(-0.5 / (strength * strength));
incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
float coefficientSum = 0.0;
// Take the central sample first...
avgValue += texture2DRect(source, tc) * incrementalGaussian.x;
coefficientSum += incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
// Go through the remaining 8 vertical samples (4 on each side of the center)
for (float i = 1.0; i <= numBlurPixelsPerSide; i++) {
avgValue += texture2DRect(source, tc - i * direction) * incrementalGaussian.x;
avgValue += texture2DRect(source, tc + i * direction) * incrementalGaussian.x;
coefficientSum += 2.0 * incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
}
return (avgValue / coefficientSum).rgb;
}
vec3 chromaticAberration(sampler2DRect source, vec2 tc, vec2 redDrift, vec2 blueDrift, float strength)
{
vec3 sourceColor = texture2DRect(source, tc).rgb;
// Sample the color components
vec3 driftColor;
driftColor.r = texture2DRect(source, tc + redDrift).r;
driftColor.g = sourceColor.g;
driftColor.b = texture2DRect(source, tc + blueDrift).b;
// Adjust the strength of the effect
return mix(sourceColor, driftColor, strength);
}
void main()
{
vec2 fragTC = vary_fragcoord.st;
float fragDepth = texture2DRect(depthMap, fragTC).x;
vec3 fragPosLocal = getPosition_d(fragTC, fragDepth).xyz;
float distance = length(fragPosLocal.xyz - SPHERE_ORIGIN);
// Linear non-branching interpolation of the strength of the sphere effect (replaces if/elseif/else for x < min, min <= x <= max and x > max)
float effectStrength = SPHERE_VALUEMIN + mix(0, SPHERE_VALUEMAX - SPHERE_VALUEMIN, (distance - SPHERE_DISTMIN) / (SPHERE_DISTMAX - SPHERE_DISTMIN));
effectStrength = mix(effectStrength, mix(0, SPHERE_VALUEMIN, SPHERE_DISTEXTEND.x), distance < SPHERE_DISTMIN);
effectStrength = mix(effectStrength, mix(0, SPHERE_VALUEMAX, SPHERE_DISTEXTEND.y), distance > SPHERE_DISTMAX);
vec3 fragColor;
switch (rlvEffectMode)
{
case 0: // Blend
fragColor = texture2DRect(diffuseRect, fragTC).rgb;
fragColor = mix(fragColor, SPHERE_PARAMS.rgb, effectStrength);
break;
case 1: // Blur (fixed)
fragColor = blur13(diffuseRect, fragTC, effectStrength * BLUR_DIRECTION);
break;
case 2: // Blur (variable)
fragColor = texture2DRect(diffuseRect, fragTC).rgb;
fragColor = mix(fragColor, blurVariable(diffuseRect, fragTC, SPHERE_PARAMS.x, BLUR_DIRECTION, effectStrength), int(effectStrength > 0));
break;
case 3: // ChromaticAberration
fragColor = chromaticAberration(diffuseRect, fragTC, SPHERE_PARAMS.xy, SPHERE_PARAMS.zw, effectStrength);
break;
case 4: // Pixelate
{
effectStrength = sign(effectStrength);
float pixelWidth = max(1, round(SPHERE_PARAMS.x * effectStrength)); float pixelHeight = max(1, round(SPHERE_PARAMS.y * effectStrength));
fragTC = vec2(pixelWidth * floor(fragTC.x / pixelWidth), pixelHeight * floor(fragTC.y / pixelHeight));
fragColor = texture2DRect(diffuseRect, fragTC).rgb;
}
break;
}
frag_color.rgb = fragColor;
frag_color.a = 0.0;
}

View File

@ -0,0 +1,176 @@
/**
*
* Copyright (c) 2018-2020, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
#extension GL_ARB_texture_rectangle : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
VARYING vec2 vary_fragcoord;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect depthMap;
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform int rlvEffectMode; // ESphereMode
uniform vec4 rlvEffectParam1; // Sphere origin (in local coordinates)
uniform vec4 rlvEffectParam2; // Min/max dist + min/max value
uniform bvec2 rlvEffectParam3; // Min/max dist extend
uniform vec4 rlvEffectParam4; // Sphere params (=color when using blend)
uniform vec2 rlvEffectParam5; // Blur direction (not used for blend)
#define SPHERE_ORIGIN rlvEffectParam1.xyz
#define SPHERE_DISTMIN rlvEffectParam2.y
#define SPHERE_DISTMAX rlvEffectParam2.w
#define SPHERE_DISTEXTEND rlvEffectParam3
#define SPHERE_VALUEMIN rlvEffectParam2.x
#define SPHERE_VALUEMAX rlvEffectParam2.z
#define SPHERE_PARAMS rlvEffectParam4
#define BLUR_DIRECTION rlvEffectParam5.xy
vec4 getPosition_d(vec2 pos_screen, float depth)
{
vec2 sc = pos_screen.xy * 2.0;
sc /= screen_res;
sc -= vec2(1.0, 1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0 * depth - 1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
vec3 blur13(sampler2DRect source, vec2 tc, vec2 direction)
{
vec4 color = vec4(0.0);
vec2 off1 = vec2(1.411764705882353) * direction;
vec2 off2 = vec2(3.2941176470588234) * direction;
vec2 off3 = vec2(5.176470588235294) * direction;
color += texture2DRect(source, tc) * 0.1964825501511404;
color += texture2DRect(source, tc + off1) * 0.2969069646728344;
color += texture2DRect(source, tc - off1) * 0.2969069646728344;
color += texture2DRect(source, tc + off2) * 0.09447039785044732;
color += texture2DRect(source, tc - off2) * 0.09447039785044732;
color += texture2DRect(source, tc + off3) * 0.010381362401148057;
color += texture2DRect(source, tc - off3) * 0.010381362401148057;
return color.xyz;
}
const float pi = 3.14159265;
// http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
vec3 blurVariable(sampler2DRect source, vec2 tc, float kernelSize, vec2 direction, float strength) {
float numBlurPixelsPerSide = float(kernelSize / 2);
// Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
vec3 incrementalGaussian;
incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * strength);
incrementalGaussian.y = exp(-0.5 / (strength * strength));
incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
float coefficientSum = 0.0;
// Take the central sample first...
avgValue += texture2DRect(source, tc) * incrementalGaussian.x;
coefficientSum += incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
// Go through the remaining 8 vertical samples (4 on each side of the center)
for (float i = 1.0; i <= numBlurPixelsPerSide; i++) {
avgValue += texture2DRect(source, tc - i * direction) * incrementalGaussian.x;
avgValue += texture2DRect(source, tc + i * direction) * incrementalGaussian.x;
coefficientSum += 2.0 * incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
}
return (avgValue / coefficientSum).rgb;
}
vec3 chromaticAberration(sampler2DRect source, vec2 tc, vec2 redDrift, vec2 blueDrift, float strength)
{
vec3 sourceColor = texture2DRect(source, tc).rgb;
// Sample the color components
vec3 driftColor;
driftColor.r = texture2DRect(source, tc + redDrift).r;
driftColor.g = sourceColor.g;
driftColor.b = texture2DRect(source, tc + blueDrift).b;
// Adjust the strength of the effect
return mix(sourceColor, driftColor, strength);
}
void main()
{
vec2 fragTC = vary_fragcoord.st;
float fragDepth = texture2DRect(depthMap, fragTC).x;
vec3 fragPosLocal = getPosition_d(fragTC, fragDepth).xyz;
float distance = length(fragPosLocal.xyz - SPHERE_ORIGIN);
// Linear non-branching interpolation of the strength of the sphere effect (replaces if/elseif/else for x < min, min <= x <= max and x > max)
float effectStrength = SPHERE_VALUEMIN + mix(0.0, SPHERE_VALUEMAX - SPHERE_VALUEMIN, (distance - SPHERE_DISTMIN) / (SPHERE_DISTMAX - SPHERE_DISTMIN));
if (distance < SPHERE_DISTMIN)
{
effectStrength = SPHERE_DISTEXTEND.x ? SPHERE_VALUEMIN : 0.0;
}
else if (distance > SPHERE_DISTMAX)
{
effectStrength = SPHERE_DISTEXTEND.y ? SPHERE_VALUEMAX : 0.0;
}
vec3 fragColor;
if (rlvEffectMode == 0) // Blend
{
fragColor = texture2DRect(diffuseRect, fragTC).rgb;
fragColor = mix(fragColor, SPHERE_PARAMS.rgb, effectStrength);
}
else if (rlvEffectMode == 1) // Blur (fixed)
{
fragColor = blur13(diffuseRect, fragTC, effectStrength * BLUR_DIRECTION);
}
else if (rlvEffectMode == 2) // Blur (variable)
{
fragColor = texture2DRect(diffuseRect, fragTC).rgb;
if (effectStrength > 0)
{
fragColor = blurVariable(diffuseRect, fragTC, SPHERE_PARAMS.x, BLUR_DIRECTION, effectStrength);
}
}
else if (rlvEffectMode == 3) // ChromaticAberration
{
fragColor = chromaticAberration(diffuseRect, fragTC, SPHERE_PARAMS.xy, SPHERE_PARAMS.zw, effectStrength);
}
else if (rlvEffectMode == 4) // Pixelate
{
effectStrength = sign(effectStrength);
float pixelWidth = max(1, floor(SPHERE_PARAMS.x * effectStrength)); float pixelHeight = max(1, floor(SPHERE_PARAMS.y * effectStrength));
fragTC = vec2(pixelWidth * floor(fragTC.x / pixelWidth), pixelHeight * floor(fragTC.y / pixelHeight));
fragColor = texture2DRect(diffuseRect, fragTC).rgb;
}
frag_color.rgb = fragColor;
frag_color.a = 0.0;
}

View File

@ -0,0 +1,33 @@
/**
*
* Copyright (c) 2018, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
ATTRIBUTE vec3 position;
uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
VARYING vec3 vary_position;
void main()
{
//transform vertex
vec4 pos = vec4(position.xyz, 1.0);
gl_Position = pos;
vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
vary_position = (vec4(1, 0, 0, 1.0)).xyz;
}

View File

@ -16,7 +16,7 @@
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS AS IS
* THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS
@ -673,13 +673,28 @@ bool cmd_line_chat(const std::string& revised_text, EChatType type, bool from_ge
std::string status;
if (i >> status)
{
// <FS:Zi> send appropriate enable/disable messages to nearby chat - FIRE-24160
bool aoWasEnabled = gSavedPerAccountSettings.getBOOL("UseAO");
if (status == "on")
{
gSavedPerAccountSettings.setBOOL("UseAO", TRUE);
// <FS:Zi> send appropriate enable/disable messages to nearby chat - FIRE-24160
if (!aoWasEnabled)
{
report_to_nearby_chat(LLTrans::getString("FSAOEnabled"));
}
}
else if (status == "off")
{
gSavedPerAccountSettings.setBOOL("UseAO", FALSE);
// <FS:Zi> send appropriate enable/disable messages to nearby chat - FIRE-24160
if (aoWasEnabled)
{
report_to_nearby_chat(LLTrans::getString("FSAODisabled"));
}
}
else if (status == "sit")
{

View File

@ -7,7 +7,7 @@
//
// Bridge platform
string BRIDGE_VERSION = "2.25"; // This should match fslslbridge.cpp
string BRIDGE_VERSION = "2.27"; // This should match fslslbridge.cpp
string gLatestURL;
integer gViewerIsFirestorm;
integer gTryHandshakeOnce = TRUE;
@ -85,8 +85,11 @@
{
if (gAO_EnabledOC)
{
aoListenOC(NULL_KEY, TRUE);
llWhisper(gAO_ChannelOC, "OpenCollar?");
if (gAO_ChannelOC != PUBLIC_CHANNEL)
{
aoListenOC(NULL_KEY, TRUE);
llWhisper(gAO_ChannelOC, "OpenCollar?");
}
}
else
{
@ -456,7 +459,10 @@ default
{
gUseMoveLock = llList2Integer(commandList, 1);
movelockMe(gUseMoveLock);
llOwnerSay("<bridgeMovelock state=" + (string)gUseMoveLock + ">");
if (llList2String(commandList, 2) != "noreport")
{
llOwnerSay("<bridgeMovelock state=" + (string)gUseMoveLock + ">");
}
}
else if (cmd == "llMoveToTarget")

View File

@ -34,6 +34,8 @@
#include "llavataractions.h"
#include "llavatarnamecache.h"
#include "llfloaterperms.h"
#include "llgroupactions.h"
#include "llgroupmgr.h"
#include "llinventorymodel.h"
#include "lllogchat.h"
#include "llmutelist.h"
@ -316,6 +318,16 @@ bool FSCommon::isLinden(const LLUUID& av_id)
last_name == LL_TESTER);
}
// request group data from the server if it's not already cached
bool FSCommon::requestGroupData(const LLUUID& groupID)
{
if (LLGroupMgr::getInstance()->getGroupData(groupID) == nullptr)
{
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(groupID);
return false;
}
return true;
}
bool FSCommon::checkIsActionEnabled(const LLUUID& av_id, EFSRegistrarFunctionActionType action)
{
@ -373,6 +385,52 @@ bool FSCommon::checkIsActionEnabled(const LLUUID& av_id, EFSRegistrarFunctionAct
{
return !isSelf;
}
else if (action == FS_RGSTR_CHK_WAITING_FOR_GROUP_DATA)
{
return !requestGroupData(av_id);
}
else if (action == FS_RGSTR_CHK_HAVE_GROUP_DATA)
{
return requestGroupData(av_id);
}
else if (action == FS_RGSTR_CHK_CAN_LEAVE_GROUP)
{
if (gAgent.getGroupID() == av_id && !RlvActions::canChangeActiveGroup())
{
return false;
}
return gAgent.isInGroup(av_id);
}
else if (action == FS_RGSTR_CHK_CAN_JOIN_GROUP)
{
if (!gAgent.canJoinGroups())
{
return false;
}
if (!RlvActions::canChangeActiveGroup())
{
return false;
}
LLGroupMgrGroupData* groupData = LLGroupMgr::getInstance()->getGroupData(av_id);
if (!groupData || !groupData->mOpenEnrollment)
{
return false;
}
return !gAgent.isInGroup(av_id);
}
else if (action == FS_RGSTR_CHK_GROUP_NOT_ACTIVE)
{
if (!RlvActions::canChangeActiveGroup())
{
return false;
}
return (gAgent.isInGroup(av_id) && gAgent.getGroupID() != av_id);
}
return false;
}

View File

@ -78,6 +78,9 @@ namespace FSCommon
*/
extern S32 sObjectAddMsg;
// request group data from the server if it's not already cached
bool requestGroupData(const LLUUID& groupID);
bool checkIsActionEnabled(const LLUUID& av_id, EFSRegistrarFunctionActionType);
LLSD populateGroupCount();

View File

@ -32,6 +32,8 @@
#include "fscommon.h"
#include "fsscrolllistctrl.h"
#include "llagent.h"
#include "llaudioengine.h"
#include "llfiltereditor.h"
#include "llfloaterreg.h"
#include "llviewercontrol.h"
@ -39,10 +41,11 @@
FSFloaterAssetBlacklist::FSFloaterAssetBlacklist(const LLSD& key)
: LLFloater(key),
: LLFloater(key), LLEventTimer(0.25f),
mResultList(NULL),
mFilterSubString(LLStringUtil::null),
mFilterSubStringOrig(LLStringUtil::null),
mAudioSourceID(LLUUID::null),
mBlacklistCallbackConnection()
{
}
@ -60,15 +63,24 @@ BOOL FSFloaterAssetBlacklist::postBuild()
mResultList = getChild<FSScrollListCtrl>("result_list");
mResultList->setContextMenu(&FSFloaterAssetBlacklistMenu::gFSAssetBlacklistMenu);
mResultList->setFilterColumn(0);
mResultList->setCommitCallback(boost::bind(&FSFloaterAssetBlacklist::onSelectionChanged, this));
mResultList->setCommitOnSelectionChange(true);
childSetAction("remove_btn", boost::bind(&FSFloaterAssetBlacklist::onRemoveBtn, this));
childSetAction("remove_temp_btn", boost::bind(&FSFloaterAssetBlacklist::onRemoveAllTemporaryBtn, this));
childSetAction("play_btn", boost::bind(&FSFloaterAssetBlacklist::onPlayBtn, this));
childSetAction("stop_btn", boost::bind(&FSFloaterAssetBlacklist::onStopBtn, this));
childSetAction("close_btn", boost::bind(&FSFloaterAssetBlacklist::onCloseBtn, this));
getChild<LLFilterEditor>("filter_input")->setCommitCallback(boost::bind(&FSFloaterAssetBlacklist::onFilterEdit, this, _2));
mBlacklistCallbackConnection = FSAssetBlacklist::getInstance()->setBlacklistChangedCallback(boost::bind(&FSFloaterAssetBlacklist::onBlacklistChanged, this, _1, _2));
childSetEnabled("play_btn", false);
childSetEnabled("stop_btn", true);
childSetVisible("play_btn", true);
childSetVisible("stop_btn", false);
return TRUE;
}
@ -82,13 +94,13 @@ std::string FSFloaterAssetBlacklist::getTypeString(S32 type)
{
switch (type)
{
case 0:
case LLAssetType::AT_TEXTURE:
return getString("asset_texture");
case 1:
case LLAssetType::AT_SOUND:
return getString("asset_sound");
case 6:
case LLAssetType::AT_OBJECT:
return getString("asset_object");
case 45:
case LLAssetType::AT_PERSON:
return getString("asset_resident");
default:
return getString("asset_unknown");
@ -144,6 +156,9 @@ void FSFloaterAssetBlacklist::addElementToList(const LLUUID& id, const LLSD& dat
element["columns"][5]["column"] = "date_sort";
element["columns"][5]["type"] = "text";
element["columns"][5]["value"] = llformat("%u", (U64)date.secondsSinceEpoch());
element["columns"][6]["column"] = "asset_type";
element["columns"][6]["type"] = "integer";
element["columns"][6]["value"] = data["asset_type"].asInteger();
mResultList->addElement(element, ADD_BOTTOM);
}
@ -198,6 +213,57 @@ void FSFloaterAssetBlacklist::onRemoveAllTemporaryBtn()
gObjectList.resetDerenderList(true);
}
void FSFloaterAssetBlacklist::onSelectionChanged()
{
bool enabled = false;
size_t num_selected = mResultList->getAllSelected().size();
if (num_selected == 1)
{
const LLScrollListItem* item = mResultList->getFirstSelected();
S32 name_column = mResultList->getColumn("asset_type")->mIndex;
if (item && item->getColumn(name_column)->getValue().asInteger() == LLAssetType::AT_SOUND)
{
enabled = true;
}
}
childSetEnabled("play_btn", enabled);
}
void FSFloaterAssetBlacklist::onPlayBtn()
{
const LLScrollListItem* item = mResultList->getFirstSelected();
S32 name_column = mResultList->getColumn("asset_type")->mIndex;
if (!item || item->getUUID().isNull() || item->getColumn(name_column)->getValue().asInteger() != LLAssetType::AT_SOUND)
{
return;
}
onStopBtn();
mAudioSourceID = LLUUID::generateNewID();
gAudiop->triggerSound(item->getUUID(), gAgentID, 1.0f, LLAudioEngine::AUDIO_TYPE_UI, LLVector3d::zero, LLUUID::null, mAudioSourceID);
childSetVisible("stop_btn", true);
childSetVisible("play_btn", false);
}
void FSFloaterAssetBlacklist::onStopBtn()
{
if (mAudioSourceID.isNull())
{
return;
}
LLAudioSource* audio_source = gAudiop->findAudioSource(mAudioSourceID);
if (audio_source && !audio_source->isDone())
{
audio_source->play(LLUUID::null);
}
}
void FSFloaterAssetBlacklist::onCloseBtn()
{
closeFloater();
@ -220,6 +286,7 @@ void FSFloaterAssetBlacklist::onFilterEdit(const std::string& search_string)
// Apply new filter.
mResultList->setFilterString(mFilterSubStringOrig);
onSelectionChanged();
}
BOOL FSFloaterAssetBlacklist::handleKeyHere(KEY key, MASK mask)
@ -233,6 +300,32 @@ BOOL FSFloaterAssetBlacklist::handleKeyHere(KEY key, MASK mask)
return LLFloater::handleKeyHere(key, mask);
}
BOOL FSFloaterAssetBlacklist::tick()
{
if (mAudioSourceID.isNull())
{
return FALSE;
}
LLAudioSource* audio_source = gAudiop->findAudioSource(mAudioSourceID);
if (!audio_source || audio_source->isDone())
{
childSetVisible("play_btn", true);
childSetVisible("stop_btn", false);
mAudioSourceID.setNull();
onSelectionChanged();
}
return FALSE;
}
void FSFloaterAssetBlacklist::closeFloater(bool /* app_quitting */)
{
onStopBtn();
LLFloater::closeFloater();
}
//---------------------------------------------------------------------------
// Context menu
//---------------------------------------------------------------------------

View File

@ -35,7 +35,7 @@
class FSScrollListCtrl;
class FSFloaterAssetBlacklist : public LLFloater
class FSFloaterAssetBlacklist : public LLFloater, public LLEventTimer
{
LOG_CLASS(FSFloaterAssetBlacklist);
@ -47,6 +47,8 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ bool hasAccelerators() const { return true; }
/*virtual*/ BOOL tick();
/*virtual*/ void closeFloater(bool app_quitting = false);
void addElementToList(const LLUUID& id, const LLSD& data);
void removeElements();
@ -54,13 +56,18 @@ public:
protected:
void onRemoveBtn();
void onRemoveAllTemporaryBtn();
void onPlayBtn();
void onStopBtn();
void onCloseBtn();
void onFilterEdit(const std::string& search_string);
void onBlacklistChanged(const LLSD& data, FSAssetBlacklist::eBlacklistOperation op);
void onSelectionChanged();
void buildBlacklist();
std::string getTypeString(S32 type);
LLUUID mAudioSourceID;
private:
FSScrollListCtrl* mResultList;

View File

@ -37,6 +37,7 @@
#include "fsdata.h"
#include "fsfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
#include "fsfloaternearbychat.h"
#include "fsnearbychathub.h" // <FS:Zi> FIRE-24133 - Redirect chat channel messages
#include "fspanelimcontrolpanel.h"
#include "llagent.h"
#include "llappviewer.h"
@ -77,6 +78,8 @@
#include "rlvactions.h"
#include "rlvhandler.h"
#include <boost/regex.hpp> // <FS:Zi> FIRE-24133 - Redirect chat channel messages
const F32 ME_TYPING_TIMEOUT = 4.0f;
const F32 OTHER_TYPING_TIMEOUT = 9.0f;
const F32 NAME_REFRESH_TIMEOUT = 300.0f;
@ -381,7 +384,20 @@ void FSFloaterIM::sendMsgFromInputEditor(EChatType type)
// Truncate and convert to UTF8 for transport
std::string utf8_text = wstring_to_utf8str(text);
// <FS:Zi> FIRE-24133 - Redirect chat channel messages
if (boost::regex_match(utf8_text.c_str(), boost::regex("/-{0,1}[0-9].*")))
{
// message starts with a / and a valid channel number, so redirect it to a chat channel
FSNearbyChat::instance().sendChatFromViewer(text, CHAT_TYPE_NORMAL, false);
// clean out the text box and typing indicator, which we wouldn't reach otherwise
mInputEditor->setText(LLStringUtil::null);
setTyping(false);
return;
}
// Convert OOC and MU* style poses
utf8_text = FSCommon::applyAutoCloseOoc(utf8_text);
utf8_text = FSCommon::applyMuPose(utf8_text);

View File

@ -55,7 +55,7 @@
static const std::string FS_BRIDGE_FOLDER = "#LSL Bridge";
static const std::string FS_BRIDGE_CONTAINER_FOLDER = "Landscaping";
static const U32 FS_BRIDGE_MAJOR_VERSION = 2;
static const U32 FS_BRIDGE_MINOR_VERSION = 25;
static const U32 FS_BRIDGE_MINOR_VERSION = 27;
static const U32 FS_MAX_MINOR_VERSION = 99;
static const std::string UPLOAD_SCRIPT_CURRENT = "EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt";
static const std::string FS_STATE_ATTRIBUTE = "state=";
@ -316,18 +316,32 @@ bool FSLSLBridge::lslToViewer(const std::string& message, const LLUUID& fromID,
}
if (tag == "<clientAO ")
{
// <FS:Zi> do nothing when the FS AO is disabled
if (!gSavedPerAccountSettings.getBOOL("UseAO"))
{
return true;
}
status = true;
size_t valuepos = message.find(FS_STATE_ATTRIBUTE);
if (valuepos != std::string::npos)
{
// <FS:Zi> send appropriate enable/disable messages to nearby chat - FIRE-24160
// use BOOL to satisfy windows compiler
BOOL aoWasPaused = gSavedPerAccountSettings.getBOOL("PauseAO");
BOOL aoStandsWasEnabled = gSavedPerAccountSettings.getBOOL("UseAOStands");
// </FS:Zi>
if (message.substr(valuepos + FS_STATE_ATTRIBUTE.size(), 2) == "on")
{
gSavedPerAccountSettings.setBOOL("UseAO", TRUE);
// <FS:Zi> Pause AO via bridge instead of switch AO on or off - FIRE-9305
gSavedPerAccountSettings.setBOOL("PauseAO", FALSE);
gSavedPerAccountSettings.setBOOL("UseAOStands", TRUE);
}
else if (message.substr(valuepos + FS_STATE_ATTRIBUTE.size(), 3) == "off")
{
gSavedPerAccountSettings.setBOOL("UseAO", FALSE);
// <FS:Zi> Pause AO via bridge instead of switch AO on or off - FIRE-9305
gSavedPerAccountSettings.setBOOL("PauseAO", TRUE);
}
else if (message.substr(valuepos + FS_STATE_ATTRIBUTE.size(), 7) == "standon")
{
@ -341,6 +355,41 @@ bool FSLSLBridge::lslToViewer(const std::string& message, const LLUUID& fromID,
{
LL_WARNS("FSLSLBridge") << "AO control - Received unknown state" << LL_ENDL;
}
// <FS:Zi> send appropriate enable/disable messages to nearby chat - FIRE-24160
std::string aoMessage;
if (aoWasPaused != gSavedPerAccountSettings.getBOOL("PauseAO"))
{
if (aoWasPaused)
{
aoMessage = LLTrans::getString("FSAOResumedScript");
}
else
{
aoMessage = LLTrans::getString("FSAOPausedScript");
}
}
if (aoStandsWasEnabled != gSavedPerAccountSettings.getBOOL("UseAOStands"))
{
if (aoStandsWasEnabled)
{
aoMessage = LLTrans::getString("FSAOStandsPausedScript");
}
else
{
aoMessage = LLTrans::getString("FSAOStandsResumedScript");
}
}
if (!aoMessage.empty())
{
LLSD args;
args["AO_MESSAGE"] = aoMessage;
LLNotificationsUtil::add("FSAOScriptedNotification", args);
}
// </FS:Zi>
}
}
//</FS:TS> FIRE-962

View File

@ -1413,7 +1413,7 @@ void FSPanelLogin::updateServerCombo()
server_choice_combo->addSeparator(ADD_TOP);
LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL;
server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(current_grid),
current_grid,
ADD_TOP);
server_choice_combo->selectFirstItem();

View File

@ -31,6 +31,7 @@
#include "llavataractions.h"
#include "llcommandhandler.h"
#include "llfloatersettingsdebug.h"
#include "llgroupactions.h"
#include "lllogchat.h"
#include "llnotificationsutil.h"
@ -135,6 +136,24 @@ public:
return true;
}
if (verb == "groupjoin")
{
LLGroupActions::join(LLUUID(target_id));
return true;
}
if (verb == "groupleave")
{
LLGroupActions::leave(LLUUID(target_id));
return true;
}
if (verb == "groupactivate")
{
LLGroupActions::activate(LLUUID(target_id));
return true;
}
return false;
}
};

View File

@ -91,12 +91,12 @@ void LFSimFeatureHandler::setSupportedFeatures()
region->getSimulatorFeatures(info);
if (!LLGridManager::getInstance()->isInSecondLife() && info.has("OpenSimExtras")) // OpenSim specific sim features
{
LL_INFOS() << "Setting OpenSimExtras..." << LL_ENDL;
LL_INFOS("SimFeatures") << "Setting OpenSimExtras..." << LL_ENDL;
// For definition of OpenSimExtras please see
// http://opensimulator.org/wiki/SimulatorFeatures_Extras
const LLSD& extras(info["OpenSimExtras"]);
LL_DEBUGS() << "OpenSimExtras received: " << extras << LL_ENDL;
LL_DEBUGS("SimFeatures") << "OpenSimExtras received: " << extras << LL_ENDL;
mSupportsExport = extras.has("ExportSupported") ? extras["ExportSupported"].asBoolean() : false;
mMapServerURL = extras.has("map-server-url") ? extras["map-server-url"].asString() : gSavedSettings.getString("CurrentMapServerURL");
@ -115,7 +115,7 @@ void LFSimFeatureHandler::setSupportedFeatures()
// Note: we do not attempt to clear trailing port numbers or / or even directories.
mHyperGridPrefix = mHyperGridPrefix.substr(pos+3,mHyperGridPrefix.size()-(pos+3));
}
LL_DEBUGS() << "Setting HyperGrid URL to \"GridURL\" [" << mHyperGridPrefix << "]" << LL_ENDL;
LL_DEBUGS("SimFeatures") << "Setting HyperGrid URL to \"GridURL\" [" << mHyperGridPrefix << "]" << LL_ENDL;
}
#ifdef OPENSIM
else if (LLGridManager::instance().getGatekeeper() != std::string{})
@ -124,14 +124,14 @@ void LFSimFeatureHandler::setSupportedFeatures()
// worst case this is checking the login grid and will simply be the same as the fallback
// If the GridURL is not available then we will try to use the Gatekeeper which is expected to be present.
mHyperGridPrefix = LLGridManager::instance().getGatekeeper();
LL_DEBUGS() << "Setting HyperGrid URL to \"Gatekeeper\" [" << mHyperGridPrefix << "]" << LL_ENDL;
LL_DEBUGS("SimFeatures") << "Setting HyperGrid URL to \"Gatekeeper\" [" << mHyperGridPrefix << "]" << LL_ENDL;
}
#endif
else
{
// Just in case that fails we will default back to the current grid
mHyperGridPrefix = LLGridManager::instance().getGridId();
LL_DEBUGS() << "Setting HyperGrid URL to fallback of current grid (target grid is misconfigured) [" << mHyperGridPrefix << "]" << LL_ENDL;
mHyperGridPrefix = LLGridManager::instance().getGrid();
LL_DEBUGS("SimFeatures") << "Setting HyperGrid URL to fallback of current grid (target grid is misconfigured) [" << mHyperGridPrefix << "]" << LL_ENDL;
}
if (extras.has("SimulatorFPS") && extras.has("SimulatorFPSFactor") &&

View File

@ -345,6 +345,14 @@ bool LLAgent::isActionAllowed(const LLSD& sdname)
retval = false;
}
}
else if (param == "fs_when_not_sitting")
{
if (!gAgentAvatarp)
{
return false;
}
return !gAgentAvatarp->isSitting();
}
return retval;
}

View File

@ -679,7 +679,10 @@ static void settings_to_globals()
static void settings_modify()
{
LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
// LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
// [RLVa:KB] - @setsphere
LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred") || (gSavedSettings.getBOOL("WindLightUseAtmosShaders") && LLPipeline::sUseDepthTexture);
// [/RLVa:KB]
LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
LLPipeline::sRenderDeferred = LLPipeline::sRenderTransparentWater && LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");

View File

@ -670,9 +670,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
U32 have_mask = params.mVertexBuffer->getTypeMask() & mask;
if (have_mask != mask)
{ //FIXME!
LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask
<< " present: " << have_mask
<< ". Skipping render batch." << LL_ENDL;
// <FS:Beq> Remove useless logging info from critical path (can be called many times per frame)
// TODO(Beq) Determine whether this can be intercepted earlier
// LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask
// << " present: " << have_mask
// << ". Skipping render batch." << LL_ENDL;
// </FS:Beq>
continue;
}

View File

@ -207,7 +207,7 @@ private:
void LLFloaterIMNearbyChatScreenChannel::reshapePanel(LLFloaterIMNearbyChatToastPanel* panel)
{
S32 percentage = gSavedSettings.getS32("NearbyToastWidth");
panel->reshape(gViewerWindow->getWindowWidthRaw() * percentage / 100, panel->getRect().getHeight(), TRUE);
panel->reshape(gViewerWindow->getWindowWidthScaled() * percentage / 100, panel->getRect().getHeight(), TRUE);
}
void LLFloaterIMNearbyChatScreenChannel::updateSize(LLRect old_world_rect, LLRect new_world_rect)

View File

@ -48,7 +48,9 @@
#include "llviewerobject.h"
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
// [RLVa:KB] - @edit
#include "rlvactions.h"
// [/RLVa:KB]
LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key)
: LLFloater(key),
@ -105,6 +107,16 @@ void LLFloaterOpenObject::refresh()
BOOL enabled = FALSE;
LLSelectNode* node = mObjectSelection->getFirstRootNode();
// [RLVa:KB] - @edit and @editobj
if ( (RlvActions::isRlvEnabled()) && (node) && (!RlvActions::canEdit(node->getObject())) )
{
// If the floater was already open before getting edit restricted then a transient selection will allow manipulation
// of the object's inventory without it getting selected by LLSelectMgr::deselectIfTooFar().
// Killing the selection would result in the user not realizing why their right-click breaks so close the floater instead.
closeFloater();
return;
}
// [/RLVa:KB]
if (node)
{
name = node->mName;

View File

@ -2275,7 +2275,7 @@ void LLFloaterPreference::refreshEnabledState()
// [RLVa:KB] - Checked: 2010-03-18 (RLVa-1.2.0a) | Modified: RLVa-0.2.0a
// "Atmospheric Shaders" can't be disabled - but can be enabled - under @setenv=n
ctrl_wind_light->setEnabled( (RlvActions::canChangeEnvironment()) || (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")));
ctrl_wind_light->setEnabled( ((RlvActions::canChangeEnvironment()) && (!RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE))) || (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")));
// [/RLVa:KB]
// ctrl_wind_light->setEnabled(TRUE);
@ -5972,7 +5972,10 @@ void LLPanelPreferenceOpensim::onClickRefreshGrid()
std::string grid = mGridListControl->getSelectedValue();
getChild<LLUICtrl>("grid_management_panel")->setEnabled(FALSE);
LLGridManager::getInstance()->addGridListChangedCallback(boost::bind(&LLPanelPreferenceOpensim::refreshGridList, this, _1));
LLGridManager::getInstance()->reFetchGrid(grid);
// <FS:Beq> FIRE-13223 grid info refresh does not update properly when applied to currently active grid
// LLGridManager::getInstance()->reFetchGrid(grid);
LLGridManager::getInstance()->reFetchGrid(grid, (grid == LLGridManager::getInstance()->getGrid()) );
// </FS:Beq>
}
void LLPanelPreferenceOpensim::onClickRemoveGrid()

View File

@ -3177,6 +3177,14 @@ void LLIMMgr::addMessage(
LL_WARNS() << "Failed to create IM session " << fixed_session_name << LL_ENDL;
}
}
// <FS:Zi> FIRE-30424 - Incoming Group message sound plays for muted posters
else if(LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !from_linden)
{
// if this message was from a muted resident, there is no point in playing any sounds or
// doing anything else in this function, so return right here
return;
}
// </FS:Zi>
else if(!do_not_disturb && PlayModeUISndNewIncomingIMSession == 2 && dialog == IM_NOTHING_SPECIAL)
{
make_ui_sound("UISndNewIncomingIMSession");

View File

@ -258,7 +258,11 @@ std::string LLInvFVBridge::getSearchableCreatorName() const
if(item)
{
LLAvatarName av_name;
if (LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
// <FS:Beq> Avoid null id requests entering name cache
// if (LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
const auto& creatorId {item->getCreatorUUID()};
if ( creatorId.notNull() && LLAvatarNameCache::get(creatorId, &av_name) )
// </FS:Beq>
{
std::string username = av_name.getUserName();
LLStringUtil::toUpper(username);
@ -7813,7 +7817,9 @@ void LLSettingsBridge::performAction(LLInventoryModel* model, std::string action
if (!item)
return;
LLUUID asset_id = item->getAssetUUID();
LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id);
// FIRE-30701 - Allow crossfade time to apply when using EEP from inventory.
// LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id);
LLEnvironment::instance().setManualEnvironment(LLEnvironment::ENV_LOCAL, asset_id);
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
}
else if ("apply_settings_parcel" == action)

View File

@ -706,7 +706,10 @@ bool get_is_item_editable(const LLUUID& inv_item_id)
case LLAssetType::AT_CLOTHING:
return gAgentWearables.isWearableModifiable(inv_item_id);
case LLAssetType::AT_OBJECT:
return true;
// [RLVa:KB] - @touch*
return (!RlvActions::isRlvEnabled()) || ((isAgentAvatarValid()) && (RlvActions::canEdit(gAgentAvatarp->getWornAttachment(inv_item_id))));
// [/RLVa:KB]
// return true;
default:
return false;;
}

View File

@ -106,12 +106,14 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
mWaitList.insert(asset_uuid);
return NULL;
}
// <FS:Beq/> fIRE-14457 Fix CopySLURL fails / landmakrs not loading - based on snippet from Chorazin Allen
mRequestedList[asset_uuid] = gFrameTimeSeconds;
gAssetStorage->getAssetData(asset_uuid,
LLAssetType::AT_LANDMARK,
LLLandmarkList::processGetAssetReply,
NULL);
mRequestedList[asset_uuid] = gFrameTimeSeconds;
// <FS:Beq/> fIRE-14457 Fix CopySLURL fails / landmakrs not loading - based on snippet from Chorazin Allen
// mRequestedList[asset_uuid] = gFrameTimeSeconds;
}
return NULL;
}

View File

@ -324,7 +324,10 @@ std::string LLHandlerUtil::getSubstitutionName(const LLNotificationPtr& notifica
from_id = notification->getPayload()["from_id"];
}
LLAvatarName av_name;
if(LLAvatarNameCache::get(from_id, &av_name))
// <FS:Beq> Avoid null UUID name cache requests
// if(LLAvatarNameCache::get(from_id, &av_name))
if( from_id.notNull() && LLAvatarNameCache::get(from_id, &av_name) )
// </FS:Beq>
{
res = av_name.getUserName();
}

View File

@ -37,6 +37,10 @@
#include "llscriptfloater.h"
#include "llavatarname.h"
#include "llavatarnamecache.h"
// [RLVa:KB] - @sendchat and @sendchannel/sendchannelexcept
#include "rlvactions.h"
#include "rlvcommon.h"
// [/RLVa:KB]
using namespace LLNotificationsUI;
@ -112,6 +116,24 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
if(notification->hasFormElements() && !notification->canShowToast())
{
// [RLVa:KB] - @sendchat and @sendchannel/sendchannelexcept
if (RlvActions::isRlvEnabled())
{
const LLSD& sdPayload = notification->getPayload();
if (sdPayload.has("chat_channel"))
{
const S32 nChannel = sdPayload["chat_channel"].asInteger();
// *TODO-RLVa: it's too late into the release cycle to block all script interactions so just take care of the nearby chat loophole for now
bool fBlock = (0 == nChannel) ? RlvActions::hasBehaviour(RLV_BHVR_SENDCHAT) : /*!RlvActions::canSendChannel(nChannel)*/false;
if (fBlock)
{
RlvUtil::notifyBlocked("blocked_scriptdialog");
return false;
}
}
}
// [/RLVa:KB]
LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
}
else if (notification->canShowToast())

View File

@ -709,12 +709,42 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const
if (cat)
{
// <FS:Ansariel> Make object root folder name localizable again
// <FS:Zi> FIRE-24142 - Show number of elements in object inventory
//mDisplayName.assign(cat->getName());
if (cat->getParentUUID().isNull() && cat->getName() == "Contents")
{
mDisplayName.assign(LLTrans::getString("Contents"));
LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
if (object)
{
LLInventoryObject::object_list_t contents;
object->getInventoryContents(contents);
S32 numElements = contents.size();
std::string elementsString = "FSObjectInventoryNoElements";
if (numElements == 1)
{
elementsString = "FSObjectInventoryOneElement";
}
else
{
elementsString = "FSObjectInventoryElements";
}
LLSD args;
args["NUM_ELEMENTS"] = numElements;
mDisplayName.assign(llformat("%s (%s)",
LLTrans::getString("Contents").c_str(),
LLTrans::getString(elementsString, args).c_str()));
}
// fallback in case something goes wrong with finding the inventory object
else
{
// <FS:Ansariel> Make object root folder name localizable again
mDisplayName.assign(LLTrans::getString("Contents"));
}
}
// </FS:Zi>
else
{
mDisplayName.assign(cat->getName());

View File

@ -173,11 +173,11 @@ protected:
}
// Enable/disable some menu items depending on the selection.
bool show_touch = !bp_selected && !clothes_selected && attachments_selected;
bool show_edit = bp_selected || clothes_selected || attachments_selected;
// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7)
bool rlv_blocked = (mUUIDs.size() == rlv_locked_count);
// [/RLVa:KB]
bool show_touch = !bp_selected && !clothes_selected && attachments_selected;
bool show_edit = bp_selected || clothes_selected || attachments_selected;
bool allow_detach = !bp_selected && !clothes_selected && attachments_selected;
bool allow_take_off = !bp_selected && clothes_selected && !attachments_selected;
@ -187,7 +187,7 @@ protected:
menu->setItemEnabled("edit_item", 1 == mUUIDs.size() && get_is_item_editable(mUUIDs.front()));
menu->setItemVisible("take_off", allow_take_off);
menu->setItemVisible("detach", allow_detach);
menu->setItemVisible("edit_outfit_separator", show_touch | show_edit | allow_take_off || allow_detach);
menu->setItemVisible("edit_outfit_separator", show_touch || show_edit || allow_take_off || allow_detach);
menu->setItemVisible("show_original", mUUIDs.size() == 1);
// [SL:KB] - Patch: Inventory-AttachmentEdit - Checked: 2010-09-04 (Catznip-2.2.0a) | Added: Catznip-2.1.2a
menu->setItemVisible("take_off_or_detach", (!allow_detach) && (!allow_take_off) && (clothes_selected) && (attachments_selected));

View File

@ -1023,9 +1023,13 @@ void LLPreviewTexture::onAspectRatioCommit(LLUICtrl* ctrl, void* userdata)
void LLPreviewTexture::loadAsset()
{
mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
mImageOldBoostLevel = mImage->getBoostLevel();
mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
// <FS:Beq> FIRE-30559 texture fetch speedup for user previews (based on patches from Oren Hurvitz)
// mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
// mImageOldBoostLevel = mImage->getBoostLevel();
// mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_PREVIEW, LLViewerTexture::LOD_TEXTURE);
mImageOldBoostLevel = LLGLTexture::BOOST_NONE;
// </FS:Beq>
mImage->forceToSaveRawImage(0) ;
// <FS:Techwolf Lupindo> texture comment decoder
mImage->setLoadedCallback(LLPreviewTexture::onTextureLoaded, 0, TRUE, FALSE, this, &mCallbackTextureList);

View File

@ -519,9 +519,49 @@ BOOL LLStatusBar::postBuild()
updateVolumeControlsVisibility(LLSD(FALSE));
}
// </FS:PP>
// <FS:Zi> FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display
mClockFormatChoices["12 Hour"] = "[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt]";
mClockFormatChoices["12 Hour Seconds"] = "[hour12, datetime, slt]:[min, datetime, slt]:[second, datetime, slt] [ampm, datetime, slt]";
mClockFormatChoices["12 Hour TZ"] = "[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]";
mClockFormatChoices["12 Hour TZ Seconds"] = "[hour12, datetime, slt]:[min, datetime, slt]:[second, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]";
mClockFormatChoices["24 Hour"] = "[hour24, datetime, slt]:[min, datetime, slt]";
mClockFormatChoices["24 Hour Seconds"] = "[hour24, datetime, slt]:[min, datetime, slt]:[second, datetime, slt]";
mClockFormatChoices["24 Hour TZ"] = "[hour24, datetime, slt]:[min, datetime, slt] [timezone, datetime, slt]";
mClockFormatChoices["24 Hour TZ Seconds"] = "[hour24, datetime, slt]:[min, datetime, slt]:[second, datetime, slt] [timezone, datetime, slt]";
// use the time format defined in the language's panel_status_bar.xml (default)
mClockFormatChoices["Language"] = getString("time");
mClockFormat = gSavedSettings.getString("FSStatusBarTimeFormat");
// </FS:Zi>
return TRUE;
}
// <FS:Zi> FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display
void LLStatusBar::updateClockDisplay()
{
// Get current UTC time, adjusted for the user's clock
// being off.
time_t utc_time;
utc_time = time_corrected();
std::string timeStr = mClockFormatChoices[mClockFormat];
LLSD substitution;
substitution["datetime"] = (S32) utc_time;
LLStringUtil::format (timeStr, substitution);
mTextTime->setText(timeStr);
// <FS:Ansariel> Add seconds to clock
static const std::string tooltip_template = getString("timeTooltip");
std::string dtStr = tooltip_template;
// </FS:Ansariel>
LLStringUtil::format (dtStr, substitution);
mTextTime->setToolTip (dtStr);
}
// </FS:Zi>
// Per-frame updates of visibility
void LLStatusBar::refresh()
{
@ -562,29 +602,25 @@ void LLStatusBar::refresh()
{
mClockUpdateTimer.reset();
// Get current UTC time, adjusted for the user's clock
// being off.
time_t utc_time;
utc_time = time_corrected();
// <FS:Zi> FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display
// // Get current UTC time, adjusted for the user's clock
// // being off.
// time_t utc_time;
// utc_time = time_corrected();
// <FS:Ansariel> Add seconds to clock
//std::string timeStr = getString("time");
static const std::string time_template = getString("time");
std::string timeStr = time_template;
// </FS:Ansariel>
LLSD substitution;
substitution["datetime"] = (S32) utc_time;
LLStringUtil::format (timeStr, substitution);
mTextTime->setText(timeStr);
// std::string timeStr = getString("time");
// LLSD substitution;
// substitution["datetime"] = (S32) utc_time;
// LLStringUtil::format (timeStr, substitution);
// mTextTime->setText(timeStr);
// set the tooltip to have the date
// <FS:Ansariel> Add seconds to clock
//std::string dtStr = getString("timeTooltip");
static const std::string tooltip_template = getString("timeTooltip");
std::string dtStr = tooltip_template;
// </FS:Ansariel>
LLStringUtil::format (dtStr, substitution);
mTextTime->setToolTip (dtStr);
// // set the tooltip to have the date
// std::string dtStr = getString("timeTooltip");
// LLStringUtil::format (dtStr, substitution);
// mTextTime->setToolTip (dtStr);
updateClockDisplay();
// </FS:Zi>
}
// <FS:Zi> Pathfinding rebake functions
@ -1717,6 +1753,14 @@ void LLStatusBar::onPopupRolloverChanged(const LLSD& newvalue)
}
}
// <FS:Zi> FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display
void LLStatusBar::onTimeFormatChanged(const std::string& format)
{
mClockFormat = format;
updateClockDisplay();
}
// </FS:Zi>
// Implements secondlife:///app/balance/request to request a L$ balance
// update via UDP message system. JC
class LLBalanceHandler : public LLCommandHandler

View File

@ -157,6 +157,9 @@ public:
void updateCurrencySymbols();
// </COLOSI opensim multi-currency support>
// <FS:Zi> FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display
void onTimeFormatChanged(const std::string& format);
private:
void onClickBuyCurrency();
@ -166,7 +169,8 @@ private:
void onMouseEnterPresets();
void onMouseEnterVolume();
void onMouseEnterNearbyMedia();
void onClickScreen(S32 x, S32 y);
// <FS:Ansariel> Does not exist 15-02-2021
//void onClickScreen(S32 x, S32 y);
static void onClickStreamToggle(void* data); // <FS:Zi> Media/Stream separation
static void onClickMediaToggle(void* data);
@ -259,16 +263,11 @@ private:
/**
* Updates the visibility state of the parcel icons according to parcel properties
*/
void updateParcelIconVisibility();
// <FS:Ansariel> Does not exist 15-02-2021
//void updateParcelIconVisibility();
void onBuyLandClicked();
// <FS:Ansariel> Pathfinding support
void onRegionBoundaryCrossed();
void onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus);
void createNavMeshStatusListenerForCurrentRegion();
// </FS:Ansariel> Pathfinding support
// <FS:Ansariel> FIRE-19697: Add setting to disable graphics preset menu popup on mouse over
void onPopupRolloverChanged(const LLSD& newvalue);
@ -395,6 +394,13 @@ private:
void onMouseLeaveParcelInfo();
// </FS:Zi>
// <FS:Zi> FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display
std::map<std::string, std::string> mClockFormatChoices;
std::string mClockFormat;
void updateClockDisplay();
// </FS:Zi>
std::string mCurrentLocationString;
};

View File

@ -517,9 +517,21 @@ static bool handleRenderLocalLightsChanged(const LLSD& newvalue)
return true;
}
// [RLVa:KB] - @setsphere
static bool handleWindLightAtmosShadersChanged(const LLSD& newvalue)
{
LLRenderTarget::sUseFBO = newvalue.asBoolean() && LLPipeline::sUseDepthTexture;
handleSetShaderChanged(LLSD());
return true;
}
// [/RLVa:KB]
static bool handleRenderDeferredChanged(const LLSD& newvalue)
{
LLRenderTarget::sUseFBO = newvalue.asBoolean();
// LLRenderTarget::sUseFBO = newvalue.asBoolean();
// [RLVa:KB] - @setsphere
LLRenderTarget::sUseFBO = newvalue.asBoolean() || (gSavedSettings.getBOOL("WindLightUseAtmosShaders") && LLPipeline::sUseDepthTexture);
// [/RLVa:KB]
if (gPipeline.isInit())
{
LLPipeline::refreshCachedSettings();
@ -541,7 +553,10 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue)
//
static bool handleRenderBumpChanged(const LLSD& newval)
{
LLRenderTarget::sUseFBO = newval.asBoolean();
// LLRenderTarget::sUseFBO = newval.asBoolean();
// [RLVa:KB] - @setsphere
LLRenderTarget::sUseFBO = newval.asBoolean() || (gSavedSettings.getBOOL("WindLightUseAtmosShaders") && LLPipeline::sUseDepthTexture);
// [/RLVa:KB]
if (gPipeline.isInit())
{
gPipeline.updateRenderBump();
@ -1033,6 +1048,17 @@ void handleSmallCameraFloaterChanged(const LLSD& newValue)
}
// </FS:Ansariel>
// <FS:Zi> FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display
void handleStatusbarTimeformatChanged(const LLSD& newValue)
{
const std::string format = newValue.asString();
if (gStatusBar)
{
gStatusBar->onTimeFormatChanged(format);
}
}
// </FS:Zi>
////////////////////////////////////////////////////////////////////////////
void settings_setup_listeners()
@ -1060,7 +1086,10 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
// gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
// [RLVa:KB] - @setsphere
gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleWindLightAtmosShadersChanged, _2));
// [/RLVa:KB]
gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
@ -1280,6 +1309,9 @@ void settings_setup_listeners()
// <FS:Ansariel> Optional small camera floater
gSavedSettings.getControl("FSUseSmallCameraFloater")->getSignal()->connect(boost::bind(&handleSmallCameraFloaterChanged, _2));
// <FS:Zi> FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display
gSavedSettings.getControl("FSStatusBarTimeFormat")->getSignal()->connect(boost::bind(&handleStatusbarTimeformatChanged, _2));
}
#if TEST_CACHED_CONTROL

View File

@ -79,7 +79,8 @@
#include "llenvironment.h"
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "llvisualeffect.h"
#include "rlvactions.h"
#include "rlvlocks.h"
// [/RLVa:KB]
#include "llpresetsmanager.h"
@ -1429,9 +1430,9 @@ void render_ui(F32 zoom_factor, int subfield)
LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
render_hud_elements();
// [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay)
if (gRlvHandler.isEnabled())
if (RlvActions::hasBehaviour(RLV_BHVR_SETOVERLAY))
{
gRlvHandler.renderOverlay();
LLVfxManager::instance().runEffect(EVisualEffect::RlvOverlay);
}
// [/RLVa:KB]
render_hud_attachments();

View File

@ -1361,11 +1361,11 @@ class LLAdvancedToggleWireframe : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
// [RLVa:KB] - Checked: RLVa-2.0.0
bool fRlvBlockWireframe = gRlvAttachmentLocks.hasLockedHUD();
if ( (!gUseWireframe) && (fRlvBlockWireframe) )
// [RLVa:KB] - @detach and @viewwireframe
const bool fRlvCanViewWireframe = RlvActions::canViewWireframe();
if ( (!gUseWireframe) && (!fRlvCanViewWireframe) )
RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Wireframe);
set_use_wireframe( (!gUseWireframe) && (!fRlvBlockWireframe) );
set_use_wireframe( (!gUseWireframe) && (fRlvCanViewWireframe) );
return true;
}
};
@ -3500,10 +3500,10 @@ bool enable_attachment_touch(const LLUUID& inv_item_id)
if (isAgentAvatarValid())
{
const LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id));
return (attach_obj) && (attach_obj->flagHandleTouch()) && ( (!RlvActions::isRlvEnabled()) || (RlvActions::canTouch(gAgentAvatarp->getWornAttachment(inv_item_id))) );
// [RLVa:KB] - Checked: 2012-08-15 (RLVa-1.4.7)
//return (attach_obj) && (attach_obj->flagHandleTouch());
// [RLVa:KB] - @touch*
return (attach_obj) && (attach_obj->flagHandleTouch()) && (!RlvActions::isRlvEnabled() || RlvActions::canTouch(attach_obj));
// [/RLVa:KB]
// return (attach_obj) && (attach_obj->flagHandleTouch());
}
return false;
}
@ -10523,8 +10523,8 @@ class LLViewHighlightTransparent : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
// LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha;
// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c
LLDrawPoolAlpha::sShowDebugAlpha = (!LLDrawPoolAlpha::sShowDebugAlpha) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT));
// [RLVa:KB] - @edit and @viewtransparent
LLDrawPoolAlpha::sShowDebugAlpha = (!LLDrawPoolAlpha::sShowDebugAlpha) && (RlvActions::canHighlightTransparent());
// [/RLVa:KB]
return true;
}

View File

@ -8179,6 +8179,20 @@ bool callback_script_dialog(const LLSD& notification, const LLSD& response)
}
}
// [RLVa:KB] - @sendchat and @sendchannel/sendchannelexcept
if ( (RlvActions::isRlvEnabled()) && (0 <= button_idx) )
{
const S32 nChannel = notification["payload"]["chat_channel"].asInteger();
// *TODO-RLVa: it's too late into the release cycle to block all script interactions so just take care of the nearby chat loophole for now
bool fBlock = (0 == nChannel) ? RlvActions::hasBehaviour(RLV_BHVR_SENDCHAT) : /*!RlvActions::canSendChannel(nChannel)*/false;
if (fBlock)
{
button_idx = -1;
}
}
// [/RLVa:KB]
if (0 <= button_idx)
{
LLMessageSystem* msg = gMessageSystem;

View File

@ -83,6 +83,7 @@
#include <algorithm>
#include <iterator>
#include <tuple> // <FS:Beq/> FIRE-30694 DeadObject Spamming cleanup
#include "fsassetblacklist.h"
#include "fsfloaterimport.h"
#include "fscommon.h"
@ -1410,15 +1411,30 @@ void LLViewerObjectList::clearDebugText()
void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
{
bool new_dead_object = true;
// <FS:Beq> FIRE-30694 DeadObject Spam - handle new_dead_object properly and closer to source
// bool new_dead_object = true;
if (mDeadObjects.find(objectp->mID) != mDeadObjects.end())
{
LL_INFOS() << "Object " << objectp->mID << " already on dead list!" << LL_ENDL;
new_dead_object = false;
// <FS:Beq> FIRE-30694 DeadObject Spam
// new_dead_object = false;
}
else
{
mDeadObjects.insert(objectp->mID);
// <FS:Beq> FIRE-30694 DeadObject Spam
// mDeadObjects.insert(objectp->mID);
bool success;
std::tie( std::ignore, success ) = mDeadObjects.insert( objectp->mID );
if( success )
{
mNumDeadObjects++;
llassert( mNumDeadObjects == mDeadObjects.size() );
}
else
{
LL_WARNS() << "Object " << objectp->mID << " failed to insert on dead list!" << LL_ENDL;
}
// </FS:Beq>
}
// Cleanup any references we have to this object
@ -1454,10 +1470,11 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
// Also, not cleaned up
removeDrawable(objectp->mDrawable);
if(new_dead_object)
{
mNumDeadObjects++;
}
// <FS:Beq> FIRE-30694 DeadObject Spam
// if(new_dead_object)
// {
// mNumDeadObjects++;
// }
}
static LLTrace::BlockTimerStatHandle FTM_REMOVE_DRAWABLE("Remove Drawable");
@ -1589,12 +1606,17 @@ void LLViewerObjectList::killAllObjects()
void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
{
// <FS:Beq/> FIRE-30694 DeadObject Spam
llassert( mNumDeadObjects == mDeadObjects.size() );
if (!mNumDeadObjects)
{
// No dead objects, don't need to scan object list.
return;
}
// <FS:Beq/> FIRE-30694 DeadObject Spam
S32 num_divergent = 0;
S32 num_removed = 0;
LLViewerObject *objectp;
@ -1617,7 +1639,13 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
if (objectp->isDead())
{
mDeadObjects.erase(objectp->mID); // <FS:Ansariel> Use timer for cleaning up dead objects
// <FS:Beq> FIRE-30694 DeadObject Spam
// mDeadObjects.erase(objectp->mID); // <FS:Ansariel> Use timer for cleaning up dead objects
if(mDeadObjects.erase(objectp->mID)==0)
{
LL_WARNS() << "Attempt to delete object " << objectp->mID << " but object not in dead list" << LL_ENDL;
num_divergent++; // this is the number we are adrift in the count
}
LLPointer<LLViewerObject>::swap(*iter, *target);
*target = NULL;
++target;
@ -1651,9 +1679,10 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
mObjects.erase(mObjects.begin()+(mObjects.size()-num_removed), mObjects.end());
mNumDeadObjects -= num_removed;
if (mNumDeadObjects != mDeadObjects.size())
// TODO(Beq) If this still happens, we ought to realign at this point. Do a full sweep and reset.
if ( mNumDeadObjects != mDeadObjects.size() )
{
LL_WARNS() << "Num dead objects != dead object list size" << LL_ENDL;
LL_WARNS() << "Num dead objects (" << mNumDeadObjects << ") != dead object list size (" << mDeadObjects.size() << "), deadlist discrepancy (" << num_divergent << ")" << LL_ENDL;
}
// </FS:Ansariel>
}

View File

@ -247,6 +247,9 @@ LLGLSLShader gDeferredFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightProgram;
LLGLSLShader gNormalMapGenProgram;
// [RLVa:KB] - @setsphere
LLGLSLShader gRlvSphereProgram;
// [/RLVa:KB]
// Deferred materials shaders
LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
@ -342,6 +345,9 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gDeferredWLCloudProgram);
mShaderList.push_back(&gDeferredWLMoonProgram);
mShaderList.push_back(&gDeferredWLSunProgram);
// [RLVa:KB] - @setsphere
mShaderList.push_back(&gRlvSphereProgram);
// [/RLVa:KB]
}
LLViewerShaderMgr::~LLViewerShaderMgr()
@ -4114,6 +4120,9 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLCloudProgram.unload();
gWLSunProgram.unload();
gWLMoonProgram.unload();
// [RLVa:KB] - @setsphere
gRlvSphereProgram.unload();
// [/RLVa:KB]
return TRUE;
}
@ -4147,6 +4156,21 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
success = gWLCloudProgram.createShader(NULL, NULL);
}
// [RLVa:KB] - @setsphere
if (success)
{
gRlvSphereProgram.mName = "RLVa Sphere Post Processing Shader";
gRlvSphereProgram.mShaderFiles.clear();
gRlvSphereProgram.mShaderFiles.push_back(make_pair("deferred/rlvV.glsl", GL_VERTEX_SHADER_ARB));
if (gGLManager.mGLVersion >= 4.5f)
gRlvSphereProgram.mShaderFiles.push_back(make_pair("deferred/rlvF.glsl", GL_FRAGMENT_SHADER_ARB));
else
gRlvSphereProgram.mShaderFiles.push_back(make_pair("deferred/rlvFLegacy.glsl", GL_FRAGMENT_SHADER_ARB));
gRlvSphereProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
success = gRlvSphereProgram.createShader(NULL, NULL);
}
// [/RLV:KB]
if (success)
{
gWLSunProgram.mName = "Windlight Sun Program";

View File

@ -334,6 +334,9 @@ extern LLGLSLShader gDeferredFullbrightShinyProgram;
extern LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
extern LLGLSLShader gDeferredSkinnedFullbrightProgram;
extern LLGLSLShader gNormalMapGenProgram;
// [RLVa:KB] - @setsphere
extern LLGLSLShader gRlvSphereProgram;
// [/RLVa:KB]
// Deferred materials shaders
extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];

View File

@ -640,7 +640,11 @@ void send_viewer_stats(bool include_preferences)
LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL;
if (debugLoggingEnabled("LogViewerStatsPacket"))
//<FS:Beq> avoid unfortunate sleep during trylock by static check
// if (debugLoggingEnabled("LogViewerStatsPacket"))
static auto debug_logging_on = debugLoggingEnabled("LogViewerStatsPacket");
if (debug_logging_on)
//</FS:Beq>
{
std::string filename("viewer_stats_packet.xml");
llofstream of(filename.c_str());

View File

@ -1696,6 +1696,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
mNeedsAux = FALSE;
destroyRawImage();
}
// <FS:Beq/> FIRE-30559 texture fetch speedup for user previews (based on patches from Oren Hurvitz)
gTextureList.recalcImageDecodePriority(this);
return res;
}

View File

@ -710,6 +710,8 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListTy
addImageToList(new_image);
mUUIDMap[key] = new_image;
new_image->setTextureListType(tex_type);
// <FS:Beq/> FIRE-30559 texture fetch speedup for user previews (based on patches from Oren Hurvitz)
gTextureList.recalcImageDecodePriority(new_image);
}
@ -721,6 +723,9 @@ void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image)
{
mCallbackList.erase(image);
}
// <FS:Beq/> FIRE-30559 texture fetch speedup for user previews (based on patches from Oren Hurvitz)
mImagesWithChangedPriorities.erase(image);
LLTextureKey key(image->getID(), (ETexListType)image->getTextureListType());
llverify(mUUIDMap.erase(key) == 1);
sNumImages--;
@ -855,121 +860,252 @@ void LLViewerTextureList::clearFetchingRequests()
}
}
// <FS:Beq> FIRE-30559 texture fetch speedup for user previews (based on patches from Oren Hurvitz)
// NOTE: previous version retained as single block comment, changes extend to the end of updateOneImageDecodePriority
// void LLViewerTextureList::updateImagesDecodePriorities()
// {
// // Update the decode priority for N images each frame
// {
// F32 lazy_flush_timeout = 30.f; // stop decoding
// F32 max_inactive_time = 20.f; // actually delete
// S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
// //reset imagep->getLastReferencedTimer() when screen is showing the progress view to avoid removing pre-fetched textures too soon.
// bool reset_timer = gViewerWindow->getProgressView()->getVisible();
// static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32
// const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES);
// S32 update_counter = llmin(max_update_count, mUUIDMap.size());
// uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);
// while ((update_counter-- > 0) && !mUUIDMap.empty())
// {
// if (iter == mUUIDMap.end())
// {
// iter = mUUIDMap.begin();
// }
// mLastUpdateKey = iter->first;
// LLPointer<LLViewerFetchedTexture> imagep = iter->second;
// ++iter; // safe to increment now
// if(imagep->isInDebug() || imagep->isUnremovable())
// {
// update_counter--;
// continue; //is in debug, ignore.
// }
// //
// // Flush formatted images using a lazy flush
// //
// S32 num_refs = imagep->getNumRefs();
// if (num_refs == min_refs)
// {
// if(reset_timer)
// {
// imagep->getLastReferencedTimer()->reset();
// }
// else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)
// {
// // Remove the unused image from the image list
// deleteImage(imagep);
// imagep = NULL; // should destroy the image
// }
// continue;
// }
// else
// {
// if(imagep->hasSavedRawImage())
// {
// if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)
// {
// imagep->destroySavedRawImage() ;
// }
// }
// if(imagep->isDeleted())
// {
// continue ;
// }
// else if(imagep->isDeletionCandidate())
// {
// imagep->destroyTexture() ;
// continue ;
// }
// else if(imagep->isInactive())
// {
// if(reset_timer)
// {
// imagep->getLastReferencedTimer()->reset();
// }
// else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)
// {
// imagep->setDeletionCandidate() ;
// }
// continue ;
// }
// else
// {
// imagep->getLastReferencedTimer()->reset();
// //reset texture state.
// imagep->setInactive() ;
// }
// }
// if (!imagep->isInImageList())
// {
// continue;
// }
// if(imagep->isInFastCacheList())
// {
// continue; //wait for loading from the fast cache.
// }
// imagep->processTextureStats();
// F32 old_priority = imagep->getDecodePriority();
// F32 old_priority_test = llmax(old_priority, 0.0f);
// F32 decode_priority = imagep->calcDecodePriority();
// F32 decode_priority_test = llmax(decode_priority, 0.0f);
// // Ignore < 20% difference
// if ((decode_priority_test < old_priority_test * .8f) ||
// (decode_priority_test > old_priority_test * 1.25f))
// {
// mImageList.erase(imagep) ;
// imagep->setDecodePriority(decode_priority);
// mImageList.insert(imagep);
// }
// }
// }
// }
void LLViewerTextureList::recalcImageDecodePriority(LLPointer<LLViewerFetchedTexture> image)
{
mImagesWithChangedPriorities.insert(image);
}
void LLViewerTextureList::updateImagesDecodePriorities()
{
// Update the decode priority for N images each frame
static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32
const size_t max_update_count = llmin((S32)(MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES);
S32 update_counter = llmin(max_update_count, (mImagesWithChangedPriorities.size() + mUUIDMap.size()));
// First, process images whose decode priorities may have changed recently
image_list_t::iterator iter2 = mImagesWithChangedPriorities.begin();
while ((update_counter-- > 0) && (iter2 != mImagesWithChangedPriorities.end()))
{
F32 lazy_flush_timeout = 30.f; // stop decoding
F32 max_inactive_time = 20.f; // actually delete
S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
LLPointer<LLViewerFetchedTexture> imagep = *iter2;
iter2 = mImagesWithChangedPriorities.erase(iter2);
updateOneImageDecodePriority(imagep);
}
//reset imagep->getLastReferencedTimer() when screen is showing the progress view to avoid removing pre-fetched textures too soon.
bool reset_timer = gViewerWindow->getProgressView()->getVisible();
static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32
const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES);
S32 update_counter = llmin(max_update_count, mUUIDMap.size());
uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);
while ((update_counter-- > 0) && !mUUIDMap.empty())
// Second, process all of the images
uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);
while ((update_counter-- > 0) && !mUUIDMap.empty())
{
if (iter == mUUIDMap.end())
{
if (iter == mUUIDMap.end())
{
iter = mUUIDMap.begin();
}
mLastUpdateKey = iter->first;
LLPointer<LLViewerFetchedTexture> imagep = iter->second;
++iter; // safe to increment now
if(imagep->isInDebug() || imagep->isUnremovable())
{
update_counter--;
continue; //is in debug, ignore.
}
//
// Flush formatted images using a lazy flush
//
S32 num_refs = imagep->getNumRefs();
if (num_refs == min_refs)
{
if(reset_timer)
{
imagep->getLastReferencedTimer()->reset();
}
else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)
{
// Remove the unused image from the image list
deleteImage(imagep);
imagep = NULL; // should destroy the image
}
continue;
}
else
{
if(imagep->hasSavedRawImage())
{
if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)
{
imagep->destroySavedRawImage() ;
}
}
if(imagep->isDeleted())
{
continue ;
}
else if(imagep->isDeletionCandidate())
{
imagep->destroyTexture() ;
continue ;
}
else if(imagep->isInactive())
{
if(reset_timer)
{
imagep->getLastReferencedTimer()->reset();
}
else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)
{
imagep->setDeletionCandidate() ;
}
continue ;
}
else
{
imagep->getLastReferencedTimer()->reset();
//reset texture state.
imagep->setInactive() ;
}
}
if (!imagep->isInImageList())
{
continue;
}
if(imagep->isInFastCacheList())
{
continue; //wait for loading from the fast cache.
}
imagep->processTextureStats();
F32 old_priority = imagep->getDecodePriority();
F32 old_priority_test = llmax(old_priority, 0.0f);
F32 decode_priority = imagep->calcDecodePriority();
F32 decode_priority_test = llmax(decode_priority, 0.0f);
// Ignore < 20% difference
if ((decode_priority_test < old_priority_test * .8f) ||
(decode_priority_test > old_priority_test * 1.25f))
{
mImageList.erase(imagep) ;
imagep->setDecodePriority(decode_priority);
mImageList.insert(imagep);
}
iter = mUUIDMap.begin();
}
mLastUpdateKey = iter->first;
LLPointer<LLViewerFetchedTexture> imagep = iter->second;
++iter; // safe to increment now
updateOneImageDecodePriority(imagep);
}
}
void LLViewerTextureList::updateOneImageDecodePriority(LLPointer<LLViewerFetchedTexture> imagep)
{
const F32 lazy_flush_timeout = 30.f; // stop decoding
const F32 max_inactive_time = 20.f; // actually delete
const S32 min_refs = 4; // 1 for mImageList, 1 for mUUIDMap, 2 for local references
bool reset_timer = gViewerWindow->getProgressView()->getVisible();
if(imagep->isInDebug() || imagep->isUnremovable())
{
return; //is in debug, ignore.
}
//
// Flush formatted images using a lazy flush
//
S32 num_refs = imagep->getNumRefs();
if (num_refs == min_refs)
{
if(reset_timer)
{
imagep->getLastReferencedTimer()->reset();
}
else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)
{
// Remove the unused image from the image list
deleteImage(imagep);
imagep = NULL; // should destroy the image
}
return;
}
else
{
if(imagep->hasSavedRawImage())
{
if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)
{
imagep->destroySavedRawImage() ;
}
}
if(imagep->isDeleted())
{
return;
}
else if(imagep->isDeletionCandidate())
{
imagep->destroyTexture() ;
return;
}
else if(imagep->isInactive())
{
if(reset_timer)
{
imagep->getLastReferencedTimer()->reset();
}
else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)
{
imagep->setDeletionCandidate() ;
}
return;
}
else
{
imagep->getLastReferencedTimer()->reset();
//reset texture state.
imagep->setInactive() ;
}
}
if (!imagep->isInImageList())
{
return;
}
if(imagep->isInFastCacheList())
{
return; //wait for loading from the fast cache.
}
imagep->processTextureStats();
F32 old_priority = imagep->getDecodePriority();
F32 old_priority_test = llmax(old_priority, 0.0f);
F32 decode_priority = imagep->calcDecodePriority();
F32 decode_priority_test = llmax(decode_priority, 0.0f);
// Ignore < 20% difference
if ((decode_priority_test < old_priority_test * .8f) ||
(decode_priority_test > old_priority_test * 1.25f))
{
mImageList.erase(imagep) ;
imagep->setDecodePriority(decode_priority);
mImageList.insert(imagep);
}
}
// </FS:Beq> FIRE-30559
void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level)
{
if(!tex->setDebugFetching(debug_level))

View File

@ -34,6 +34,7 @@
#include "llui.h"
#include <list>
#include <set>
#include <deque>
#include "lluiimage.h"
const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128;
@ -147,6 +148,8 @@ public:
private:
void updateImagesDecodePriorities();
// <FS:Beq/> FIRE-30559 texture fetch speedup for user previews (based on patches from Oren Hurvitz)
void updateOneImageDecodePriority(LLPointer<LLViewerFetchedTexture> imagep);
F32 updateImagesCreateTextures(F32 max_time);
F32 updateImagesFetchTextures(F32 max_time);
void updateImagesUpdateStats();
@ -219,7 +222,12 @@ public:
// <FS:Ansariel> Fast cache stats
static U32 sNumFastCacheReads;
// <FS:Beq> FIRE-30559 texture fetch speedup for user previews (based on patches from Oren Hurvitz)
// Recalculate the image's Decode Priority.
// (We'll get to the image eventually even if this method isn't called, but this way it goes
// to the head(-ish) of the line.)
void recalcImageDecodePriority(LLPointer<LLViewerFetchedTexture> image);
// </FS:Beq>
private:
typedef std::map< LLTextureKey, LLPointer<LLViewerFetchedTexture> > uuid_map_t;
uuid_map_t mUUIDMap;
@ -228,7 +236,11 @@ private:
typedef std::set<LLPointer<LLViewerFetchedTexture>, LLViewerFetchedTexture::Compare> image_priority_list_t;
image_priority_list_t mImageList;
// <FS:Beq> FIRE-30559 texture fetch speedup for user previews (based on patches from Oren Hurvitz)
// Images that should be handled first in updateImagesDecodePriorities()
image_list_t mImagesWithChangedPriorities;
// </FS:Beq>
// simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon
std::set<LLPointer<LLViewerFetchedTexture> > mImagePreloads;

View File

@ -229,6 +229,8 @@
#include "llviewermenufile.h"
// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c)
#include "rlvactions.h"
#include "rlveffects.h"
#include "rlvhandler.h"
// [/RLVa:KB]
@ -489,6 +491,15 @@ public:
camera_view_text = llformat("CameraAtAxis %f %f %f",
(F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
// [RLVa:KB] - @showloc
if (!RlvActions::canShowLocation())
{
agent_center_text = RlvStrings::getString(RlvStringKeys::Hidden::Generic);
agent_root_center_text = RlvStrings::getString(RlvStringKeys::Hidden::Generic);
camera_center_text = RlvStrings::getString(RlvStringKeys::Hidden::Generic);
}
// [/RLVa:KB]
addText(xpos, ypos, agent_center_text); ypos += y_inc;
addText(xpos, ypos, agent_root_center_text); ypos += y_inc;
addText(xpos, ypos, agent_view_text); ypos += y_inc;
@ -5928,7 +5939,10 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) &&
(image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
{
U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA;
// <FS:Ansariel> FIRE-15667: 24bit depth maps
//U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA;
U32 color_fmt = (type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH || type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH24) ? GL_DEPTH_COMPONENT : GL_RGBA;
// </FS:Ansariel>
if (scratch_space.allocate(image_width, image_height, color_fmt, true, true))
{
original_width = gPipeline.mDeferredScreen.getWidth();
@ -7011,11 +7025,12 @@ void LLPickInfo::fetchResults()
mPickPt = mMousePt;
// [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay)
if ( (gRlvHandler.isEnabled()) && (hit_object) && (!hit_object->isHUDAttachment()) )
if ( (RlvActions::hasBehaviour(RLV_BHVR_SETOVERLAY)) && (hit_object) && (!hit_object->isHUDAttachment()) )
{
if (gRlvHandler.hitTestOverlay(mMousePt))
if (auto* pOverlayEffect = LLVfxManager::instance().getEffect<RlvOverlayEffect>(EVisualEffect::RlvOverlay))
{
hit_object = nullptr;
if (pOverlayEffect->hitTest(mMousePt))
hit_object = nullptr;
}
}
// [/RLVa:KB]

View File

@ -0,0 +1,140 @@
/**
*
* Copyright (c) 2021, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
#include "llviewerprecompiledheaders.h"
#include "llvisualeffect.h"
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range/iterator_range.hpp>
// ============================================================================
// LLTweenableValue class
//
template<>
float LLTweenableValueLerp<float>::get()
{
if (!m_CurValue)
{
float curFactor = (LLTimer::getElapsedSeconds() - m_StartTime) / m_Duration;
if (curFactor < 1.0)
return lerp(m_StartValue, m_EndValue, curFactor);
m_CurValue = m_EndValue;
}
return m_CurValue.get();
}
template<>
LLColor3 LLTweenableValueLerp<LLColor3>::get()
{
if (!m_CurValue)
{
float curFactor = (LLTimer::getElapsedSeconds() - m_StartTime) / m_Duration;
if (curFactor < 1.0)
return lerp(m_StartValue, m_EndValue, curFactor);
m_CurValue = m_EndValue;
}
return m_CurValue.get();
}
template<>
LLVector4 LLTweenableValueLerp<LLVector4>::get()
{
if (!m_CurValue)
{
float curFactor = (LLTimer::getElapsedSeconds() - m_StartTime) / m_Duration;
if (curFactor < 1.0)
return lerp(m_StartValue, m_EndValue, curFactor);
m_CurValue = m_EndValue;
}
return m_CurValue.get();
}
// ============================================================================
// LLVfxManager class
//
LLVfxManager::LLVfxManager()
{
}
bool LLVfxManager::addEffect(LLVisualEffect* pEffectInst)
{
if (m_Effects.end() != m_Effects.find(pEffectInst))
return false;
m_Effects.insert(pEffectInst);
return true;
}
LLVisualEffect* LLVfxManager::getEffect(const LLUUID& idEffect) const
{
auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [&idEffect](const LLVisualEffect* pEffect) { return pEffect->getId() == idEffect; });
return (m_Effects.end() != itEffect) ? *itEffect : nullptr;
}
LLVisualEffect* LLVfxManager::getEffect(EVisualEffect eCode) const
{
// NOTE: returns the first found but there could be more
auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; });
return (m_Effects.end() != itEffect) ? *itEffect : nullptr;
}
bool LLVfxManager::removeEffect(const LLUUID& idEffect)
{
auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [&idEffect](const LLVisualEffect* pEffect) { return pEffect->getId() == idEffect; });
if (m_Effects.end() == itEffect)
return false;
delete *itEffect;
m_Effects.erase(itEffect);
return true;
}
void LLVfxManager::runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams)
{
// *TODO-Catz: once we're done, check whether iterating over the entire list still has negliable impact
auto pred = [eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; };
auto itEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()),
endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end());
for (; itEffect != endEffect; ++itEffect)
{
if (pParams)
pParams->step(itEffect == endEffect);
(*itEffect)->run(pParams);
}
}
void LLVfxManager::runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams)
{
// *TODO-Catz: once we're done, check whether iterating over the entire list still has negliable impact
auto pred = [eType](const LLVisualEffect* pEffect) { return pEffect->getType() == eType; };
auto itEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()),
endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end());
for (; itEffect != endEffect; ++itEffect)
{
if (pParams)
pParams->step(itEffect == endEffect);
(*itEffect)->run(pParams);
}
}
// ============================================================================

View File

@ -0,0 +1,179 @@
/**
*
* Copyright (c) 2021, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
#pragma once
#include "llsingleton.h"
#include <boost/optional.hpp>
#include <boost/none.hpp>
// ============================================================================
//
//
class LLRenderTarget;
// ============================================================================
//
//
enum class EVisualEffect
{
RlvOverlay,
RlvSphere,
};
enum class EVisualEffectType
{
PostProcessShader,
Custom,
};
// ============================================================================
//
//
struct LLVisualEffectParams
{
virtual void step(bool isLast) = 0;
};
struct LLShaderEffectParams : LLVisualEffectParams
{
explicit LLShaderEffectParams(LLRenderTarget* pSrcBuffer, LLRenderTarget* pScratchBuffer, bool fBindLast) : m_pSrcBuffer(pScratchBuffer), m_pDstBuffer(pSrcBuffer), m_fBindLast(fBindLast) {}
void step(bool isLast) override
{
LLRenderTarget* pPrevSrc = m_pSrcBuffer, *pPrevDst = m_pDstBuffer;
m_pSrcBuffer = pPrevDst;
m_pDstBuffer = (!isLast || !m_fBindLast) ? pPrevSrc : nullptr;
}
LLRenderTarget* m_pSrcBuffer = nullptr;
LLRenderTarget* m_pDstBuffer = nullptr;
bool m_fBindLast = false;
};
// ============================================================================
//
//
class LLVisualEffect
{
public:
LLVisualEffect(LLUUID id, EVisualEffect eCode, EVisualEffectType eType)
: m_id(id), m_eCode(eCode), m_eType(eType)
{}
virtual ~LLVisualEffect() {}
EVisualEffect getCode() const { return m_eCode;}
const LLUUID& getId() const { return m_id;}
U32 getPriority() const { return m_nPriority; }
EVisualEffectType getType() const { return m_eType;}
virtual void run(const LLVisualEffectParams* pParams) = 0;
/*
* Member variables
*/
protected:
LLUUID m_id;
EVisualEffect m_eCode;
EVisualEffectType m_eType;
U32 m_nPriority;
};
// ============================================================================
//
//
template<typename T>
class LLTweenableValue
{
public:
LLTweenableValue(const T& defaultValue) : m_CurValue(defaultValue) {}
virtual ~LLTweenableValue() {}
virtual T get() = 0;
virtual void start(const T& endValue, double duration) = 0;
T& operator =(const T& value) { m_CurValue = value; }
/*
* Member variables
*/
protected:
boost::optional<T> m_CurValue;
};
template<typename T>
class LLTweenableValueLerp : public LLTweenableValue<T>
{
public:
LLTweenableValueLerp(const T& defaultValue) : LLTweenableValue<T>(defaultValue) {}
T get() override;
void start(const T& endValue, double duration) override
{
m_StartValue = get();
this->m_CurValue = boost::none;
m_EndValue = endValue;
m_StartTime = LLTimer::getElapsedSeconds();
m_Duration = duration;
}
/*
* Member variables
*/
protected:
double m_StartTime;
double m_Duration;
T m_StartValue;
T m_EndValue;
};
// ============================================================================
//
//
class LLVfxManager : public LLSingleton<LLVfxManager>
{
LLSINGLETON(LLVfxManager);
protected:
~LLVfxManager() {}
/*
* Member functions
*/
public:
bool addEffect(LLVisualEffect* pEffectInst);
LLVisualEffect* getEffect(const LLUUID& idEffect) const;
template<typename T> T* getEffect(const LLUUID& idEffect) const { return dynamic_cast<T*>(getEffect(idEffect)); }
LLVisualEffect* getEffect(EVisualEffect eCode) const;
template<typename T> T* getEffect(EVisualEffect eCode) const { return dynamic_cast<T*>(getEffect(eCode)); }
bool removeEffect(const LLUUID& idEffect);
void runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams = nullptr);
void runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams = nullptr);
protected:
/*
* Member variables
*/
protected:
std::set<LLVisualEffect*> m_Effects;
};
// ============================================================================

View File

@ -131,6 +131,7 @@
#include "llviewernetwork.h" // [FS:CR] isInSecondlife()
#include "llsidepanelappearance.h"
#include "fsavatarrenderpersistence.h"
#include "fslslbridge.h" // <FS:PP> Movelock position refresh
#include "fsdiscordconnect.h" // <FS:LO> tapping a place that happens on landing in world to start up discord
@ -3320,7 +3321,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
bool fRlvShowAvTag = true, fRlvShowAvName = true;
if (RlvActions::isRlvEnabled())
{
fRlvShowAvTag = RlvActions::canShowName(RlvActions::SNC_NAMETAG, getID());
fRlvShowAvTag = RlvActions::canShowNameTag(this);
fRlvShowAvName = (fRlvShowAvTag) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, getID()));
}
// [/RLVa:KB]
@ -8235,6 +8236,13 @@ void LLVOAvatar::sitDown(BOOL bSitting)
gRlvHandler.onSitOrStand(bSitting);
}
// [/RLVa:KB]
// <FS:PP> Refresh movelock position after sitting down to prevent pulling avatar back to previous one after standing up
if (bSitting && gSavedPerAccountSettings.getBOOL("UseMoveLock") && gSavedPerAccountSettings.getBOOL("RelockMoveLockAfterMovement"))
{
FSLSLBridge::instance().viewerToLSL("UseMoveLock|1|noreport");
}
// </FS:PP>
}
}

View File

@ -115,6 +115,7 @@
#include "llprogressview.h"
#include "llcleanup.h"
// [RLVa:KB] - Checked: RLVa-2.0.0
#include "llvisualeffect.h"
#include "rlvactions.h"
#include "rlvlocks.h"
// [/RLVa:KB]
@ -376,6 +377,9 @@ bool LLPipeline::sRenderParticles; // <FS:LO> flag to hold correct, user selecte
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
bool LLPipeline::sRenderTextures = true;
// [/SL:KB]
// [RLVa:KB] - @setsphere
bool LLPipeline::sUseDepthTexture = false;
// [/RLVa:KB]
// EventHost API LLPipeline listener.
static LLPipelineListener sPipelineListener;
@ -1055,8 +1059,22 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mFXAABuffer.release();
mScreen.release();
mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
mDeferredDepth.release();
mOcclusionDepth.release();
// [RLVa:KB] - @setsphere
if (!LLRenderTarget::sUseFBO || !LLPipeline::sUseDepthTexture)
{
mDeferredDepth.release();
mOcclusionDepth.release();
}
else
{
const U32 occlusion_divisor = 3;
if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!mOcclusionDepth.allocate(resX / occlusion_divisor, resY / occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (RlvActions::isRlvEnabled() && !mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
// [/RLVa:KB]
// mDeferredDepth.release();
// mOcclusionDepth.release();
if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
@ -4591,7 +4609,17 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
LLGLSLShader::bindNoShader();
doOcclusion(camera);
// [RLVa:KB] - @setsphere
if (LLPipeline::RenderDeferred || !LLRenderTarget::sUseFBO || !LLPipeline::sUseDepthTexture)
{
doOcclusion(camera);
}
else
{
doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth);
}
// [/RLVa:KB]
// doOcclusion(camera);
}
pool_set_t::iterator iter2 = iter1;
@ -7898,6 +7926,9 @@ void LLPipeline::renderFinalize()
LLVertexBuffer::unbind();
// [RLVa:KB] - @setsphere
LLRenderTarget* pRenderBuffer = (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) ? &mDeferredLight : nullptr;
// [/RLVa:KB]
if (LLPipeline::sRenderDeferred)
{
@ -7910,6 +7941,12 @@ void LLPipeline::renderFinalize()
bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete();
exoPostProcess::instance().multisample = multisample; // <FS:CR> Import Vignette from Exodus
// [RLVa:KB] - @setsphere
if (multisample && !pRenderBuffer)
{
pRenderBuffer = &mDeferredLight;
}
// [/RLVa:KB]
gViewerWindow->setup3DViewport();
@ -8108,11 +8145,18 @@ void LLPipeline::renderFinalize()
}
{ // combine result based on alpha
if (multisample)
// if (multisample)
// {
// mDeferredLight.bindTarget();
// glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
// }
// [RLVa:KB] - @setsphere
if (pRenderBuffer)
{
mDeferredLight.bindTarget();
pRenderBuffer->bindTarget();
glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
}
// [/RLVa:KB]
else
{
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
@ -8153,18 +8197,30 @@ void LLPipeline::renderFinalize()
unbindDeferredShader(*shader);
if (multisample)
// [RLVa:KB] - @setsphere
if (pRenderBuffer)
{
mDeferredLight.flush();
pRenderBuffer->flush();
}
// [/RLVa:KB]
// if (multisample)
// {
// mDeferredLight.flush();
// }
}
}
else
{
if (multisample)
// if (multisample)
// {
// mDeferredLight.bindTarget();
// }
// [RLVa:KB] - @setsphere
if (pRenderBuffer)
{
mDeferredLight.bindTarget();
pRenderBuffer->bindTarget();
}
// [/RLVa:KB]
LLGLSLShader *shader = &gDeferredPostNoDoFProgram;
bindDeferredShader(*shader);
@ -8192,12 +8248,27 @@ void LLPipeline::renderFinalize()
unbindDeferredShader(*shader);
if (multisample)
// [RLVa:KB] - @setsphere
if (pRenderBuffer)
{
mDeferredLight.flush();
pRenderBuffer->flush();
}
// [/RLVa:KB]
// if (multisample)
// {
// mDeferredLight.flush();
// }
}
// [RLVa:KB] - @setsphere
if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE))
{
LLShaderEffectParams params(pRenderBuffer, &mScreen, !multisample);
LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere, &params);
pRenderBuffer = params.m_pDstBuffer;
}
// [/RLVa:KB]
if (multisample)
{
// bake out texture2D with RGBL for FXAA shader
@ -8212,11 +8283,18 @@ void LLPipeline::renderFinalize()
shader->bind();
shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
// S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
// if (channel > -1)
// {
// mDeferredLight.bindTexture(0, channel);
// }
// [RLVa:KB] - @setsphere
S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, pRenderBuffer->getUsage());
if (channel > -1)
{
mDeferredLight.bindTexture(0, channel);
pRenderBuffer->bindTexture(0, channel);
}
// [RLVa:KB]
// <FS:Ansariel> FIRE-16829: Visual Artifacts with ALM enabled on AMD graphics
//gGL.begin(LLRender::TRIANGLE_STRIP);
@ -8229,7 +8307,10 @@ void LLPipeline::renderFinalize()
drawAuxiliaryVB();
// </FS:Ansariel>
shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
// [RLVa:KB] - @setsphere
shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, pRenderBuffer->getUsage());
// [/RLVa:KB]
// shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
shader->unbind();
mFXAABuffer.flush();
@ -8273,6 +8354,15 @@ void LLPipeline::renderFinalize()
}
else // not deferred
{
// [RLVa:KB] - @setsphere
if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE))
{
LLShaderEffectParams params(&mScreen, &mDeferredLight, false);
LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere, &params);
pRenderBuffer = params.m_pDstBuffer;
}
// [/RLVa:KB]
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
buff->allocateBuffer(3, 0, TRUE);
@ -8315,7 +8405,10 @@ void LLPipeline::renderFinalize()
}
gGL.getTexUnit(0)->bind(&mGlow[1]);
gGL.getTexUnit(1)->bind(&mScreen);
// [RLVa:KB] - @setsphere
gGL.getTexUnit(1)->bind( pRenderBuffer ? pRenderBuffer : &mScreen );
// [/RLVa:KB]
// gGL.getTexUnit(1)->bind(&mScreen);
LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);

View File

@ -622,6 +622,9 @@ public:
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
static bool sRenderTextures;
// [/SL:KB]
// [RLVa:KB] - @setsphere
static bool sUseDepthTexture;
// [/RLVa:KB]
static LLTrace::EventStatHandle<S64> sStatBatchSize;

View File

@ -616,7 +616,7 @@ BOOL FloaterQuickPrefs::postBuild()
if (gRlvHandler.isEnabled())
{
enableWindlightButtons(!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
enableWindlightButtons(!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV) && !gRlvHandler.hasBehaviour(RLV_BHVR_SETSPHERE));
}
// <FS:Zi> Dynamic quick prefs
@ -1026,7 +1026,7 @@ void FloaterQuickPrefs::refreshSettings()
BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
mCtrlReflectionDetail->setEnabled(reflections);
mCtrlWindLight->setEnabled((!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) || (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")) );
mCtrlWindLight->setEnabled((!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV) && !gRlvHandler.hasBehaviour(RLV_BHVR_SETSPHERE)) || (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")) );
LLTextBox* sky_label = getChild<LLTextBox>("T_Sky_Detail");
LLSlider* sky_slider = getChild<LLSlider>("SB_Sky_Detail");
@ -1170,7 +1170,7 @@ void FloaterQuickPrefs::refreshSettings()
void FloaterQuickPrefs::updateRlvRestrictions(ERlvBehaviour behavior, ERlvParamType type)
{
if (behavior == RLV_BHVR_SETENV)
if (behavior == RLV_BHVR_SETENV || behavior == RLV_BHVR_SETSPHERE)
{
enableWindlightButtons(type != RLV_TYPE_ADD);
}

View File

@ -220,9 +220,6 @@ bool RlvActions::canShowName(EShowNamesContext eContext, const LLUUID& idAgent)
{
switch (eContext)
{
// Show/hide avatar nametag
case SNC_NAMETAG:
return (gRlvHandler.isException(RLV_BHVR_SHOWNAMETAGS, idAgent)) || (gAgentID == idAgent);
// Show/hide avatar name
case SNC_DEFAULT:
case SNC_TELEPORTOFFER:
@ -235,6 +232,19 @@ bool RlvActions::canShowName(EShowNamesContext eContext, const LLUUID& idAgent)
return false;
}
bool RlvActions::canShowNameTag(const LLVOAvatar* pAvatar)
{
// An avatar's name tag can be shown if:
// - not restricted from seeing avatars' name tags
// - OR the avatar is a @shownametags exception
// - OR the avatar is within the distance that nametags can be shown
if ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMETAGS)) || (gRlvHandler.isException(RLV_BHVR_SHOWNAMETAGS, pAvatar->getID())) || (gAgentID == pAvatar->getID()) )
return true;
const F32 nShowNameTagsDist = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SHOWNAMETAGSDIST)->getValue<F32>();
return (nShowNameTagsDist != 0.f) && (dist_vec_squared(pAvatar->getPositionGlobal(), gAgent.getPositionGlobal()) < nShowNameTagsDist * nShowNameTagsDist);
}
bool RlvActions::canShowNearbyAgents()
{
return !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNEARBY);
@ -586,6 +596,28 @@ bool RlvActions::canShowLocation()
return !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC);
}
// ============================================================================
// World (General)
//
bool RlvActions::canHighlightTransparent()
{
// User cannot highlight transparent faces if:
// - prevented from editing (exceptions are not taken into account)
// - specifically prevented from highlight transparent faces
return !gRlvHandler.hasBehaviour(RLV_BHVR_EDIT) && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC);
}
bool RlvActions::canViewWireframe()
{
// User can use wireframe rendering if:
// - no HUD attachment is (remove) locked
// - not specifically prevented from using wireframe mode
return
!gRlvAttachmentLocks.hasLockedHUD() && // Trivial function so no overhead when RLV is not enabled
!gRlvHandler.hasBehaviour(RLV_BHVR_VIEWWIREFRAME);
}
// ============================================================================
// Helper functions
//

View File

@ -28,6 +28,7 @@
class LLInventoryCategory;
class LLInventoryItem;
class LLViewerObject;
class LLVOAvatar;
// ============================================================================
// RlvActions class declaration - developer-friendly non-RLVa code facing class, use in lieu of RlvHandler whenever possible
@ -124,8 +125,9 @@ public:
* (This is used to hide an avatar name in one case but not a near-identical case - such as teleporting a friend vs a nearby agent -
* in a way that limits the amount of code that needs to be changed to carry context from one function to another)
*/
enum EShowNamesContext { SNC_DEFAULT = 0, SNC_NAMETAG, SNC_TELEPORTOFFER, SNC_TELEPORTREQUEST, SNC_COUNT };
enum EShowNamesContext { SNC_DEFAULT = 0, SNC_TELEPORTOFFER, SNC_TELEPORTREQUEST, SNC_COUNT };
static bool canShowName(EShowNamesContext eContext, const LLUUID& idAgent = LLUUID::null);
static bool canShowNameTag(const LLVOAvatar* pAvatar);
static void setShowName(EShowNamesContext eContext, bool fCanShowName) { if ( (eContext < SNC_COUNT) && (isRlvEnabled()) ) { s_BlockNamesContexts[eContext] = !fCanShowName; } }
/*
@ -301,6 +303,20 @@ public:
*/
static bool canTouch(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero);
// ===============
// World (General)
// ===============
public:
/*
* Returns true if the user can highlight transparent faces
*/
static bool canHighlightTransparent();
/*
* Returns true if the user can switch to wireframe rendering
*/
static bool canViewWireframe();
// ================
// Helper functions
// ================

View File

@ -405,6 +405,8 @@ const char* RlvStrings::getStringFromReturnCode(ERlvCmdRet eRet)
return "deprecated and disabled";
case RLV_RET_FAILED_NOBEHAVIOUR:
return "no active behaviours";
case RLV_RET_FAILED_UNHELDBEHAVIOUR:
return "base behaviour not held";
case RLV_RET_FAILED_BLOCKED:
return "blocked object";
case RLV_RET_FAILED_THROTTLED:

View File

@ -56,7 +56,7 @@ class RlvObject;
struct RlvException;
typedef boost::variant<std::string, LLUUID, S32, ERlvBehaviour> RlvExceptionOption;
typedef boost::variant<int, float, bool, LLVector3, LLVector3d, LLUUID> RlvBehaviourModifierValue;
typedef boost::variant<int, float, bool, LLVector3, LLVector3d, LLVector4, LLUUID> RlvBehaviourModifierValue;
class RlvGCTimer;

View File

@ -26,19 +26,19 @@
// Version of the specifcation we report
const S32 RLV_VERSION_MAJOR = 3;
const S32 RLV_VERSION_MINOR = 3;
const S32 RLV_VERSION_MINOR = 4;
const S32 RLV_VERSION_PATCH = 3;
const S32 RLV_VERSION_BUILD = 0;
// Version of the specifcation we report (in compatibility mode)
const S32 RLV_VERSION_MAJOR_COMPAT = 2;
const S32 RLV_VERSION_MINOR_COMPAT = 8;
const S32 RLV_VERSION_PATCH_COMPAT = 0;
const S32 RLV_VERSION_MINOR_COMPAT = 9;
const S32 RLV_VERSION_PATCH_COMPAT = 28;
const S32 RLV_VERSION_BUILD_COMPAT = 0;
// Implementation version
const S32 RLVa_VERSION_MAJOR = 2;
const S32 RLVa_VERSION_MINOR = 3;
const S32 RLVa_VERSION_MINOR = 4;
const S32 RLVa_VERSION_PATCH = 0;
const S32 RLVa_IMPL_ID = 13;
@ -157,6 +157,8 @@ enum ERlvBehaviour {
RLV_BHVR_BUY, // "buy"
RLV_BHVR_EDIT, // "edit"
RLV_BHVR_EDITOBJ, // "editobj"
RLV_BHVR_VIEWTRANSPARENT,
RLV_BHVR_VIEWWIREFRAME,
RLV_BHVR_PAY, // "pay"
RLV_BHVR_REZ, // "rez"
RLV_BHVR_FARTOUCH, // "fartouch"
@ -243,12 +245,9 @@ enum ERlvBehaviour {
// Camera (force)
RLV_BHVR_SETCAM_MODE, // Switch the user's camera into the specified mode (e.g. mouselook or thirdview)
// Overlay
// Effects
RLV_BHVR_SETSPHERE, // Gives an object exclusive control of the 'vision spheres' effect
RLV_BHVR_SETOVERLAY, // Gives an object exclusive control of the overlay
RLV_BHVR_SETOVERLAY_ALPHA, // Changes the overlay texture's transparency level
RLV_BHVR_SETOVERLAY_TEXTURE, // Changes the overlay texture
RLV_BHVR_SETOVERLAY_TINT, // Changes the tint that's applied to the overlay texture
RLV_BHVR_SETOVERLAY_TOUCH, // Block world interaction (=touching) based on the alpha channel of the overlay texture
RLV_BHVR_SETOVERLAY_TWEEN, // Animate between the current overlay settings and the supplied values
RLV_BHVR_COUNT,
@ -258,10 +257,6 @@ enum ERlvBehaviour {
enum ERlvBehaviourModifier
{
RLV_MODIFIER_FARTOUCHDIST, // Radius of a sphere around the user in which they can interact with the world
RLV_MODIFIER_OVERLAY_ALPHA, // Transparency level of the overlay texture (in addition to the texture's own alpha channel)
RLV_MODIFIER_OVERLAY_TEXTURE, // Specifies the UUID of the overlay texture
RLV_MODIFIER_OVERLAY_TINT, // The tint that's applied to the overlay texture
RLV_MODIFIER_OVERLAY_TOUCH, // Determines whether the overlay texture's alpha channel will be used to allow/block world interaction
RLV_MODIFIER_RECVIMDISTMIN, // Minimum distance to receive an IM from an otherwise restricted sender (squared value)
RLV_MODIFIER_RECVIMDISTMAX, // Maximum distance to receive an IM from an otherwise restricted sender (squared value)
RLV_MODIFIER_SENDIMDISTMIN, // Minimum distance to send an IM to an otherwise restricted recipient (squared value)
@ -279,6 +274,7 @@ enum ERlvBehaviourModifier
RLV_MODIFIER_SETCAM_FOVMIN, // Minimum value for the camera's field of view (angle in radians)
RLV_MODIFIER_SETCAM_FOVMAX, // Maximum value for the camera's field of view (angle in radians)
RLV_MODIFIER_SETCAM_TEXTURE, // Specifies the UUID of the texture used to texture the world view
RLV_MODIFIER_SHOWNAMETAGSDIST, // Distance at which name tags will still be shown
RLV_MODIFIER_SITTPDIST,
RLV_MODIFIER_TPLOCALDIST,
@ -286,6 +282,28 @@ enum ERlvBehaviourModifier
RLV_MODIFIER_UNKNOWN
};
enum class ERlvLocalBhvrModifier
{
// @setoverlay
OverlayAlpha, // Transparency level of the overlay texture (in addition to the texture's own alpha channel)
OverlayTexture, // Specifies the UUID of the overlay texture
OverlayTint, // The tint that's applied to the overlay texture
OverlayTouch, // Determines whether the overlay texture's alpha channel will be used to allow/block world interaction
// @setsphere
SphereMode, // The type of effect that will apply to any pixel that intersects with the sphere (e.g. blend, blur, ...)
SphereOrigin, // The origin of the sphere can either be the avatar or the camera position
SphereColor, // [Blend only] Colour to mix with the actual pixel colour (stored as params)
SphereParams, // Effect parameters (dependent on mode - see RlvSphereEffect)
SphereDistMin, // Distance at which the effect starts and has weight minValue; e.g. for blend this would be colour = mix(colour, sphere_colour, min_alpha)
SphereDistMax, // Distance at which the effect starts and has weight maxValue; e.g. for blend this would be colour = mix(colour, sphere_colour, max_alpha)
SphereDistExtend, // Specifies the value beyond min dist or max dist (by default the sphere extends beyond max distance at max vlaue)
SphereValueMin, // Value of the effect at minimum distance
SphereValueMax, // Value of the effect at maximum distance
SphereTween, // Amount of seconds it takes to lerp from value A to value B
Unknown,
};
enum ERlvBehaviourOptionType
{
RLV_OPTION_NONE, // Behaviour takes no parameters
@ -323,6 +341,7 @@ enum ERlvCmdRet {
RLV_RET_FAILED_NOSHAREDROOT, // Command failed (missing #RLV)
RLV_RET_FAILED_DEPRECATED, // Command failed (deprecated and no longer supported)
RLV_RET_FAILED_NOBEHAVIOUR, // Command failed (force modifier on an object with no active restrictions)
RLV_RET_FAILED_UNHELDBEHAVIOUR, // Command failed (local modifier on an object that doesn't hold the base behaviour)
RLV_RET_FAILED_BLOCKED, // Command failed (object is blocked)
RLV_RET_FAILED_THROTTLED, // Command failed (throttled)
RLV_RET_NO_PROCESSOR // Command doesn't have a template processor define (legacy code)

View File

@ -0,0 +1,443 @@
/**
*
* Copyright (c) 2021, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "llfasttimer.h"
#include "llviewershadermgr.h"
#include "llviewertexturelist.h"
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "pipeline.h"
#include "rlveffects.h"
#include "rlvhandler.h"
// ====================================================================================
// RlvOverlayEffect class
//
const float c_DefaultAlpha = 1.0f;
const float c_DefaultColor[3] = { 1.0f, 1.0f, 1.0f };
RlvOverlayEffect::RlvOverlayEffect(const LLUUID& idRlvObj)
: LLVisualEffect(idRlvObj, EVisualEffect::RlvOverlay, EVisualEffectType::Custom)
, m_nAlpha(c_DefaultAlpha)
, m_fBlockTouch(false)
, m_Color(LLColor3(c_DefaultColor))
{
}
RlvOverlayEffect::~RlvOverlayEffect()
{
clearImage();
}
// static
ERlvCmdRet RlvOverlayEffect::onAlphaValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvOverlayEffect* pEffect = dynamic_cast<RlvOverlayEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
pEffect->m_nAlpha = (newValue) ? boost::get<float>(newValue.value()) : c_DefaultAlpha;
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvOverlayEffect::onBlockTouchValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvOverlayEffect* pEffect = dynamic_cast<RlvOverlayEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
pEffect->m_fBlockTouch = (newValue) ? boost::get<bool>(newValue.value()) : false;
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvOverlayEffect::onColorValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvOverlayEffect* pEffect = dynamic_cast<RlvOverlayEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
pEffect->m_Color = LLColor3( (newValue) ? boost::get<LLVector3>(newValue.value()).mV : c_DefaultColor);
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvOverlayEffect::onTextureChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvOverlayEffect* pEffect = dynamic_cast<RlvOverlayEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
if (newValue)
pEffect->setImage(boost::get<LLUUID>(newValue.value()));
else
pEffect->clearImage();
}
return RLV_RET_SUCCESS;
}
void RlvOverlayEffect::clearImage()
{
if (m_pImage)
{
m_pImage->setBoostLevel(m_nImageOrigBoost);
m_pImage = nullptr;
}
}
bool RlvOverlayEffect::hitTest(const LLCoordGL& ptMouse) const
{
if (!m_pImage)
return false;
return (m_fBlockTouch) && (m_pImage->getMask(LLVector2((float)ptMouse.mX / gViewerWindow->getWorldViewWidthScaled(), (float)ptMouse.mY / gViewerWindow->getWorldViewHeightScaled())));
}
void RlvOverlayEffect::setImage(const LLUUID& idTexture)
{
if ( (m_pImage) && (m_pImage->getID() == idTexture) )
return;
clearImage();
m_pImage = LLViewerTextureManager::getFetchedTexture(idTexture, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
m_nImageOrigBoost = m_pImage->getBoostLevel();
m_pImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
m_pImage->forceToSaveRawImage(0);
}
void RlvOverlayEffect::run(const LLVisualEffectParams*)
{
if (m_pImage)
{
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.bind();
}
int nWidth = gViewerWindow->getWorldViewWidthScaled();
int nHeight = gViewerWindow->getWorldViewHeightScaled();
m_pImage->addTextureStats(nWidth * nHeight);
m_pImage->setKnownDrawSize(nWidth, nHeight);
gGL.pushMatrix();
LLGLSUIDefault glsUI;
gViewerWindow->setup2DRender();
const LLVector2& displayScale = gViewerWindow->getDisplayScale();
gGL.scalef(displayScale.mV[VX], displayScale.mV[VY], 1.f);
gGL.getTexUnit(0)->bind(m_pImage);
const LLColor3 col = m_Color.get();
gGL.color4f(col.mV[0], col.mV[1], col.mV[2], llclamp(m_nAlpha.get(), 0.0f, 1.0f));
gl_rect_2d_simple_tex(nWidth, nHeight);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.popMatrix();
gGL.flush();
gViewerWindow->setup3DRender();
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.unbind();
}
}
}
// ====================================================================================
// RlvSphereEffect class
//
const int c_SphereDefaultMode = 0;
const int c_SphereDefaultOrigin = 0;
const float c_SphereDefaultColor[4] = { 0.0, 0.f, 0.f, 0.f };
const float c_SphereDefaultDistance = 0.0f;
const int c_SphereDefaultDistanceExtend = 1;
const float c_SphereDefaultAlpha = 1.0f;
RlvSphereEffect::RlvSphereEffect(const LLUUID& idRlvObj)
: LLVisualEffect(idRlvObj, EVisualEffect::RlvSphere, EVisualEffectType::PostProcessShader)
, m_eMode((ESphereMode)c_SphereDefaultMode)
, m_eOrigin((ESphereOrigin)c_SphereDefaultOrigin)
, m_Params(LLVector4(c_SphereDefaultColor))
, m_nDistanceMin(c_SphereDefaultDistance), m_nDistanceMax(c_SphereDefaultDistance)
, m_eDistExtend((ESphereDistExtend)c_SphereDefaultDistanceExtend)
, m_nValueMin(c_SphereDefaultAlpha), m_nValueMax(c_SphereDefaultAlpha)
, m_nTweenDuration(0.f)
{
}
RlvSphereEffect::~RlvSphereEffect()
{
}
// static
ERlvCmdRet RlvSphereEffect::onModeChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
pEffect->m_eMode = (ESphereMode)((newValue) ? boost::get<int>(newValue.value()) : c_SphereDefaultMode);
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvSphereEffect::onOriginChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
pEffect->m_eOrigin = (ESphereOrigin)((newValue) ? boost::get<int>(newValue.value()) : c_SphereDefaultOrigin);
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvSphereEffect::onColorChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
LLVector4 vecColor = (newValue) ? LLVector4(boost::get<LLVector3>(newValue.value()), 1.0f) : LLVector4(c_SphereDefaultColor);
if (!pEffect->m_nTweenDuration)
pEffect->m_Params = vecColor;
else
pEffect->m_Params.start(vecColor, pEffect->m_nTweenDuration);
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvSphereEffect::onDistMinChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
float nDistanceMin = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultDistance;
if (!pEffect->m_nTweenDuration)
pEffect->m_nDistanceMin = nDistanceMin;
else
pEffect->m_nDistanceMin.start(nDistanceMin, pEffect->m_nTweenDuration);
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvSphereEffect::onDistMaxChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
float nDistanceMax = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultDistance;
if (!pEffect->m_nTweenDuration)
pEffect->m_nDistanceMax = nDistanceMax;
else
pEffect->m_nDistanceMax.start(nDistanceMax, pEffect->m_nTweenDuration);
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvSphereEffect::onDistExtendChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
pEffect->m_eDistExtend = (ESphereDistExtend)((newValue) ? boost::get<int>(newValue.value()) : c_SphereDefaultDistanceExtend);
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvSphereEffect::onParamsChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
LLVector4 params = LLVector4((newValue) ? boost::get<LLVector4>(newValue.value()).mV : c_SphereDefaultColor);
if (!pEffect->m_nTweenDuration)
pEffect->m_Params = params;
else
pEffect->m_Params.start(params, pEffect->m_nTweenDuration);
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvSphereEffect::onTweenDurationChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
pEffect->m_nTweenDuration = (newValue) ? boost::get<float>(newValue.value()) : 0;
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvSphereEffect::onValueMinChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
float nValueMin = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultAlpha;;
if (!pEffect->m_nTweenDuration)
pEffect->m_nValueMin = nValueMin;
else
pEffect->m_nValueMin.start(nValueMin, pEffect->m_nTweenDuration);
}
return RLV_RET_SUCCESS;
}
// static
ERlvCmdRet RlvSphereEffect::onValueMaxChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
{
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
{
float nValueMax = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultAlpha;
if (!pEffect->m_nTweenDuration)
pEffect->m_nValueMax = nValueMax;
else
pEffect->m_nValueMax.start(nValueMax, pEffect->m_nTweenDuration);
}
return RLV_RET_SUCCESS;
}
void RlvSphereEffect::setShaderUniforms(LLGLSLShader* pShader)
{
pShader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, get_current_projection().inverse().m);
pShader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, gPipeline.mScreen.getWidth(), gPipeline.mScreen.getHeight());
pShader->uniform1i(LLShaderMgr::RLV_EFFECT_MODE, llclamp((int)m_eMode, 0, (int)ESphereMode::Count));
// Pass the sphere origin to the shader
LLVector4 posSphereOrigin;
switch (m_eOrigin)
{
case ESphereOrigin::Camera:
posSphereOrigin.setVec(LLViewerCamera::instance().getOrigin(), 1.0f);
break;
case ESphereOrigin::Avatar:
default:
posSphereOrigin.setVec((isAgentAvatarValid()) ? gAgentAvatarp->getRenderPosition() : gAgent.getPositionAgent(), 1.0f);
break;
}
glh::vec4f posSphereOriginGl(posSphereOrigin.mV);
const glh::matrix4f& mvMatrix = gGLModelView;
mvMatrix.mult_matrix_vec(posSphereOriginGl);
pShader->uniform4fv(LLShaderMgr::RLV_EFFECT_PARAM1, 1, posSphereOriginGl.v);
// Pack min/max distance and alpha together
float nDistMin = m_nDistanceMin.get(), nDistMax = m_nDistanceMax.get();
const glh::vec4f sphereParams(m_nValueMin.get(), nDistMin, m_nValueMax.get(), (nDistMax >= nDistMin) ? nDistMax : nDistMin);
pShader->uniform4fv(LLShaderMgr::RLV_EFFECT_PARAM2, 1, sphereParams.v);
// Pass dist extend
int eDistExtend = (int)m_eDistExtend;
pShader->uniform2f(LLShaderMgr::RLV_EFFECT_PARAM3, eDistExtend & (int)ESphereDistExtend::Min, eDistExtend & (int)ESphereDistExtend::Max);
// Pass effect params
const glh::vec4f effectParams(m_Params.get().mV);
pShader->uniform4fv(LLShaderMgr::RLV_EFFECT_PARAM4, 1, effectParams.v);
}
void RlvSphereEffect::renderPass(LLGLSLShader* pShader, const LLShaderEffectParams* pParams) const
{
if (pParams->m_pDstBuffer)
{
pParams->m_pDstBuffer->bindTarget();
}
else
{
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
}
RLV_ASSERT_DBG(pParams->m_pSrcBuffer);
S32 nDiffuseChannel = pShader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, pParams->m_pSrcBuffer->getUsage());
if (nDiffuseChannel > -1)
{
pParams->m_pSrcBuffer->bindTexture(0, nDiffuseChannel);
gGL.getTexUnit(nDiffuseChannel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
S32 nDepthChannel = pShader->enableTexture(LLShaderMgr::DEFERRED_DEPTH, gPipeline.mDeferredDepth.getUsage());
if (nDepthChannel > -1)
{
gGL.getTexUnit(nDepthChannel)->bind(&gPipeline.mDeferredDepth, TRUE);
}
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
gGL.loadMatrix(gGLModelView);
LLVector2 tc1(0, 0);
LLVector2 tc2((F32)gPipeline.mScreen.getWidth() * 2, (F32)gPipeline.mScreen.getHeight() * 2);
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
gGL.vertex2f(-1, -1);
gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
gGL.vertex2f(-1, 3);
gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
gGL.vertex2f(3, -1);
gGL.end();
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
pShader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, pParams->m_pSrcBuffer->getUsage());
pShader->disableTexture(LLShaderMgr::DEFERRED_DEPTH, gPipeline.mDeferredDepth.getUsage());
if (pParams->m_pDstBuffer)
{
pParams->m_pDstBuffer->flush();
}
}
LLTrace::BlockTimerStatHandle FTM_RLV_EFFECT_SPHERE("Post-process (RLVa sphere)");
void RlvSphereEffect::run(const LLVisualEffectParams* pParams)
{
LL_RECORD_BLOCK_TIME(FTM_RLV_EFFECT_SPHERE);
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
gRlvSphereProgram.bind();
setShaderUniforms(&gRlvSphereProgram);
const LLShaderEffectParams* pShaderParams = static_cast<const LLShaderEffectParams*>(pParams);
switch (m_eMode)
{
case ESphereMode::Blend:
case ESphereMode::ChromaticAberration:
case ESphereMode::Pixelate:
renderPass(&gRlvSphereProgram, pShaderParams);
break;
case ESphereMode::Blur:
case ESphereMode::BlurVariable:
gRlvSphereProgram.uniform2f(LLShaderMgr::RLV_EFFECT_PARAM5, 1.f, 0.f);
renderPass(&gRlvSphereProgram, pShaderParams);
gRlvSphereProgram.uniform2f(LLShaderMgr::RLV_EFFECT_PARAM5, 0.f, 1.f);
renderPass(&gRlvSphereProgram, pShaderParams);
break;
default:
llassert(true);
}
gRlvSphereProgram.unbind();
}
// ====================================================================================

107
indra/newview/rlveffects.h Normal file
View File

@ -0,0 +1,107 @@
/**
*
* Copyright (c) 2021, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
#pragma once
#include "llvisualeffect.h"
#include "rlvhelper.h"
// ============================================================================
// Forward declarations
//
class LLViewerFetchedTexture;
// ====================================================================================
// RlvOverlayEffect class
//
class RlvOverlayEffect : public LLVisualEffect
{
public:
RlvOverlayEffect(const LLUUID& idRlvObj);
~RlvOverlayEffect();
public:
bool hitTest(const LLCoordGL& ptMouse) const;
void run(const LLVisualEffectParams*) override;
void tweenAlpha(float endAlpha, double duration) { m_nAlpha.start(endAlpha, duration); }
void tweenColor(LLColor3 endColor, double duration) { m_Color.start(endColor, duration); }
static ERlvCmdRet onAlphaValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onBlockTouchValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onColorValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onTextureChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
protected:
void clearImage();
void setImage(const LLUUID& idTexture);
/*
* Member variables
*/
protected:
LLTweenableValueLerp<float> m_nAlpha;
bool m_fBlockTouch;
LLTweenableValueLerp<LLColor3> m_Color;
LLPointer<LLViewerFetchedTexture> m_pImage = nullptr;
int m_nImageOrigBoost = 0;
};
// ====================================================================================
// RlvSphereEffect class
//
class RlvSphereEffect : public LLVisualEffect
{
public:
RlvSphereEffect(const LLUUID& idRlvObj);
~RlvSphereEffect();
public:
void run(const LLVisualEffectParams* pParams) override;
static ERlvCmdRet onModeChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onOriginChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onColorChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onDistMinChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onDistMaxChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onDistExtendChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onParamsChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onTweenDurationChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onValueMinChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
static ERlvCmdRet onValueMaxChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
protected:
void renderPass(LLGLSLShader* pShader, const LLShaderEffectParams* pParams) const;
void setShaderUniforms(LLGLSLShader* pShader);
/*
* Member variables
*/
protected:
enum class ESphereMode { Blend = 0, Blur, BlurVariable, ChromaticAberration, Pixelate, Count };
ESphereMode m_eMode;
enum class ESphereOrigin { Avatar = 0, Camera, Count };
ESphereOrigin m_eOrigin;
LLTweenableValueLerp<LLVector4> m_Params;
LLTweenableValueLerp<float> m_nDistanceMin;
LLTweenableValueLerp<float> m_nDistanceMax;
enum class ESphereDistExtend { Max = 0x01, Min = 0x02, Both = 0x03 };
ESphereDistExtend m_eDistExtend;
LLTweenableValueLerp<float> m_nValueMin;
LLTweenableValueLerp<float> m_nValueMax;
float m_nTweenDuration;
};
// ====================================================================================

View File

@ -17,6 +17,7 @@
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "rlvextensions.h"
@ -34,6 +35,7 @@ RlvExtGetSet::RlvExtGetSet()
if (!m_DbgAllowed.size()) // m_DbgAllowed is static and should only be initialized once
{
m_DbgAllowed.insert(std::pair<std::string, S16>("AvatarSex", DBG_READ | DBG_WRITE | DBG_PSEUDO));
m_DbgAllowed.insert(std::pair<std::string, S16>("AspectRatio", DBG_READ | DBG_PSEUDO));
m_DbgAllowed.insert(std::pair<std::string, S16>("RenderResolutionDivisor", DBG_READ | DBG_WRITE));
m_DbgAllowed.insert(std::pair<std::string, S16>(RlvSettingNames::ForbidGiveToRlv, DBG_READ));
m_DbgAllowed.insert(std::pair<std::string, S16>(RlvSettingNames::NoSetEnv, DBG_READ));
@ -196,6 +198,10 @@ std::string RlvExtGetSet::onGetPseudoDebug(const std::string& strSetting)
return llformat("%d", (gAgentAvatarp->getSex() == SEX_MALE)); // [See LLFloaterCustomize::LLFloaterCustomize()]
}
}
else if ("AspectRatio" == strSetting)
{
return llformat("%.3f", (float)gViewerWindow->getWorldViewWidthScaled() / gViewerWindow->getWorldViewHeightScaled());
}
return std::string();
}

View File

@ -813,7 +813,7 @@ void RlvFloaterConsole::onInput(LLUICtrl* pCtrl, const LLSD& sdParam)
strCmd.clear(); // Only show feedback on successful commands when there's an informational notice
if (!pstr->empty())
pstr->push_back(',');
pstr->append(", ");
pstr->append(strCmd);
}

View File

@ -50,15 +50,17 @@
#include "lltabcontainer.h" // @showinv - Tab container control for inventory tabs
#include "lltoolmgr.h" // @edit
#include "llviewercamera.h" // @setcam and related
#include "llviewershadermgr.h" // @setsphere
#include "llworldmapmessage.h" // @tpto
#include "llviewertexturelist.h" // @setcam_texture
#include "llviewerwindow.h" // @setoverlay
#include "pipeline.h" // @setsphere
// RLVa includes
#include "rlvactions.h"
#include "rlvenvironment.h"
#include "rlvfloaters.h"
#include "rlvactions.h"
#include "rlveffects.h"
#include "rlvhandler.h"
#include "rlvhelper.h"
#include "rlvinventory.h"
@ -184,7 +186,6 @@ void RlvHandler::cleanup()
RLV_ASSERT(std::all_of(m_Behaviours, m_Behaviours + RLV_BHVR_COUNT, [](S16 cnt) { return !cnt; }));
RLV_ASSERT(m_CurCommandStack.empty());
RLV_ASSERT(m_CurObjectStack.empty());
RLV_ASSERT(m_pOverlayImage.isNull());
//
// Clean up what's left
@ -1728,6 +1729,8 @@ ERlvCmdRet RlvCommandHandlerBaseImpl<RLV_TYPE_ADDREM>::processCommand(const RlvC
{
if (rlvCmd.isStrict())
gRlvHandler.removeException(rlvCmd.getObjectID(), RLV_BHVR_PERMISSIVE, eBhvr);
if (RlvObject* pRlvObj = gRlvHandler.getObject(rlvCmd.getObjectID()))
pRlvObj->clearModifiers(eBhvr);
gRlvHandler.m_Behaviours[eBhvr]--;
}
@ -1794,7 +1797,7 @@ ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_MODIFIER>::onCommand(const RlvC
// There should be an option and it should specify a valid modifier (RlvBehaviourModifier performs the appropriate type checks)
RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(rlvCmd.getBehaviourType());
RlvBehaviourModifierValue modValue;
if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), modValue)) )
if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), pBhvrModifier->getType(), modValue)) )
return RLV_RET_FAILED_OPTION;
// HACK-RLVa: reference counting doesn't happen until control returns to our caller but the modifier callbacks will happen now so we need to adjust the reference counts here
@ -1815,15 +1818,22 @@ ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_MODIFIER>::onCommand(const RlvC
return RLV_RET_SUCCESS;
}
// Handles: @bhvr[:<modifier>]=n|y
// Handles: @bhvr=n, @bhvr:<global modifier>=n|y and @bhvr:<local modifier>=force
template<>
ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_MODIFIER>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount)
{
// If there is an option then it should specify a valid modifier (and reference count)
if (rlvCmd.hasOption())
if ( (rlvCmd.getParamType() & RLV_TYPE_ADDREM) && (rlvCmd.hasOption()) )
{
// @bhvr:<global modifier>=n|y : if there is an option then it should specify a valid global modifier and if so we reference count
return RlvBehaviourGenericHandler<RLV_OPTION_MODIFIER>::onCommand(rlvCmd, fRefCount);
}
else if (rlvCmd.getParamType() == RLV_TYPE_FORCE)
{
// @bhvr:<local modifier>=force : local modifiers hide behind their primary behaviour which knows how to handle them
return rlvCmd.getBehaviourInfo()->processModifier(rlvCmd);
}
// Add the default option on an empty modifier if needed
// @bhvr=n : add the default option on an empty modifier if needed
RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(rlvCmd.getBehaviourType());
if ( (pBhvrModifier) && (pBhvrModifier->getAddDefault()) )
{
@ -2059,36 +2069,41 @@ void RlvBehaviourToggleHandler<RLV_BHVR_PAY>::onCommandToggle(ERlvBehaviour eBhv
template<> template<>
void RlvBehaviourToggleHandler<RLV_BHVR_SETOVERLAY>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
{
// Once an object has exclusive control over the overlay only its behaviours should be active. This affects:
// - behaviour modifiers => handled for us once we set the primary object
LLUUID idRlvObject;
if (fHasBhvr)
{
// Get the UUID of the primary object (there should only be one)
std::list<const RlvObject*> lObjects;
gRlvHandler.findBehaviour(RLV_BHVR_SETOVERLAY, lObjects);
RLV_ASSERT(lObjects.size() == 1);
idRlvObject = lObjects.front()->getObjectID();
}
RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_ALPHA)->setPrimaryObject(idRlvObject);
RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TINT)->setPrimaryObject(idRlvObject);
RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TEXTURE)->setPrimaryObject(idRlvObject);
RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TOUCH)->setPrimaryObject(idRlvObject);
LLVfxManager::instance().addEffect(new RlvOverlayEffect(gRlvHandler.getCurrentObject()));
else
LLVfxManager::instance().removeEffect(gRlvHandler.getCurrentObject());
}
// Handles: @setoverlay_texture:<uuid>=n|y changes
template<>
void RlvBehaviourModifierHandler<RLV_MODIFIER_OVERLAY_TEXTURE>::onValueChange() const
// Handles: @setsphere=n|y
template<> template<>
ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETSPHERE>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount)
{
if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TEXTURE))
// *TODO: this needs to be done in a cleaner way but FS needs to release ASAP
if (RLV_TYPE_ADD == rlvCmd.getParamType() && gRlvHandler.m_Behaviours[RLV_BHVR_SETSPHERE] >= 6)
return RLV_RET_FAILED_LOCK;
ERlvCmdRet eRet = RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_MODIFIER>::onCommand(rlvCmd, fRefCount);
if ( (RLV_RET_SUCCESS == eRet) && (!rlvCmd.isModifier()) )
{
if (pBhvrModifier->hasValue())
gRlvHandler.setOverlayImage(pBhvrModifier->getValue<LLUUID>());
// If we're not using deferred but are using Windlight shaders we need to force use of FBO and depthmap texture
if ( (!LLPipeline::RenderDeferred) && (LLPipeline::WindLightUseAtmosShaders) && (!LLPipeline::sUseDepthTexture) )
{
LLRenderTarget::sUseFBO = true;
LLPipeline::sUseDepthTexture = true;
gPipeline.releaseGLBuffers();
gPipeline.createGLBuffers();
gPipeline.resetVertexBuffers();
LLViewerShaderMgr::instance()->setShaders();
}
if (gRlvHandler.hasBehaviour(rlvCmd.getObjectID(), rlvCmd.getBehaviourType()))
LLVfxManager::instance().addEffect(new RlvSphereEffect(rlvCmd.getObjectID()));
else
gRlvHandler.clearOverlayImage();
LLVfxManager::instance().removeEffect(gRlvHandler.getCurrentObject());
}
return eRet;
}
// Handles: @sendchannel[:<channel>]=n|y and @sendchannel_except[:<channel>]=n|y
@ -2598,28 +2613,31 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SHOWNAMES>::onCommand(const RlvCommand&
return eRet;
}
// Handles: @shownametags[:<uuid>]=n|y toggles
template<> template<>
void RlvBehaviourToggleHandler<RLV_BHVR_SHOWNAMETAGS>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
// Handles: @shownametags[:<distance>] value changes
template<>
void RlvBehaviourModifierHandler<RLV_MODIFIER_SHOWNAMETAGSDIST>::onValueChange() const
{
if (LLApp::isExiting())
return; // Nothing to do if the viewer is shutting down
// Update the shownames context
RlvActions::setShowName(RlvActions::SNC_NAMETAG, !fHasBhvr);
// Refresh all name tags
LLVOAvatar::invalidateNameTags();
}
// Handles: @shownametags[:<uuid>]=n|y
// Handles: @shownametags[:<distance|uuid>]=n|y
template<> template<>
ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SHOWNAMETAGS>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount)
{
ERlvCmdRet eRet = RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_EXCEPTION>::onCommand(rlvCmd, fRefCount);
if ( (RLV_RET_SUCCESS == eRet) && (rlvCmd.hasOption()) )
LLVOAvatar::invalidateNameTag(RlvCommandOptionHelper::parseOption<LLUUID>(rlvCmd.getOption()));
return eRet;
LLUUID idOption;
if ( (rlvCmd.hasOption()) && (RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), idOption)) )
{
ERlvCmdRet eRet = RlvBehaviourGenericHandler<RLV_OPTION_EXCEPTION>::onCommand(rlvCmd, fRefCount);
if (RLV_RET_SUCCESS == eRet)
LLVOAvatar::invalidateNameTag(idOption);
fRefCount = false;
return eRet;
}
return RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_MODIFIER>::onCommand(rlvCmd, fRefCount);
}
// Handles: @shownearby=n|y toggles
@ -2671,6 +2689,26 @@ void RlvBehaviourShowSelfToggleHandler::onCommandToggle(ERlvBehaviour eBvhr, boo
gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
}
// Handles: @viewtransparent toggles
template<> template<>
void RlvBehaviourToggleHandler<RLV_BHVR_VIEWTRANSPARENT>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
{
if (fHasBhvr)
{
LLDrawPoolAlpha::sShowDebugAlpha = false;
}
}
// Handles: @viewwireframe toggles
template<> template<>
void RlvBehaviourToggleHandler<RLV_BHVR_VIEWWIREFRAME>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
{
if (fHasBhvr)
{
set_use_wireframe(false);
}
}
// ============================================================================
// Command handlers (RLV_TYPE_FORCE)
//
@ -2691,7 +2729,7 @@ ERlvCmdRet RlvForceGenericHandler<RLV_OPTION_MODIFIER>::onCommand(const RlvComma
// There should be an option and it should specify a valid modifier (RlvBehaviourModifier performs the appropriate type checks)
RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(rlvCmd.getBehaviourType());
RlvBehaviourModifierValue modValue;
if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), modValue)) )
if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), pBhvrModifier->getType(), modValue)) )
return RLV_RET_FAILED_OPTION;
pBhvrModifier->setValue(modValue, rlvCmd.getObjectID());
@ -3046,6 +3084,14 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SETCAM_MODE>::onCommand(const RlvCommand& rl
template<> template<>
ERlvCmdRet RlvForceHandler<RLV_BHVR_SETOVERLAY_TWEEN>::onCommand(const RlvCommand& rlvCmd)
{
RlvObject* pRlvObj = gRlvHandler.getObject(rlvCmd.getObjectID());
if (!pRlvObj)
return RLV_RET_FAILED_NOBEHAVIOUR;
RlvOverlayEffect* pOverlayEffect = LLVfxManager::instance().getEffect<RlvOverlayEffect>(rlvCmd.getObjectID());
if (!pOverlayEffect)
return RLV_RET_FAILED_LOCK;
std::vector<std::string> optionList;
if ( (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) || (3 != optionList.size()) )
return RLV_RET_FAILED_OPTION;
@ -3058,12 +3104,18 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SETOVERLAY_TWEEN>::onCommand(const RlvComman
// Process the overlay alpha tween (if there is one and it is a valid value)
float overlayAlpha = .0f;
if (RlvCommandOptionHelper::parseOption(optionList[0], overlayAlpha))
RlvBehaviourModifierAnimator::instance().addTween(rlvCmd.getObjectID(), RLV_MODIFIER_OVERLAY_ALPHA, RlvBehaviourModifierAnimationType::Lerp, overlayAlpha, tweenDuration);
{
pOverlayEffect->tweenAlpha(overlayAlpha, tweenDuration);
pRlvObj->setModifierValue(ERlvLocalBhvrModifier::OverlayAlpha, overlayAlpha);
}
// Process the overlay tint tween (if there is one and it is a valid value)
LLVector3 overlayColor;
if (RlvCommandOptionHelper::parseOption(optionList[1], overlayColor))
RlvBehaviourModifierAnimator::instance().addTween(rlvCmd.getObjectID(), RLV_MODIFIER_OVERLAY_TINT, RlvBehaviourModifierAnimationType::Lerp, overlayColor, tweenDuration);
{
pOverlayEffect->tweenColor(LLColor3(overlayColor.mV), tweenDuration);
pRlvObj->setModifierValue(ERlvLocalBhvrModifier::OverlayTint, overlayColor);
}
return RLV_RET_SUCCESS;
}
@ -3851,76 +3903,4 @@ ERlvCmdRet RlvHandler::onGetPath(const RlvCommand& rlvCmd, std::string& strReply
// Command specific helper functions - @setoverlay
//
void RlvHandler::clearOverlayImage()
{
if (m_pOverlayImage)
{
m_pOverlayImage->setBoostLevel(m_nOverlayOrigBoost);
m_pOverlayImage = nullptr;
}
}
bool RlvHandler::hitTestOverlay(const LLCoordGL& ptMouse) const
{
if (!m_pOverlayImage)
return false;
RlvBehaviourModifier* pTouchModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TOUCH);
return (pTouchModifier) && (pTouchModifier->hasValue()) && (pTouchModifier->getValue<bool>()) &&
(m_pOverlayImage->getMask(LLVector2((float)ptMouse.mX / gViewerWindow->getWorldViewWidthScaled(), (float)ptMouse.mY / gViewerWindow->getWorldViewHeightScaled())));
}
void RlvHandler::renderOverlay()
{
if ( (hasBehaviour(RLV_BHVR_SETOVERLAY)) && (m_pOverlayImage) )
{
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.bind();
}
int nWidth = gViewerWindow->getWorldViewWidthScaled();
int nHeight = gViewerWindow->getWorldViewHeightScaled();
m_pOverlayImage->addTextureStats(nWidth * nHeight);
m_pOverlayImage->setKnownDrawSize(nWidth, nHeight);
gGL.pushMatrix();
LLGLSUIDefault glsUI;
gViewerWindow->setup2DRender();
const LLVector2& displayScale = gViewerWindow->getDisplayScale();
gGL.scalef(displayScale.mV[VX], displayScale.mV[VY], 1.f);
gGL.getTexUnit(0)->bind(m_pOverlayImage);
const LLVector3 overlayTint = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TINT)->getValue<LLVector3>();
gGL.color4f(overlayTint.mV[0], overlayTint.mV[1], overlayTint.mV[2], llclamp(RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_ALPHA)->getValue<float>(), 0.0f, 1.0f));
gl_rect_2d_simple_tex(nWidth, nHeight);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.popMatrix();
gGL.flush();
gViewerWindow->setup3DRender();
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.unbind();
}
}
}
void RlvHandler::setOverlayImage(const LLUUID& idTexture)
{
if ( (m_pOverlayImage) && (m_pOverlayImage->getID() == idTexture) )
return;
clearOverlayImage();
m_pOverlayImage = LLViewerTextureManager::getFetchedTexture(idTexture, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
m_nOverlayOrigBoost = m_pOverlayImage->getBoostLevel();
m_pOverlayImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
m_pOverlayImage->forceToSaveRawImage(0);
}
// ============================================================================

View File

@ -23,13 +23,9 @@
#include "rlvcommon.h"
#include "rlvhelper.h"
// ============================================================================
// Forward declarations
//
class LLViewerFetchedTexture;
// ============================================================================
// RlvHandler class
//
class RlvHandler : public LLOldEvents::LLSimpleListener, public LLParticularGroupObserver
{
@ -56,6 +52,8 @@ public:
public:
// Returns a list of all objects containing the specified behaviour
bool findBehaviour(ERlvBehaviour eBhvr, std::list<const RlvObject*>& lObjects) const;
// Returns a pointer to an RLV object instance (DO NOT STORE THIS!)
RlvObject* getObject(const LLUUID& idRlvObj) const;
// Returns TRUE is at least one object contains the specified behaviour (and optional option)
bool hasBehaviour(ERlvBehaviour eBhvr) const { return (eBhvr < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBhvr]) : false; }
bool hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const;
@ -123,9 +121,7 @@ public:
// Command specific helper functions
bool filterChat(std::string& strUTF8Text, bool fFilterEmote) const; // @sendchat, @recvchat and @redirchat
bool hitTestOverlay(const LLCoordGL& ptMouse) const; // @setoverlay
bool redirectChatOrEmote(const std::string& strUTF8Test) const; // @redirchat and @rediremote
void renderOverlay(); // @setoverlay
// Command processing helper functions
ERlvCmdRet processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj);
@ -144,11 +140,9 @@ public:
protected:
// Command specific helper functions (NOTE: these generally do not perform safety checks)
bool checkActiveGroupThrottle(const LLUUID& idRlvObj); // @setgroup=force
void clearOverlayImage(); // @setoverlay=n
void setActiveGroup(const LLUUID& idGroup); // @setgroup=force
void setActiveGroupRole(const LLUUID& idGroup, const std::string& strRole); // @setgroup=force
void setCameraOverride(bool fOverride); // @setcam family
void setOverlayImage(const LLUUID& idTexture); // @setoverlay=n
void onIMQueryListResponse(const LLSD& sdNotification, const LLSD sdResponse);
@ -275,8 +269,6 @@ protected:
mutable LLUUID m_idAgentGroup; // @setgroup=n
std::pair<LLUUID, std::string> m_PendingGroupChange; // @setgroup=force
std::pair<LLTimer, LLUUID> m_GroupChangeExpiration; // @setgroup=force
LLPointer<LLViewerFetchedTexture> m_pOverlayImage = nullptr; // @setoverlay=n
int m_nOverlayOrigBoost = 0; // @setoverlay=n
std::string m_strCameraPresetRestore; // @setcam_eyeoffset, @setcam_eyeoffsetscale and @setcam_focusoffset
@ -313,6 +305,12 @@ inline RlvHandler* RlvHandler::getInstance()
return &gRlvHandler;
}
inline RlvObject* RlvHandler::getObject(const LLUUID& idRlvObj) const
{
auto itObj = m_Objects.find(idRlvObj);
return (m_Objects.end() != itObj) ? const_cast<RlvObject*>(&itObj->second) : nullptr;
}
inline bool RlvHandler::hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const
{
return hasBehaviourExcept(eBhvr, strOption, LLUUID::null);

View File

@ -26,6 +26,7 @@
//</FS:TS> FIRE-4453
#include "rlvcommon.h"
#include "rlveffects.h"
#include "rlvhelper.h"
#include "rlvhandler.h"
#include "rlvinventory.h"
@ -104,6 +105,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addEntry(new RlvBehaviourInfo("detachallthis_except", RLV_BHVR_DETACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE));
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_EDIT, RLV_OPTION_NONE_OR_EXCEPTION>("edit"));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_EXCEPTION>("editobj", RLV_BHVR_EDITOBJ));
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_VIEWTRANSPARENT, RLV_OPTION_NONE>("viewtransparent", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_VIEWWIREFRAME, RLV_OPTION_NONE>("viewwireframe", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("emote", RLV_BHVR_EMOTE));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_MODIFIER>("fartouch", RLV_BHVR_FARTOUCH));
addModifier(RLV_BHVR_FARTOUCH, RLV_MODIFIER_FARTOUCHDIST, new RlvBehaviourModifier("Fartouch Distance", RLV_MODIFIER_FARTOUCH_DEFAULT, true, new RlvBehaviourModifierCompMin));
@ -147,7 +150,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("showloc", RLV_BHVR_SHOWLOC));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("showminimap", RLV_BHVR_SHOWMINIMAP));
addEntry(new RlvBehaviourToggleProcessor<RLV_BHVR_SHOWNAMES>("shownames", RlvBehaviourInfo::BHVR_STRICT));
addEntry(new RlvBehaviourToggleProcessor<RLV_BHVR_SHOWNAMETAGS>("shownametags", RlvBehaviourInfo::BHVR_STRICT ));
addEntry(new RlvBehaviourProcessor<RLV_BHVR_SHOWNAMETAGS>("shownametags", RlvBehaviourInfo::BHVR_STRICT));
addModifier(RLV_BHVR_SHOWNAMETAGS, RLV_MODIFIER_SHOWNAMETAGSDIST, new RlvBehaviourModifierHandler<RLV_MODIFIER_SHOWNAMETAGSDIST>("Name Tags - Visible Distance", 0.0f, true, new RlvBehaviourModifierCompMin));
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SHOWNEARBY, RLV_OPTION_NONE>("shownearby", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SHOWSELF, RLV_OPTION_NONE, RlvBehaviourShowSelfToggleHandler>("showself", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SHOWSELFHEAD, RLV_OPTION_NONE, RlvBehaviourShowSelfToggleHandler>("showselfhead", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
@ -219,17 +223,28 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETCAM_UNLOCK, RLV_OPTION_NONE>("camunlock", RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));
// Overlay
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETOVERLAY, RLV_OPTION_NONE>("setoverlay", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addModifier(new RlvForceGenericProcessor<RLV_OPTION_MODIFIER>("setoverlay_alpha", RLV_BHVR_SETOVERLAY_ALPHA, RlvBehaviourInfo::BHVR_EXPERIMENTAL),
RLV_MODIFIER_OVERLAY_ALPHA, new RlvBehaviourModifier("Overlay - Alpha", 1.0f, false, new RlvBehaviourModifierComp()));
addModifier(new RlvForceGenericProcessor<RLV_OPTION_MODIFIER>("setoverlay_texture", RLV_BHVR_SETOVERLAY_TEXTURE, RlvBehaviourInfo::BHVR_EXPERIMENTAL),
RLV_MODIFIER_OVERLAY_TEXTURE, new RlvBehaviourModifierHandler<RLV_MODIFIER_OVERLAY_TEXTURE>("Overlay - Texture", LLUUID::null, false, new RlvBehaviourModifierComp()));
addModifier(new RlvForceGenericProcessor<RLV_OPTION_MODIFIER>("setoverlay_tint", RLV_BHVR_SETOVERLAY_TINT, RlvBehaviourInfo::BHVR_EXPERIMENTAL),
RLV_MODIFIER_OVERLAY_TINT, new RlvBehaviourModifier("Overlay - Tint", LLVector3(1.0f, 1.0f, 1.0f), false, new RlvBehaviourModifierComp()));
addModifier(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_MODIFIER>("setoverlay_touch", RLV_BHVR_SETOVERLAY_TOUCH, RlvBehaviourInfo::BHVR_EXPERIMENTAL),
RLV_MODIFIER_OVERLAY_TOUCH, new RlvBehaviourModifier("Overlay - Touch", true, true, new RlvBehaviourModifierComp()));
RlvBehaviourInfo* pSetOverlayBhvr = new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETOVERLAY, RLV_OPTION_NONE_OR_MODIFIER>("setoverlay");
pSetOverlayBhvr->addModifier(ERlvLocalBhvrModifier::OverlayAlpha, typeid(float), "alpha", &RlvOverlayEffect::onAlphaValueChanged);
pSetOverlayBhvr->addModifier(ERlvLocalBhvrModifier::OverlayTexture, typeid(LLUUID), "texture", &RlvOverlayEffect::onTextureChanged);
pSetOverlayBhvr->addModifier(ERlvLocalBhvrModifier::OverlayTint, typeid(LLVector3), "tint", &RlvOverlayEffect::onColorValueChanged);
pSetOverlayBhvr->addModifier(ERlvLocalBhvrModifier::OverlayTouch, typeid(LLVector3), "touch", &RlvOverlayEffect::onBlockTouchValueChanged);
addEntry(pSetOverlayBhvr);
addEntry(new RlvForceProcessor<RLV_BHVR_SETOVERLAY_TWEEN>("setoverlay_tween", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
// Sphere
RlvBehaviourInfo* pSetSphereBhvr = new RlvBehaviourProcessor<RLV_BHVR_SETSPHERE>("setsphere", RlvBehaviourInfo::BHVR_EXPERIMENTAL);
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereMode, typeid(int), "mode", &RlvSphereEffect::onModeChanged);
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereOrigin, typeid(int), "origin", &RlvSphereEffect::onOriginChanged);
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereColor, typeid(LLVector3), "color", &RlvSphereEffect::onColorChanged);
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereDistMin, typeid(float), "distmin", &RlvSphereEffect::onDistMinChanged);
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereDistMax, typeid(float), "distmax", &RlvSphereEffect::onDistMaxChanged);
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereDistExtend, typeid(int), "distextend", &RlvSphereEffect::onDistExtendChanged);
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereParams, typeid(LLVector4), "param", &RlvSphereEffect::onParamsChanged);
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereTween, typeid(float), "tween", &RlvSphereEffect::onTweenDurationChanged);
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereValueMin, typeid(float), "valuemin", &RlvSphereEffect::onValueMinChanged);
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereValueMax, typeid(float), "valuemax", &RlvSphereEffect::onValueMaxChanged);
addEntry(pSetSphereBhvr);
//
// Force-wear
//
@ -398,20 +413,50 @@ void RlvBehaviourDictionary::clearModifiers(const LLUUID& idRlvObj)
}
}
const RlvBehaviourInfo* RlvBehaviourDictionary::getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict) const
const RlvBehaviourInfo* RlvBehaviourDictionary::getBehaviourInfo(ERlvBehaviour eBhvr, ERlvParamType eParamType) const
{
bool fStrict = boost::algorithm::ends_with(strBhvr, "_sec");
const RlvBehaviourInfo* pBhvrInfo = nullptr;
for (auto itBhvrLower = m_Bhvr2InfoMap.lower_bound(eBhvr), itBhvrUpper = m_Bhvr2InfoMap.upper_bound(eBhvr);
std::find_if(itBhvrLower, itBhvrUpper, [eParamType](const rlv_bhvr2info_map_t::value_type& bhvrEntry) { return bhvrEntry.second->getParamTypeMask() == eParamType; }) != itBhvrUpper;
++itBhvrLower)
{
if (pBhvrInfo)
return nullptr;
pBhvrInfo = itBhvrLower->second;
}
return pBhvrInfo;
}
const RlvBehaviourInfo* RlvBehaviourDictionary::getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict, ERlvLocalBhvrModifier* peBhvrModifier) const
{
size_t idxBhvrLastPart = strBhvr.find_last_of('_');
std::string strBhvrLastPart((std::string::npos != idxBhvrLastPart) && (idxBhvrLastPart < strBhvr.size()) ? strBhvr.substr(idxBhvrLastPart + 1) : LLStringUtil::null);
bool fStrict = (strBhvrLastPart.compare("sec") == 0);
if (pfStrict)
*pfStrict = fStrict;
ERlvLocalBhvrModifier eBhvrModifier = ERlvLocalBhvrModifier::Unknown;
rlv_string2info_map_t::const_iterator itBhvr = m_String2InfoMap.find(std::make_pair( (!fStrict) ? strBhvr : strBhvr.substr(0, strBhvr.size() - 4), (eParamType & RLV_TYPE_ADDREM) ? RLV_TYPE_ADDREM : eParamType));
return ( (itBhvr != m_String2InfoMap.end()) && ((!fStrict) || (itBhvr->second->hasStrict())) ) ? itBhvr->second : NULL;
if ( (m_String2InfoMap.end() == itBhvr) && (!fStrict) && (!strBhvrLastPart.empty()) && (RLV_TYPE_FORCE == eParamType) )
{
// No match found but it could still be a local scope modifier
auto itBhvrMod = m_String2InfoMap.find(std::make_pair(strBhvr.substr(0, idxBhvrLastPart), RLV_TYPE_ADDREM));
if ( (m_String2InfoMap.end() != itBhvrMod) && (eBhvrModifier = itBhvrMod->second->lookupBehaviourModifier(strBhvrLastPart)) != ERlvLocalBhvrModifier::Unknown)
itBhvr = itBhvrMod;
}
if (peBhvrModifier)
*peBhvrModifier = eBhvrModifier;
return ( (itBhvr != m_String2InfoMap.end()) && ((!fStrict) || (itBhvr->second->hasStrict())) ) ? itBhvr->second : nullptr;
}
ERlvBehaviour RlvBehaviourDictionary::getBehaviourFromString(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict) const
{
const RlvBehaviourInfo* pBhvrInfo = getBehaviourInfo(strBhvr, eParamType, pfStrict);
return (pBhvrInfo) ? pBhvrInfo->getBehaviourType() : RLV_BHVR_UNKNOWN;
ERlvLocalBhvrModifier eBhvrModifier;
const RlvBehaviourInfo* pBhvrInfo = getBehaviourInfo(strBhvr, eParamType, pfStrict, &eBhvrModifier);
// Filter out locally scoped modifier commands since they don't actually have a unique behaviour value of their own
return (pBhvrInfo && ERlvLocalBhvrModifier::Unknown == eBhvrModifier) ? pBhvrInfo->getBehaviourType() : RLV_BHVR_UNKNOWN;
}
bool RlvBehaviourDictionary::getCommands(const std::string& strMatch, ERlvParamType eParamType, std::list<std::string>& cmdList) const
@ -460,6 +505,42 @@ void RlvBehaviourDictionary::toggleBehaviourFlag(const std::string& strBhvr, ERl
}
}
// ============================================================================
// RlvBehaviourInfo
//
// virtual
ERlvCmdRet RlvBehaviourInfo::processModifier(const RlvCommand& rlvCmd) const
{
// The object should have the base behaviour set (or else there's nothing to modify)
if (!gRlvHandler.hasBehaviour(rlvCmd.getObjectID(), rlvCmd.getBehaviourType()))
return RLV_RET_FAILED_UNHELDBEHAVIOUR;
auto itBhvrModifier = std::find_if(m_BhvrModifiers.begin(), m_BhvrModifiers.end(), [&rlvCmd](const modifier_lookup_t::value_type& entry) { return std::get<0>(entry.second) == rlvCmd.getBehaviourModifier(); });
if (m_BhvrModifiers.end() == itBhvrModifier)
return RLV_RET_FAILED_UNKNOWN;
ERlvCmdRet eCmdRet; const modifier_handler_func_t& fnHandler = std::get<2>(itBhvrModifier->second);
if (rlvCmd.hasOption())
{
// If there's an option parse it (and perform type checking)
RlvBehaviourModifierValue modValue;
if ( (rlvCmd.hasOption()) && (!RlvBehaviourModifier::convertOptionValue(rlvCmd.getOption(), std::get<1>(itBhvrModifier->second), modValue)) )
return RLV_RET_FAILED_OPTION;
eCmdRet = (fnHandler) ? fnHandler(rlvCmd.getObjectID(), modValue) : RLV_RET_SUCCESS;
if (RLV_RET_SUCCESS == eCmdRet)
gRlvHandler.getObject(rlvCmd.getObjectID())->setModifierValue(rlvCmd.getBehaviourModifier(), modValue);
}
else
{
eCmdRet = (fnHandler) ? fnHandler(rlvCmd.getObjectID(), boost::none) : RLV_RET_SUCCESS;
if (RLV_RET_SUCCESS == eCmdRet)
gRlvHandler.getObject(rlvCmd.getObjectID())->clearModifierValue(rlvCmd.getBehaviourModifier());
}
return eCmdRet;
}
// ============================================================================
// RlvBehaviourModifier
//
@ -499,7 +580,6 @@ void RlvBehaviourModifier::clearValues(const LLUUID& idRlvObj)
[&idRlvObj](const RlvBehaviourModifierValueTuple& modValue) {
return (std::get<1>(modValue) == idRlvObj) && (std::get<2>(modValue) == RLV_BHVR_UNKNOWN);
}), m_Values.end());
RlvBehaviourModifierAnimator::instance().clearTweens(idRlvObj);
if (origCount != m_Values.size())
{
onValueChange();
@ -574,21 +654,22 @@ void RlvBehaviourModifier::setValue(const RlvBehaviourModifierValue& modValue, c
}
}
bool RlvBehaviourModifier::convertOptionValue(const std::string& optionValue, RlvBehaviourModifierValue& modValue) const
// static
bool RlvBehaviourModifier::convertOptionValue(const std::string& optionValue, const std::type_index& modType, RlvBehaviourModifierValue& modValue)
{
try
{
if (typeid(float) == m_DefaultValue.type())
if (modType == typeid(float))
{
modValue = std::stof(optionValue);
return true;
}
else if (typeid(int) == m_DefaultValue.type())
else if (modType == typeid(int))
{
modValue = std::stoi(optionValue);
return true;
}
else if (typeid(LLVector3) == m_DefaultValue.type())
else if (modType == typeid(LLVector3))
{
LLVector3 vecOption;
if (3 == sscanf(optionValue.c_str(), "%f/%f/%f", vecOption.mV + 0, vecOption.mV + 1, vecOption.mV + 2))
@ -597,7 +678,16 @@ bool RlvBehaviourModifier::convertOptionValue(const std::string& optionValue, Rl
return true;
}
}
else if (typeid(LLUUID) == m_DefaultValue.type())
else if (modType == typeid(LLVector4))
{
LLVector4 vecOption;
if (4 == sscanf(optionValue.c_str(), "%f/%f/%f/%f", vecOption.mV + 0, vecOption.mV + 1, vecOption.mV + 2, vecOption.mV + 3))
{
modValue = vecOption;
return true;
}
}
else if (modType == typeid(LLUUID))
{
LLUUID idOption;
if (LLUUID::parseUUID(optionValue, &idOption))
@ -619,7 +709,7 @@ bool RlvBehaviourModifier::convertOptionValue(const std::string& optionValue, Rl
//
RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand)
: m_fValid(false), m_idObj(idObj), m_pBhvrInfo(NULL), m_eParamType(RLV_TYPE_UNKNOWN), m_fStrict(false), m_fRefCounted(false)
: m_idObj(idObj)
{
if ((m_fValid = parseCommand(strCommand, m_strBehaviour, m_strOption, m_strParam)))
{
@ -647,13 +737,13 @@ RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand)
return;
}
m_pBhvrInfo = RlvBehaviourDictionary::instance().getBehaviourInfo(m_strBehaviour, m_eParamType, &m_fStrict);
m_pBhvrInfo = RlvBehaviourDictionary::instance().getBehaviourInfo(m_strBehaviour, m_eParamType, &m_fStrict, &m_eBhvrModifier);
}
RlvCommand::RlvCommand(const RlvCommand& rlvCmd, ERlvParamType eParamType)
: m_fValid(rlvCmd.m_fValid), m_idObj(rlvCmd.m_idObj), m_strBehaviour(rlvCmd.m_strBehaviour), m_pBhvrInfo(rlvCmd.m_pBhvrInfo)
, m_eParamType( (RLV_TYPE_UNKNOWN == eParamType) ? rlvCmd.m_eParamType : eParamType),m_fStrict(rlvCmd.m_fStrict), m_strOption(rlvCmd.m_strOption)
, m_strParam(rlvCmd.m_strParam), m_fRefCounted(rlvCmd.m_fRefCounted)
, m_eParamType( (RLV_TYPE_UNKNOWN == eParamType) ? rlvCmd.m_eParamType : eParamType), m_eBhvrModifier(rlvCmd.m_eBhvrModifier)
, m_fStrict(rlvCmd.m_fStrict), m_strOption(rlvCmd.m_strOption), m_strParam(rlvCmd.m_strParam), m_fRefCounted(rlvCmd.m_fRefCounted)
{
}
@ -1107,6 +1197,31 @@ std::string RlvObject::getStatusString(const std::string& strFilter, const std::
return strStatus;
}
void RlvObject::clearModifiers(ERlvBehaviour eBhvr)
{
if (const RlvBehaviourInfo* pBhvrInfo = RlvBehaviourDictionary::instance().getBehaviourInfo(eBhvr, RLV_TYPE_ADDREM))
{
for (const auto& modifierEntry : pBhvrInfo->getModifiers())
{
clearModifierValue(std::get<0>(modifierEntry.second));
}
}
}
void RlvObject::clearModifierValue(ERlvLocalBhvrModifier eBhvrModifier)
{
m_Modifiers.erase(eBhvrModifier);
}
void RlvObject::setModifierValue(ERlvLocalBhvrModifier eBhvrModifier, const RlvBehaviourModifierValue& newValue)
{
auto itBhvrModifierValue = m_Modifiers.find(eBhvrModifier);
if (m_Modifiers.end() != itBhvrModifierValue)
itBhvrModifierValue->second = newValue;
else
m_Modifiers.insert(std::make_pair(eBhvrModifier, newValue));
}
// ============================================================================
// RlvForceWear
//

View File

@ -38,7 +38,10 @@ struct RlvBehaviourModifierComp;
class RlvBehaviourInfo
{
typedef std::function<ERlvCmdRet(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue>)> modifier_handler_func_t;
public:
typedef std::map<std::string, std::tuple<ERlvLocalBhvrModifier, std::type_index, modifier_handler_func_t>> modifier_lookup_t;
enum EBehaviourFlags
{
// General behaviour flags
@ -65,24 +68,29 @@ public:
: m_strBhvr(strBhvr), m_eBhvr(eBhvr), m_maskParamType(maskParamType), m_nBhvrFlags(nBhvrFlags) {}
virtual ~RlvBehaviourInfo() {}
const std::string& getBehaviour() const { return m_strBhvr; }
ERlvBehaviour getBehaviourType() const { return m_eBhvr; }
U32 getBehaviourFlags() const { return m_nBhvrFlags; }
U32 getParamTypeMask() const { return m_maskParamType; }
bool hasStrict() const { return m_nBhvrFlags & BHVR_STRICT; }
bool isBlocked() const { return m_nBhvrFlags & BHVR_BLOCKED; }
bool isExperimental() const { return m_nBhvrFlags & BHVR_EXPERIMENTAL; }
bool isExtended() const { return m_nBhvrFlags & BHVR_EXTENDED; }
bool isSynonym() const { return m_nBhvrFlags & BHVR_SYNONYM; }
void toggleBehaviourFlag(EBehaviourFlags eBhvrFlag, bool fEnable);
void addModifier(ERlvLocalBhvrModifier eBhvrMod, const std::type_info& valueType, const std::string& strBhvrMod, modifier_handler_func_t fnHandler = nullptr);
const std::string& getBehaviour() const { return m_strBhvr; }
ERlvBehaviour getBehaviourType() const { return m_eBhvr; }
U32 getBehaviourFlags() const { return m_nBhvrFlags; }
U32 getParamTypeMask() const { return m_maskParamType; }
const modifier_lookup_t& getModifiers() const { return m_BhvrModifiers; }
bool hasStrict() const { return m_nBhvrFlags & BHVR_STRICT; }
bool isBlocked() const { return m_nBhvrFlags & BHVR_BLOCKED; }
bool isExperimental() const { return m_nBhvrFlags & BHVR_EXPERIMENTAL; }
bool isExtended() const { return m_nBhvrFlags & BHVR_EXTENDED; }
bool isSynonym() const { return m_nBhvrFlags & BHVR_SYNONYM; }
ERlvLocalBhvrModifier lookupBehaviourModifier(const std::string& strBhvrMod) const;
void toggleBehaviourFlag(EBehaviourFlags eBhvrFlag, bool fEnable);
virtual ERlvCmdRet processCommand(const RlvCommand& rlvCmd) const { return RLV_RET_NO_PROCESSOR; }
virtual ERlvCmdRet processModifier(const RlvCommand& rlvCmd) const;
protected:
std::string m_strBhvr;
ERlvBehaviour m_eBhvr;
U32 m_nBhvrFlags;
U32 m_maskParamType;
modifier_lookup_t m_BhvrModifiers;
};
// ============================================================================
@ -106,7 +114,8 @@ public:
public:
void clearModifiers(const LLUUID& idRlvObj);
ERlvBehaviour getBehaviourFromString(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict = NULL) const;
const RlvBehaviourInfo* getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict = NULL) const;
const RlvBehaviourInfo* getBehaviourInfo(ERlvBehaviour eBhvr, ERlvParamType eParamType) const;
const RlvBehaviourInfo* getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict = nullptr, ERlvLocalBhvrModifier* peBhvrModifier = nullptr) const;
bool getCommands(const std::string& strMatch, ERlvParamType eParamType, std::list<std::string>& cmdList) const;
bool getHasStrict(ERlvBehaviour eBhvr) const;
RlvBehaviourModifier* getModifier(ERlvBehaviourModifier eBhvrMod) const { return (eBhvrMod < RLV_MODIFIER_COUNT) ? m_BehaviourModifiers[eBhvrMod] : nullptr; }
@ -244,12 +253,13 @@ protected:
virtual void onValueChange() const {}
public:
bool addValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj, ERlvBehaviour eBhvr = RLV_BHVR_UNKNOWN);
bool convertOptionValue(const std::string& optionValue, RlvBehaviourModifierValue& modValue) const;
static bool convertOptionValue(const std::string& optionValue, const std::type_index& modType, RlvBehaviourModifierValue& modValue);
void clearValues(const LLUUID& idRlvObj);
bool getAddDefault() const { return m_fAddDefaultOnEmpty; }
const RlvBehaviourModifierValue& getDefaultValue() const { return m_DefaultValue; }
const LLUUID& getPrimaryObject() const;
const std::string& getName() const { return m_strName; }
const std::type_info& getType() const { return m_DefaultValue.type(); }
const RlvBehaviourModifierValue& getValue() const { return (hasValue()) ? std::get<0>(m_Values.front()) : m_DefaultValue; }
template<typename T> const T& getValue() const { return boost::get<T>(getValue()); }
bool hasValue() const;
@ -289,14 +299,17 @@ public:
public:
std::string asString() const;
const std::string& getBehaviour() const { return m_strBehaviour; }
const RlvBehaviourInfo* getBehaviourInfo() const { return m_pBhvrInfo; }
ERlvBehaviour getBehaviourType() const { return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviourType() : RLV_BHVR_UNKNOWN; }
U32 getBehaviourFlags() const{ return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviourFlags() : 0; }
ERlvLocalBhvrModifier getBehaviourModifier() const { return m_eBhvrModifier; }
const LLUUID& getObjectID() const { return m_idObj; }
const std::string& getOption() const { return m_strOption; }
const std::string& getParam() const { return m_strParam; }
ERlvParamType getParamType() const { return m_eParamType; }
bool hasOption() const { return !m_strOption.empty(); }
bool isBlocked() const { return (m_pBhvrInfo) ? m_pBhvrInfo->isBlocked() : false; }
bool isModifier() const { return ERlvLocalBhvrModifier::Unknown != m_eBhvrModifier; }
bool isRefCounted() const { return m_fRefCounted; }
bool isStrict() const { return m_fStrict; }
bool isValid() const { return m_fValid; }
@ -316,15 +329,16 @@ public:
* Member variables
*/
protected:
bool m_fValid;
bool m_fValid = false;
LLUUID m_idObj;
std::string m_strBehaviour;
const RlvBehaviourInfo* m_pBhvrInfo;
ERlvParamType m_eParamType;
bool m_fStrict;
const RlvBehaviourInfo* m_pBhvrInfo = nullptr;
ERlvParamType m_eParamType = RLV_TYPE_UNKNOWN;
ERlvLocalBhvrModifier m_eBhvrModifier = ERlvLocalBhvrModifier::Unknown;
bool m_fStrict = false;
std::string m_strOption;
std::string m_strParam;
mutable bool m_fRefCounted;
mutable bool m_fRefCounted = false;
friend class RlvHandler;
friend class RlvObject;
@ -452,6 +466,15 @@ public:
bool hasLookup() const { return m_fLookup; }
const rlv_command_list_t& getCommandList() const { return m_Commands; }
/*
* Local-scope modifiers
*/
public:
void clearModifiers(ERlvBehaviour eBhvr);
void clearModifierValue(ERlvLocalBhvrModifier eBhvrMod);
template<typename T> bool getModifierValue(ERlvLocalBhvrModifier eBhvrModifier, T& value) const;
void setModifierValue(ERlvLocalBhvrModifier eBhvrMod, const RlvBehaviourModifierValue& modValue);
/*
* Member variables
*/
@ -462,6 +485,8 @@ protected:
bool m_fLookup; // TRUE if the object existed in gObjectList at one point in time
S16 m_nLookupMisses; // Count of unsuccessful lookups in gObjectList by the GC
rlv_command_list_t m_Commands; // List of behaviours held by this object (in the order they were received)
typedef std::map<ERlvLocalBhvrModifier, RlvBehaviourModifierValue> bhvr_modifier_map_t;
bhvr_modifier_map_t m_Modifiers; // List of (local scope) modifiers set on this object
friend class RlvHandler;
};
@ -668,6 +693,19 @@ std::string rlvGetLastParenthesisedText(const std::string& strText, std::string:
// Inlined class member functions
//
inline void RlvBehaviourInfo::addModifier(ERlvLocalBhvrModifier eBhvrMod, const std::type_info& valueType, const std::string& strBhvrMod, modifier_handler_func_t fnHandler)
{
RLV_ASSERT_DBG(m_BhvrModifiers.find(strBhvrMod) == m_BhvrModifiers.end());
m_BhvrModifiers.insert(std::make_pair(strBhvrMod, std::make_tuple(eBhvrMod, std::type_index(valueType), fnHandler)));
}
inline ERlvLocalBhvrModifier RlvBehaviourInfo::lookupBehaviourModifier(const std::string& strBhvrMod) const
{
auto itBhvrModifier = m_BhvrModifiers.find(strBhvrMod);
return (m_BhvrModifiers.end() != itBhvrModifier) ? std::get<0>(itBhvrModifier->second) : ERlvLocalBhvrModifier::Unknown;
}
inline void RlvBehaviourInfo::toggleBehaviourFlag(EBehaviourFlags eBhvrFlag, bool fEnable)
{
if (fEnable)
@ -692,6 +730,18 @@ inline bool RlvCommand::operator ==(const RlvCommand& rhs) const
( (RLV_TYPE_UNKNOWN != m_eParamType) ? (m_eParamType == rhs.m_eParamType) : (m_strParam == rhs.m_strParam) );
}
template <typename T>
inline bool RlvObject::getModifierValue(ERlvLocalBhvrModifier eBhvrModifier, T& value) const
{
auto itBhvrModifierValue = m_Modifiers.find(eBhvrModifier);
if (m_Modifiers.end() != itBhvrModifierValue)
{
value = boost::get<T>(itBhvrModifierValue->second);
return true;
}
return false;
}
// Checked: 2010-04-05 (RLVa-1.2.0d) | Modified: RLVa-1.2.0d
inline bool RlvForceWear::isWearableItem(const LLInventoryItem* pItem)
{

View File

@ -1,115 +0,0 @@
/**
*
* Copyright (c) 2009-2018, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
#include "llviewerprecompiledheaders.h"
#include "rlvmodifiers.h"
// ====================================================================================
// RlvBehaviourModifierAnimator
//
RlvBehaviourModifierAnimator::~RlvBehaviourModifierAnimator()
{
if (!m_TimerHandle.isDead())
m_TimerHandle.markDead();
}
void RlvBehaviourModifierAnimator::addTween(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod, RlvBehaviourModifierAnimationType eAnimType, const RlvBehaviourModifierValue& endValue, float nDuration)
{
// Make sure we don't run two animations on the same modifier for the same object
const auto itTween = std::find_if(m_Tweens.begin(), m_Tweens.end(), [&idObject, eBhvrMod](const RlvBehaviourModifierTween& t) { return t.idObject == idObject && t.eBhvrMod == eBhvrMod; });
if (m_Tweens.end() != itTween)
m_Tweens.erase(itTween);
if (const RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(eBhvrMod))
{
RlvBehaviourModifierTween newTween;
newTween.idObject = idObject;
newTween.eBhvrMod = eBhvrMod;
newTween.eAnimType = RlvBehaviourModifierAnimationType::Lerp;
newTween.nStartTime = LLTimer::getElapsedSeconds();
newTween.nDuration = nDuration;
newTween.startValue = pBhvrModifier->getValue();
newTween.endValue = endValue;
if (newTween.startValue.which() == newTween.endValue.which())
{
if (m_TimerHandle.isDead())
m_TimerHandle = (new AnimationTimer())->getHandle();
m_Tweens.emplace_back(std::move(newTween));
}
}
}
void RlvBehaviourModifierAnimator::clearTweens(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod)
{
m_Tweens.erase(std::remove_if(m_Tweens.begin(), m_Tweens.end(),
[&idObject, eBhvrMod](const RlvBehaviourModifierTween& cmpTween)
{
return cmpTween.idObject == idObject && ((cmpTween.eBhvrMod == eBhvrMod) || (RLV_MODIFIER_UNKNOWN == eBhvrMod));
}), m_Tweens.end());
}
// ====================================================================================
// RlvBehaviourModifierAnimator timer
//
RlvBehaviourModifierAnimator::AnimationTimer::AnimationTimer()
: LLEventTimer(1.f / RLV_MODIFIER_ANIMATION_FREQUENCY)
{
}
BOOL RlvBehaviourModifierAnimator::AnimationTimer::tick()
{
RlvBehaviourModifierAnimator& modAnimatior = RlvBehaviourModifierAnimator::instance();
const double curTime = LLTimer::getElapsedSeconds();
const auto activeTweens = modAnimatior.m_Tweens;
for (const auto& curTween : activeTweens)
{
if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(curTween.eBhvrMod))
{
// Update the modifier's value
float curFactor = (curTime - curTween.nStartTime) / curTween.nDuration;
if (curFactor < 1.0)
{
const auto& valueType = curTween.startValue.type();
if (typeid(float) == valueType)
pBhvrModifier->setValue(lerp(boost::get<float>(curTween.startValue), boost::get<float>(curTween.endValue), curFactor), curTween.idObject);
else if (typeid(int) == valueType)
pBhvrModifier->setValue(lerp(boost::get<int>(curTween.startValue), boost::get<int>(curTween.endValue), curFactor), curTween.idObject);
else if (typeid(LLVector3) == valueType)
pBhvrModifier->setValue(lerp(boost::get<LLVector3>(curTween.startValue), boost::get<LLVector3>(curTween.endValue), curFactor), curTween.idObject);
}
else
{
pBhvrModifier->setValue(curTween.endValue, curTween.idObject);
auto itTween = std::find_if(modAnimatior.m_Tweens.begin(), modAnimatior.m_Tweens.end(),
[&curTween](const RlvBehaviourModifierTween& t)
{
// NOTE: implementation leak - taking advantage of the fact that we know there can only be one active tween per object/modifier/type combination
return t.idObject == curTween.idObject && t.eBhvrMod == curTween.eBhvrMod && t.eAnimType == curTween.eAnimType;
});
modAnimatior.m_Tweens.erase(itTween);
}
}
}
return modAnimatior.m_Tweens.empty();
}
// ====================================================================================

View File

@ -73,56 +73,6 @@ struct RlvBehaviourModifierCompMax : public RlvBehaviourModifierComp
}
};
// ====================================================================================
// RlvBehaviourModifierAnimator - A class to animate behaviour modifiers
//
enum class RlvBehaviourModifierAnimationType { Lerp };
struct RlvBehaviourModifierTween
{
LLUUID idObject;
ERlvBehaviourModifier eBhvrMod;
RlvBehaviourModifierAnimationType eAnimType;
double nStartTime;
float nDuration;
RlvBehaviourModifierValue startValue;
RlvBehaviourModifierValue endValue;
};
class RlvBehaviourModifierAnimator : public LLSingleton<RlvBehaviourModifierAnimator>
{
LLSINGLETON_EMPTY_CTOR(RlvBehaviourModifierAnimator);
public:
~RlvBehaviourModifierAnimator();
/*
* Member functions
*/
public:
void addTween(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod, RlvBehaviourModifierAnimationType eAnimType, const RlvBehaviourModifierValue& endValue, float nDuration);
void clearTweens(const LLUUID& idObject) { clearTweens(idObject, RLV_MODIFIER_UNKNOWN); }
void clearTweens(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod);
/*
* Animation timer
*/
protected:
class AnimationTimer : public LLEventTimer, public LLHandleProvider<AnimationTimer>
{
public:
AnimationTimer();
BOOL tick() override;
};
/*
* Member variables
*/
protected:
LLHandle<AnimationTimer> m_TimerHandle;
std::list< RlvBehaviourModifierTween> m_Tweens;
};
// ====================================================================================
// RlvCachedBehaviourModifier - Provides an optimized way to access a modifier that's frequently accessed and rarely updated
//

View File

@ -68,7 +68,7 @@ Fejl detaljer: Beskeden kaldet &apos;[_NAME]&apos; blev ikke fundet i notificati
<usetemplate name="okcancelbuttons" notext="Annullér" yestext="Ja"/>
</notification>
<notification name="BadInstallation">
Der opstod en fejl ved opdatering af [APP_NAME]. Please [http://get.secondlife.com download the latest version] of the Viewer.
Der opstod en fejl ved opdatering af [APP_NAME]. Please [https://www.firestormviewer.org/downloads download the latest version] of the Viewer.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LoginFailedNoNetwork">

View File

@ -34,5 +34,7 @@
</fs_scroll_list>
<button name="remove_btn" label="Ausgewählte Objekte entfernen" width="210"/>
<button name="remove_temp_btn" label="Alle Temporären entfernen" width="180"/>
<button name="play_btn" label="Sound abspielen" tool_tip="Spielt den selektierten Sound; nur ein einzelner Eintrag kann zur Wiedergabe ausgewählt werden." width="120"/>
<button name="stop_btn" label="Sound stoppen" tool_tip="Stoppt die Wiedergabe des aktuell abgespielten Sounds." width="120"/>
<button name="close_btn" label="Schließen"/>
</floater>

View File

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
<menu_item_call label="Gruppeninformation anzeigen" name="show_group"/>
<menu_item_call label="Hole Gruppen-Daten, bitte erneut versuchen!" name="waiting_for_group_data"/>
<menu_item_call label="Gruppe aktivieren" name="activate_group"/>
<menu_item_call label="Gruppe beitreten" name="join_group"/>
<menu_item_call label="Gruppe verlassen" name="leave_group"/>
<menu_item_call label="Gruppe in Zwischenablage kopieren" name="url_copy_label"/>
<menu_item_call label="SLurl in die Zwischenablage kopieren" name="url_copy"/>
</context_menu>

View File

@ -82,7 +82,7 @@ Fehlerdetails: The notification called &apos;[_NAME]&apos; was not found in noti
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="BadInstallation">
Beim Aktualisieren von [APP_NAME] ist ein Fehler aufgetreten. Bitte [http://get.secondlife.com laden Sie die aktuellste Version des Viewers herunter].
Installation von [APP_NAME] ist defekt. Bitte [https://www.firestormviewer.org/downloads laden Sie neue Kopie des Viewers herunter] und installieren Sie erneut.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LoginFailedNoNetwork">

View File

@ -104,6 +104,20 @@
<check_box label="Menüsuche anzeigen" name="show_search_menu_check"/>
<check_box label="Kontostand anzeigen" name="FSShowCurrencyBalanceInStatusbar"/>
<check_box label="Popup-Fenster beim Überfahren der Icons mit der Maus in der Menüleiste aktivieren" name="FSStatusBarMenuButtonPopupOnRollover"/>
<text name="statusbar_timeformat_textbox">
Zeitformat:
</text>
<combo_box name="FSStatusBarTimeFormat" tool_tip="Bestimmt das Zeitformat, das in der Menüleiste verwendet wird.">
<combo_box.item label="Standard ausgewählter Sprache" name="Language"/>
<combo_box.item label="12 Stunden" name="12_Hour"/>
<combo_box.item label="12 Stunden inkl. Sekunden" name="12_Hour_Seconds"/>
<combo_box.item label="12 Stunden inkl. Zeitzone" name="12_Hour_TZ"/>
<combo_box.item label="12 Stunden inkl. Sekunden &amp; Zeitzone" name="12_Hour_TZ_Seconds"/>
<combo_box.item label="24 Stunden" name="24_Hour"/>
<combo_box.item label="24 Stunden inkl. Sekunden" name="24_Hour_Seconds"/>
<combo_box.item label="24 Stunden inkl. Zeitzone" name="24_Hour_TZ"/>
<combo_box.item label="24 Stunden inkl. Sekunden &amp; Zeitzone" name="24_Hour_TZ_Seconds"/>
</combo_box>
<text name="navfav_textbox">
Navigations- und Favoriten-Leiste:
</text>

View File

@ -81,6 +81,11 @@
<key>value</key>
<string>"[OBJECT]" wurde aufgrund von RLV-Einschränkungen verweigert, dich zu teleportieren.</string>
</map>
<key>blocked_scriptdialog</key>
<map>
<key>value</key>
<string>Skript-Dialog oder Textbox kann aufgrund von RLV-Einschränkungen nicht angezeigt werden.</string>
</map>
<key>blocked_startim</key>
<map>
<key>value</key>

View File

@ -2770,16 +2770,16 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo
Dieser Einwohner hat den Nicht-stören-Modus aktiviert und wird Ihre Nachricht später sehen.
</string>
<string name="AutoResponseModeDefault">
Dieser Einwohner hat den Firestorm-Viewer-Modus „Automatische Antwort“ aktiviert. Dies bedeutet, dass er nicht gestört werden möchte. Er wird Ihre Nachricht später sehen.
Dieser Einwohner hat den [APP_NAME]-Viewer-Modus „Automatische Antwort“ aktiviert. Dies bedeutet, dass er nicht gestört werden möchte. Er wird Ihre Nachricht später sehen.
</string>
<string name="AutoResponseModeNonFriendsDefault">
Dieser Einwohner hat den Firestorm-Viewer-Modus „Automatische Antwort“ aktiviert. Dies bedeutet, dass er nicht gestört werden möchte. Er wird Ihre Nachricht später sehen.
Dieser Einwohner hat den [APP_NAME]-Viewer-Modus „Automatische Antwort“ aktiviert. Dies bedeutet, dass er nicht gestört werden möchte. Er wird Ihre Nachricht später sehen.
</string>
<string name="RejectTeleportOffersResponseDefault">
Dieser Einwohner hat den Firestorm-Viewer-Modus „Teleport-Angebote und -Anforderungen abweisen“ aktiviert. Dies bedeutet, dass er nicht mit Teleport-Angeboten oder -Anforderungen gestört werden möchte. Sie können Ihm weiterhin eine Nachricht senden.
Dieser Einwohner hat den [APP_NAME]-Viewer-Modus „Teleport-Angebote und -Anforderungen abweisen“ aktiviert. Dies bedeutet, dass er nicht mit Teleport-Angeboten oder -Anforderungen gestört werden möchte. Sie können Ihm weiterhin eine Nachricht senden.
</string>
<string name="RejectFriendshipRequestsResponseDefault">
Dieser Einwohner hat den Firestorm-Viewer-Modus „Alle Freundschaftsanfragen abweisen“ aktiviert. Dies bedeutet, dass er nicht mit Freundschaftsanfragen gestört werden möchte. Sie können Ihm weiterhin eine Nachricht senden.
Dieser Einwohner hat den [APP_NAME]-Viewer-Modus „Alle Freundschaftsanfragen abweisen“ aktiviert. Dies bedeutet, dass er nicht mit Freundschaftsanfragen gestört werden möchte. Sie können Ihm weiterhin eine Nachricht senden.
</string>
<string name="MutedAvatarsResponseDefault">
Dieser Einwohner hat den Empfang Ihrer Nachrichten blockiert.
@ -6707,10 +6707,10 @@ Support-Bereich der Website Secondlife.com und melden Sie das Problem.
Unbekannt; Bitte die Debugeinstellung RenderQualityPerformance prüfen!
</string>
<string name="fsbridge_cant_create_disabled">
Firestorm kann die LSL-Brücke nicht erstellen, wenn „LSL-Client-Brücke aktivieren“ in den Einstellungen deaktiviert ist.
[APP_NAME] kann die LSL-Brücke nicht erstellen, wenn „LSL-Client-Brücke aktivieren“ in den Einstellungen deaktiviert ist.
</string>
<string name="fsbridge_no_library">
Firestorm konnte die LSL-Brücke nicht erstellen. Bitte die Bibliothek aktivieren und neu einloggen.
[APP_NAME] konnte die LSL-Brücke nicht erstellen. Bitte die Bibliothek aktivieren und neu einloggen.
</string>
<string name="fsbridge_already_creating">
LSL-Brücke wird bereits erstellt. Bitte einige Minuten vor einem erneuten Versuch warten.
@ -6786,10 +6786,29 @@ Ihre aktuelle Position: [AVATAR_POS]
Skript-Info: Fehlerhafte Antwort von LSL-Brücke erhalten. Bitte erneut versuchen.
</string>
<string name="fsbridge_error_injection">
HINWEIS: Ein oder mehrere Skripte wurden zur Firestorm-LSL-Brücke hinzugefügt! Falls dieser Hinweis unerwartet aufgetreten ist, bitte die LSL-Brücke über die Menü-Option „Avatar“ &gt; „Avatar-Befinden“ &gt; „LSL-Brücke neu erstellen“ neu erstellen.
HINWEIS: Ein oder mehrere Skripte wurden zur [APP_NAME]-LSL-Brücke hinzugefügt! Falls dieser Hinweis unerwartet aufgetreten ist, bitte die LSL-Brücke über die Menü-Option „Avatar“ &gt; „Avatar-Befinden“ &gt; „LSL-Brücke neu erstellen“ neu erstellen.
</string>
<string name="fsbridge_error_wrongvm">
HINWEIS: Das Skript der Firestorm-LSL-Brücke verwendet die alte LSO Virtuelle Maschine (16 KB Speicherlimit) anstelle von Mono (64 KB Speicherlimit), wodurch eine hohe Wahrscheinlichkeit von Stack-Heap-Collisions und Fehlern aufgrund von nicht mehr verfügbarem Speicher besteht! Bitte die LSL-Brücke über die Menü-Option „Avatar“ &gt; „Avatar-Befinden“ &gt; „LSL-Brücke neu erstellen“ neu erstellen. Falls dieser Hinweis erneut angezeigt wurde, bitte die Brücke in einer anderen Region neu erstellen.
HINWEIS: Das Skript der [APP_NAME]-LSL-Brücke verwendet die alte LSO Virtuelle Maschine (16 KB Speicherlimit) anstelle von Mono (64 KB Speicherlimit), wodurch eine hohe Wahrscheinlichkeit von Stack-Heap-Collisions und Fehlern aufgrund von nicht mehr verfügbarem Speicher besteht! Bitte die LSL-Brücke über die Menü-Option „Avatar“ &gt; „Avatar-Befinden“ &gt; „LSL-Brücke neu erstellen“ neu erstellen. Falls dieser Hinweis erneut angezeigt wurde, bitte die Brücke in einer anderen Region neu erstellen.
</string>
<string name="FSAOEnabled">
[APP_NAME] Animation Overrider aktiviert.
</string>
<string name="FSAODisabled">
[APP_NAME] Animation Overrider deaktiviert.
</string>
<string name="FSAOPausedScript">
Pausiert durch geskripteten Anhang.
</string>
<string name="FSAOResumedScript">
Fortgesetzt durch geskripteten Anhang.
</string>
<string name="FSAOStandsPausedScript">
Stand-Animationen pausiert durch geskripteten Anhang.
</string>
<string name="FSAOStandsResumedScript">
Stand-Animationen fortgesetzt durch geskripteten Anhang.
</string>
<string name="QP Draw Distance">
@ -7162,4 +7181,13 @@ Ihre aktuelle Position: [AVATAR_POS]
<string name="ImportingWindlightBulk">
Importiere Windlight...
</string>
<string name="FSObjectInventoryNoElements">
Keine Elemente
</string>
<string name="FSObjectInventoryOneElement">
1 Element
</string>
<string name="FSObjectInventoryElements">
[NUM_ELEMENTS] Elemente
</string>
</strings>

View File

@ -165,7 +165,7 @@ Additional code generously contributed to Firestorm by:
top_pad="4"
width="450"
wrap="true">
Albatroz Hird, Alexie Birman, Andromeda Rage, Angeldark Raymaker, Animats, Armin Weatherwax, Beq Janus, Casper Warden, Chalice Yao, Chaser Zaks, Cron Stardust, Damian Zhaoying, Dan Threebeards, Dawa Gurbux, Denver Maksim, Drake Arconis, Felyza Wishbringer, f0rbidden, Fractured Crystal, Geenz Spad, Gibson Firehawk, Hitomi Tiponi, Inusaito Sayori, Jean Severine, Katharine Berry, Kittin Ninetails, Kool Koolhoven, Lance Corrimal, Lassie, Latif Khalifa, Laurent Bechir, Magne Metaverse LLC, Magus Freston, Manami Hokkigai, MartinRJ Fayray, McCabe Maxstead, Melancholy Lemon, Melysmile, Mimika Oh, Mister Acacia, MorganMegan, mygoditsfullofstars, Mysty Saunders, Nagi Michinaga, Name Short, nhede Core, NiranV Dean, Nogardrevlis Lectar, Paladin Forzane, paperwork, Penny Patton, Peyton Menges, programmtest, Qwerty Venom, Revolution Smythe, Romka Swallowtail, Sahkolihaa Contepomi, sal Kaligawa, Samm Florian, Satomi Ahn, Sei Lisa, Sempervirens Oddfellow, Shin Wasp, Shyotl Kuhr, Sione Lomu, Skills Hak, StarlightShining, Sunset Faulkes, Testicular Slingshot, Thickbrick Sleaford, Ubit Umarov, Vaalith Jinn, Vincent Sylvester, Whirly Fizzle, Xenhat Liamano, Zwagoth Klaar and others.
Albatroz Hird, Alexie Birman, Andromeda Rage, Angeldark Raymaker, Animats, Armin Weatherwax, Beq Janus, Casper Warden, Chalice Yao, Chaser Zaks, Chorazin Allen, Cron Stardust, Damian Zhaoying, Dan Threebeards, Dawa Gurbux, Denver Maksim, Drake Arconis, Felyza Wishbringer, f0rbidden, Fractured Crystal, Geenz Spad, Gibson Firehawk, Hitomi Tiponi, Inusaito Sayori, Jean Severine, Katharine Berry, Kittin Ninetails, Kool Koolhoven, Lance Corrimal, Lassie, Latif Khalifa, Laurent Bechir, Magne Metaverse LLC, Magus Freston, Manami Hokkigai, MartinRJ Fayray, McCabe Maxstead, Melancholy Lemon, Melysmile, Mimika Oh, Mister Acacia, MorganMegan, mygoditsfullofstars, Mysty Saunders, Nagi Michinaga, Name Short, nhede Core, NiranV Dean, Nogardrevlis Lectar, Oren Hurvitz, Paladin Forzane, paperwork, Penny Patton, Peyton Menges, programmtest, Qwerty Venom, Revolution Smythe, Romka Swallowtail, Sahkolihaa Contepomi, sal Kaligawa, Samm Florian, Satomi Ahn, Sei Lisa, Sempervirens Oddfellow, Shin Wasp, Shyotl Kuhr, Sione Lomu, Skills Hak, StarlightShining, Sunset Faulkes, Testicular Slingshot, Thickbrick Sleaford, Ubit Umarov, Vaalith Jinn, Vincent Sylvester, Whirly Fizzle, Xenhat Liamano, Zwagoth Klaar and others.
</text>
<text
follows="top|left"

View File

@ -94,6 +94,10 @@
name="date_sort"
width="-1"
/>
<columns
name="asset_type"
width="-1"
/>
<row>
<column column="name">[UNKNOWN] Template item</column>
<column column="region">[UNKNOWN] Template item</column>
@ -120,6 +124,26 @@
left_pad="10"
bottom="-6"
follows="left|bottom"/>
<button
name="play_btn"
label="Play Sound"
tool_tip="Play the selected sound; only a single sound entry can be selected at a time for playback."
font="SansSerif"
height="24"
width="90"
left_pad="10"
bottom="-6"
follows="left|bottom"/>
<button
name="stop_btn"
label="Stop Sound"
tool_tip="Stop playing the current sound."
font="SansSerif"
height="24"
width="90"
left_delta="0"
bottom="-6"
follows="left|bottom"/>
<button
name="close_btn"
label="Close"

View File

@ -1178,7 +1178,8 @@
label="Overrides"
layout="topleft"
name="rigging_panel"
title="Rigging">
title="Rigging"
help_topic="upload_model_rigging">
<view_border
bevel_style="none"
follows="top|left"
@ -1331,7 +1332,8 @@
<panel
label="Log"
layout="topleft"
name="logs_panel">
name="logs_panel"
help_topic="upload_model_log">
<view_border
bevel_style="none"
follows="top|left"
@ -1376,7 +1378,8 @@
<panel
label="Preview Settings"
layout="topleft"
name="mesh_preview_settings_panel">
name="mesh_preview_settings_panel"
help_topic="upload_model_settings">
<view_border
bevel_style="none"
follows="top|left"

View File

@ -11,6 +11,58 @@
</menu_item_call>
<menu_item_separator
layout="topleft" />
<!-- <FS:Zi> FIRE-30725 - Add more group functions to group URL context menu -->
<!-- menu entry to call internal request for group data - this will make sure the
rest of the functions can actually do something once the data is loaded -->
<menu_item_call
label="Fetching Group Data, please try again!"
layout="topleft"
enabled="false"
name="waiting_for_group_data">
<menu_item_call.on_visible
function="FS.WaitingForGroupData" />
</menu_item_call>
<menu_item_call
label="Activate Group"
layout="topleft"
visible="false"
name="activate_group">
<menu_item_call.on_click
function="FS.ActivateGroup" />
<menu_item_call.on_visible
function="FS.HaveGroupData" />
<menu_item_call.on_enable
function="FS.EnableActivateGroup" />
</menu_item_call>
<menu_item_call
label="Join Group"
layout="topleft"
visible="false"
name="join_group">
<menu_item_call.on_click
function="FS.JoinGroup" />
<menu_item_call.on_visible
function="FS.HaveGroupData" />
<menu_item_call.on_enable
function="FS.EnableJoinGroup" />
</menu_item_call>
<menu_item_call
label="Leave Group"
layout="topleft"
visible="false"
name="leave_group">
<menu_item_call.on_click
function="FS.LeaveGroup" />
<menu_item_call.on_visible
function="FS.HaveGroupData" />
<menu_item_call.on_enable
function="FS.EnableLeaveGroup" />
</menu_item_call>
<menu_item_separator
layout="topleft" />
<!-- </FS:Zi> -->
<menu_item_call
label="Copy Group to clipboard"
layout="topleft"

View File

@ -352,6 +352,9 @@
<menu_item_call.on_click
function="Floater.Show"
parameter="fs_posestand" />
<menu_item_call.on_enable
function="Agent.IsActionAllowed"
parameter="fs_when_not_sitting" />
</menu_item_call>
<menu_item_separator/>

View File

@ -193,7 +193,7 @@ No tutorial is currently available.
icon="alertmodal.tga"
name="BadInstallation"
type="alertmodal">
An error occurred while updating [APP_NAME]. Please [http://get.secondlife.com download the latest version] of the Viewer.
Installation of [APP_NAME] is defective. Please [https://www.firestormviewer.org/downloads download a new copy] of the Viewer and reinstall.
<tag>fail</tag>
<usetemplate
name="okbutton"
@ -13597,4 +13597,19 @@ Cannot create inventory item: [NAME]
type="notifytip">
Bulk import of Windlights has finished.
</notification>
<notification
icon = "notifytip.tga"
name = "FSAOScriptedNotification"
type = "notifytip"
log_to_chat = "false">
<unique combine = "cancel_old">
<context>FSAOScriptedNotification</context>
</unique>
Firestorm Animation Overrider: [AO_MESSAGE]
<usetemplate
ignoretext="Warn me when the Firestorm Animation Overrider gets accessed by a scripted object"
name="notifyignore"/>
</notification>
</notifications>

View File

@ -46,6 +46,7 @@ Maximum 200 per group daily
draw_heading="true"
sort_column="4"
sort_ascending="false"
sort_lazily="true"
follows="left|top|right"
layout="topleft">
<scroll_list.columns

View File

@ -721,6 +721,63 @@
name="FSStatusBarMenuButtonPopupOnRollover"
width="270"
control_name="FSStatusBarMenuButtonPopupOnRollover"/>
<text
type="string"
follows="left|top"
height="16"
layout="topleft"
name="statusbar_timeformat_textbox"
left="13"
top_pad="8"
width="75">
Time format:
</text>
<combo_box
control_name="FSStatusBarTimeFormat"
height="23"
layout="topleft"
left_pad="10"
top_delta="-4"
name="FSStatusBarTimeFormat"
tool_tip="Selects the time format used on main menu bar."
width="250">
<combo_box.item
label="Language default"
name="Language"
value="Language"/>
<combo_box.item
label="12 Hour"
name="12_Hour"
value="12 Hour"/>
<combo_box.item
label="12 Hour incl. Seconds"
name="12_Hour_Seconds"
value="12 Hour Seconds"/>
<combo_box.item
label="12 Hour incl. Timezone"
name="12_Hour_TZ"
value="12 Hour TZ"/>
<combo_box.item
label="12 Hour incl. Seconds &amp; Timezone"
name="12_Hour_TZ_Seconds"
value="12 Hour TZ Seconds"/>
<combo_box.item
label="24 Hour"
name="24_Hour"
value="24 Hour"/>
<combo_box.item
label="24 Hour incl. Seconds"
name="24_Hour_Seconds"
value="24 Hour Seconds"/>
<combo_box.item
label="24 Hour incl. Timezone"
name="24_Hour_TZ"
value="12 Hour TZ"/>
<combo_box.item
label="24 Hour incl. Seconds &amp; Timezone"
name="24_Hour_TZ_Seconds"
value="24 Hour TZ Seconds"/>
</combo_box>
<text
type="string"
@ -762,7 +819,6 @@
width="270"
left="20"
control_name="ShowSearchTopBar"/>
</panel>
<!--Interface Windows-->

View File

@ -307,7 +307,7 @@
font="SansSerifSmall"
text_color="TimeTextColor"
follows="right|top"
halign="left"
halign="center"
height="16"
h_pad="2"
top="4"

Some files were not shown because too many files have changed in this diff Show More