diff --git a/autobuild.xml b/autobuild.xml
index ac5174405d..bcb424112c 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -22,9 +22,9 @@
archive
name
linux64
@@ -964,11 +964,11 @@
archive
name
darwin
@@ -978,11 +978,11 @@
archive
name
linux64
@@ -992,11 +992,11 @@
archive
name
windows
@@ -1006,18 +1006,18 @@
archive
name
windows64
version
- 2.01.07
+ 2.01.08
fontconfig
+ PauseAO
+
+ Comment
+ Pause the viewer side Animation Overrider
+ Persist
+ 0
+ Type
+ Boolean
+ Value
+ 0
+
UseAOStands
Comment
diff --git a/indra/newview/app_settings/shaders/class1/deferred/rlvF.glsl b/indra/newview/app_settings/shaders/class1/deferred/rlvF.glsl
new file mode 100644
index 0000000000..8661ffe923
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/rlvF.glsl
@@ -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), 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;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/rlvFMac.glsl b/indra/newview/app_settings/shaders/class1/deferred/rlvFMac.glsl
new file mode 100644
index 0000000000..fce37c24be
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/rlvFMac.glsl
@@ -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;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/rlvV.glsl b/indra/newview/app_settings/shaders/class1/deferred/rlvV.glsl
new file mode 100644
index 0000000000..19124b6101
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/rlvV.glsl
@@ -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;
+}
diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp
index c14b11162c..04098fad54 100644
--- a/indra/newview/chatbar_as_cmdline.cpp
+++ b/indra/newview/chatbar_as_cmdline.cpp
@@ -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)
{
+ // send appropriate enable/disable messages to nearby chat - FIRE-24160
+ bool aoWasEnabled = gSavedPerAccountSettings.getBOOL("UseAO");
+
if (status == "on")
{
gSavedPerAccountSettings.setBOOL("UseAO", TRUE);
+
+ // 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);
+
+ // send appropriate enable/disable messages to nearby chat - FIRE-24160
+ if (aoWasEnabled)
+ {
+ report_to_nearby_chat(LLTrans::getString("FSAODisabled"));
+ }
}
else if (status == "sit")
{
diff --git a/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt b/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt
index 1c161565a8..11e5ee0ce5 100644
--- a/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt
+++ b/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt
@@ -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("");
+ if (llList2String(commandList, 2) != "noreport")
+ {
+ llOwnerSay("");
+ }
}
else if (cmd == "llMoveToTarget")
diff --git a/indra/newview/fscommon.cpp b/indra/newview/fscommon.cpp
index a1bba035e0..b87fd79ef6 100644
--- a/indra/newview/fscommon.cpp
+++ b/indra/newview/fscommon.cpp
@@ -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;
}
diff --git a/indra/newview/fscommon.h b/indra/newview/fscommon.h
index be33ef6790..a7d8d350d6 100644
--- a/indra/newview/fscommon.h
+++ b/indra/newview/fscommon.h
@@ -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();
diff --git a/indra/newview/fsfloaterassetblacklist.cpp b/indra/newview/fsfloaterassetblacklist.cpp
index 890c7a79de..00bb43988c 100644
--- a/indra/newview/fsfloaterassetblacklist.cpp
+++ b/indra/newview/fsfloaterassetblacklist.cpp
@@ -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("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("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
//---------------------------------------------------------------------------
diff --git a/indra/newview/fsfloaterassetblacklist.h b/indra/newview/fsfloaterassetblacklist.h
index 83ffc020f7..a767db72c9 100644
--- a/indra/newview/fsfloaterassetblacklist.h
+++ b/indra/newview/fsfloaterassetblacklist.h
@@ -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;
diff --git a/indra/newview/fsfloaterim.cpp b/indra/newview/fsfloaterim.cpp
index d63c509230..591d76f91e 100644
--- a/indra/newview/fsfloaterim.cpp
+++ b/indra/newview/fsfloaterim.cpp
@@ -37,6 +37,7 @@
#include "fsdata.h"
#include "fsfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
#include "fsfloaternearbychat.h"
+#include "fsnearbychathub.h" // 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 // 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);
-
+
+ // 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);
diff --git a/indra/newview/fslslbridge.cpp b/indra/newview/fslslbridge.cpp
index ad8c49cc4c..e8596296cb 100644
--- a/indra/newview/fslslbridge.cpp
+++ b/indra/newview/fslslbridge.cpp
@@ -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 == " 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)
{
+ // 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");
+ //
+
if (message.substr(valuepos + FS_STATE_ATTRIBUTE.size(), 2) == "on")
{
- gSavedPerAccountSettings.setBOOL("UseAO", TRUE);
+ // 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);
+ // 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;
}
+
+ // 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);
+ }
+ //
}
}
// FIRE-962
diff --git a/indra/newview/fspanellogin.cpp b/indra/newview/fspanellogin.cpp
index 6699d6bed9..2f5d1449ec 100644
--- a/indra/newview/fspanellogin.cpp
+++ b/indra/newview/fspanellogin.cpp
@@ -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();
diff --git a/indra/newview/fsslurlcommand.cpp b/indra/newview/fsslurlcommand.cpp
index d0307b98d8..b53041d829 100644
--- a/indra/newview/fsslurlcommand.cpp
+++ b/indra/newview/fsslurlcommand.cpp
@@ -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;
}
};
diff --git a/indra/newview/lfsimfeaturehandler.cpp b/indra/newview/lfsimfeaturehandler.cpp
index ad7c60d2e4..03703c31b1 100644
--- a/indra/newview/lfsimfeaturehandler.cpp
+++ b/indra/newview/lfsimfeaturehandler.cpp
@@ -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") &&
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f0df7e5977..2b3c6ff395 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -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;
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4f3c458b48..a473bdfe02 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -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");
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index cc76b2e094..87bf2cb098 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -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;
+ // 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;
+ //
continue;
}
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index 77f0710d00..3136f96fe4 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -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)
diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index 17321e0bf2..361f54c2f1 100644
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -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;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index f7ef007017..a239024ec7 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -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("grid_management_panel")->setEnabled(FALSE);
LLGridManager::getInstance()->addGridListChangedCallback(boost::bind(&LLPanelPreferenceOpensim::refreshGridList, this, _1));
- LLGridManager::getInstance()->reFetchGrid(grid);
+ // 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()) );
+ //
}
void LLPanelPreferenceOpensim::onClickRemoveGrid()
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e786192df6..c1ac3e755d 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -3177,6 +3177,14 @@ void LLIMMgr::addMessage(
LL_WARNS() << "Failed to create IM session " << fixed_session_name << LL_ENDL;
}
}
+ // 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;
+ }
+ //
else if(!do_not_disturb && PlayModeUISndNewIncomingIMSession == 2 && dialog == IM_NOTHING_SPECIAL)
{
make_ui_sound("UISndNewIncomingIMSession");
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index c1f6c2f167..90c0c62079 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -258,7 +258,11 @@ std::string LLInvFVBridge::getSearchableCreatorName() const
if(item)
{
LLAvatarName av_name;
- if (LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
+ // 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) )
+ //
{
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)
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 9f5a528219..02b97924d2 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -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;;
}
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index b4236c406b..5a7ea32711 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -106,12 +106,14 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
mWaitList.insert(asset_uuid);
return NULL;
}
-
+ // 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;
+ // fIRE-14457 Fix CopySLURL fails / landmakrs not loading - based on snippet from Chorazin Allen
+ // mRequestedList[asset_uuid] = gFrameTimeSeconds;
}
return NULL;
}
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 4b231ca72b..3666ef7bc4 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -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))
+ // Avoid null UUID name cache requests
+ // if(LLAvatarNameCache::get(from_id, &av_name))
+ if( from_id.notNull() && LLAvatarNameCache::get(from_id, &av_name) )
+ //
{
res = av_name.getUserName();
}
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index ba831ab2ed..149d50c93a 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -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())
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 4e37d8da59..799e0fb412 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -709,12 +709,42 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const
if (cat)
{
- // Make object root folder name localizable again
+ // 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
+ {
+ // Make object root folder name localizable again
+ mDisplayName.assign(LLTrans::getString("Contents"));
+ }
}
+ //
else
{
mDisplayName.assign(cat->getName());
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index 76cb8fcf99..bfb80a634b 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -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));
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index b162afddf0..808d218e8e 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -1006,9 +1006,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);
+ // 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;
+ //
mImage->forceToSaveRawImage(0) ;
// texture comment decoder
mImage->setLoadedCallback(LLPreviewTexture::onTextureLoaded, 0, TRUE, FALSE, this, &mCallbackTextureList);
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 134dfd5a73..0ce7258e59 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -519,9 +519,49 @@ BOOL LLStatusBar::postBuild()
updateVolumeControlsVisibility(LLSD(FALSE));
}
//
+
+ // 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");
+ //
+
return TRUE;
}
+// 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);
+
+ // Add seconds to clock
+ static const std::string tooltip_template = getString("timeTooltip");
+ std::string dtStr = tooltip_template;
+ //
+ LLStringUtil::format (dtStr, substitution);
+ mTextTime->setToolTip (dtStr);
+}
+//
+
// 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();
+ // 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();
- // Add seconds to clock
- //std::string timeStr = getString("time");
- static const std::string time_template = getString("time");
- std::string timeStr = time_template;
- //
- 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
- // Add seconds to clock
- //std::string dtStr = getString("timeTooltip");
- static const std::string tooltip_template = getString("timeTooltip");
- std::string dtStr = tooltip_template;
- //
- 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();
+ //
}
// Pathfinding rebake functions
@@ -1717,6 +1753,14 @@ void LLStatusBar::onPopupRolloverChanged(const LLSD& newvalue)
}
}
+// FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display
+void LLStatusBar::onTimeFormatChanged(const std::string& format)
+{
+ mClockFormat = format;
+ updateClockDisplay();
+}
+//
+
// Implements secondlife:///app/balance/request to request a L$ balance
// update via UDP message system. JC
class LLBalanceHandler : public LLCommandHandler
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index a14a1f8370..81d427cfd4 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -157,6 +157,9 @@ public:
void updateCurrencySymbols();
//
+ // 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);
+ // Does not exist 15-02-2021
+ //void onClickScreen(S32 x, S32 y);
static void onClickStreamToggle(void* data); // 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();
+ // Does not exist 15-02-2021
+ //void updateParcelIconVisibility();
void onBuyLandClicked();
- // Pathfinding support
- void onRegionBoundaryCrossed();
- void onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus);
- void createNavMeshStatusListenerForCurrentRegion();
- // Pathfinding support
-
// 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();
//
+// FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display
+ std::map mClockFormatChoices;
+ std::string mClockFormat;
+
+ void updateClockDisplay();
+//
+
std::string mCurrentLocationString;
};
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index eebce59f9a..2f4b91a114 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -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)
}
//
+// 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);
+ }
+}
+//
+
////////////////////////////////////////////////////////////////////////////
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()
// Optional small camera floater
gSavedSettings.getControl("FSUseSmallCameraFloater")->getSignal()->connect(boost::bind(&handleSmallCameraFloaterChanged, _2));
+
+ // 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
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index c4ad6774c5..e955166827 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -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();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 1b99238bcf..13c890c57a 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -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;
}
@@ -10492,8 +10492,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;
}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index c42a5e5c06..39f25ae290 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -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;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index cd60588896..dc040019f0 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -83,6 +83,7 @@
#include
#include
+#include // 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;
+ // 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;
+ // FIRE-30694 DeadObject Spam
+ // new_dead_object = false;
}
else
{
- mDeadObjects.insert(objectp->mID);
+ // 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;
+ }
+ //
}
// 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++;
- }
+ // 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)
{
+ // FIRE-30694 DeadObject Spam
+ llassert( mNumDeadObjects == mDeadObjects.size() );
+
if (!mNumDeadObjects)
{
// No dead objects, don't need to scan object list.
return;
}
+ // 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); // Use timer for cleaning up dead objects
+ // FIRE-30694 DeadObject Spam
+ // mDeadObjects.erase(objectp->mID); // 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::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;
}
//
}
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index b0f2beeabe..d84649f3f5 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -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,22 @@ 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));
+#ifndef LL_DARWIN
+ gRlvSphereProgram.mShaderFiles.push_back(make_pair("deferred/rlvF.glsl", GL_FRAGMENT_SHADER_ARB));
+#else
+ gRlvSphereProgram.mShaderFiles.push_back(make_pair("deferred/rlvFMac.glsl", GL_FRAGMENT_SHADER_ARB));
+#endif
+ gRlvSphereProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
+ success = gRlvSphereProgram.createShader(NULL, NULL);
+ }
+// [/RLV:KB]
+
if (success)
{
gWLSunProgram.mName = "Windlight Sun Program";
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 5008873b62..955e8da0b1 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -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];
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index a06f906762..e048947762 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -640,7 +640,11 @@ void send_viewer_stats(bool include_preferences)
LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL;
- if (debugLoggingEnabled("LogViewerStatsPacket"))
+ // avoid unfortunate sleep during trylock by static check
+ // if (debugLoggingEnabled("LogViewerStatsPacket"))
+ static auto debug_logging_on = debugLoggingEnabled("LogViewerStatsPacket");
+ if (debug_logging_on)
+ //
{
std::string filename("viewer_stats_packet.xml");
llofstream of(filename.c_str());
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 3cd7ccd3ee..16611734c2 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1696,6 +1696,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
mNeedsAux = FALSE;
destroyRawImage();
}
+ // FIRE-30559 texture fetch speedup for user previews (based on patches from Oren Hurvitz)
+ gTextureList.recalcImageDecodePriority(this);
return res;
}
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 88777fbc15..bb85c9054d 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -710,6 +710,8 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListTy
addImageToList(new_image);
mUUIDMap[key] = new_image;
new_image->setTextureListType(tex_type);
+ // 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);
}
+ // 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()
}
}
+// 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 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 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 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 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 imagep = iter->second;
+ ++iter; // safe to increment now
+ updateOneImageDecodePriority(imagep);
}
}
+void LLViewerTextureList::updateOneImageDecodePriority(LLPointer 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);
+ }
+}
+// FIRE-30559
+
void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level)
{
if(!tex->setDebugFetching(debug_level))
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 6feae4d897..ca26883763 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -34,6 +34,7 @@
#include "llui.h"
#include
#include
+#include
#include "lluiimage.h"
const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128;
@@ -147,6 +148,8 @@ public:
private:
void updateImagesDecodePriorities();
+ // FIRE-30559 texture fetch speedup for user previews (based on patches from Oren Hurvitz)
+ void updateOneImageDecodePriority(LLPointer imagep);
F32 updateImagesCreateTextures(F32 max_time);
F32 updateImagesFetchTextures(F32 max_time);
void updateImagesUpdateStats();
@@ -219,7 +222,12 @@ public:
// Fast cache stats
static U32 sNumFastCacheReads;
-
+ // 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 image);
+ //
private:
typedef std::map< LLTextureKey, LLPointer > uuid_map_t;
uuid_map_t mUUIDMap;
@@ -228,7 +236,11 @@ private:
typedef std::set, LLViewerFetchedTexture::Compare> image_priority_list_t;
image_priority_list_t mImageList;
-
+ // 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;
+ //
+
// simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon
std::set > mImagePreloads;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 1ef53c5db2..751df0582d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -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;
+ // 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;
+ //
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(EVisualEffect::RlvOverlay))
{
- hit_object = nullptr;
+ if (pOverlayEffect->hitTest(mMousePt))
+ hit_object = nullptr;
}
}
// [/RLVa:KB]
diff --git a/indra/newview/llvisualeffect.cpp b/indra/newview/llvisualeffect.cpp
new file mode 100644
index 0000000000..af68a57413
--- /dev/null
+++ b/indra/newview/llvisualeffect.cpp
@@ -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
+#include
+
+// ============================================================================
+// LLTweenableValue class
+//
+
+template<>
+float LLTweenableValueLerp::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::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::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);
+ }
+}
+
+// ============================================================================
diff --git a/indra/newview/llvisualeffect.h b/indra/newview/llvisualeffect.h
new file mode 100644
index 0000000000..41d10bda90
--- /dev/null
+++ b/indra/newview/llvisualeffect.h
@@ -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
+#include
+
+// ============================================================================
+//
+//
+
+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
+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 m_CurValue;
+};
+
+template
+class LLTweenableValueLerp : public LLTweenableValue
+{
+public:
+ LLTweenableValueLerp(const T& defaultValue) : LLTweenableValue(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
+{
+ LLSINGLETON(LLVfxManager);
+protected:
+ ~LLVfxManager() {}
+
+ /*
+ * Member functions
+ */
+public:
+ bool addEffect(LLVisualEffect* pEffectInst);
+ LLVisualEffect* getEffect(const LLUUID& idEffect) const;
+ template T* getEffect(const LLUUID& idEffect) const { return dynamic_cast(getEffect(idEffect)); }
+ LLVisualEffect* getEffect(EVisualEffect eCode) const;
+ template T* getEffect(EVisualEffect eCode) const { return dynamic_cast(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 m_Effects;
+};
+
+// ============================================================================
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 9ea5cfef74..f6c836c17e 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -131,6 +131,7 @@
#include "llviewernetwork.h" // [FS:CR] isInSecondlife()
#include "llsidepanelappearance.h"
#include "fsavatarrenderpersistence.h"
+#include "fslslbridge.h" // Movelock position refresh
#include "fsdiscordconnect.h" // 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]
+
+ // 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");
+ }
+ //
}
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 06225f21c1..7c4b5a3afc 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -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; // 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; // 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, ¶ms);
+ 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]
// FIRE-16829: Visual Artifacts with ALM enabled on AMD graphics
//gGL.begin(LLRender::TRIANGLE_STRIP);
@@ -8229,7 +8307,10 @@ void LLPipeline::renderFinalize()
drawAuxiliaryVB();
//
- 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, ¶ms);
+ pRenderBuffer = params.m_pDstBuffer;
+ }
+// [/RLVa:KB]
+
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
LLPointer 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);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 75e2410147..570ed5e6a9 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -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 sStatBatchSize;
diff --git a/indra/newview/quickprefs.cpp b/indra/newview/quickprefs.cpp
index b9d272ec4f..9ad3f15a62 100644
--- a/indra/newview/quickprefs.cpp
+++ b/indra/newview/quickprefs.cpp
@@ -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));
}
// 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("T_Sky_Detail");
LLSlider* sky_slider = getChild("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);
}
diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp
index fd77515434..690250c164 100644
--- a/indra/newview/rlvactions.cpp
+++ b/indra/newview/rlvactions.cpp
@@ -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();
+ 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
//
diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h
index c1f2f46ec8..39fd2beac7 100644
--- a/indra/newview/rlvactions.h
+++ b/indra/newview/rlvactions.h
@@ -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
// ================
diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp
index 6c37fa9d78..9b33285368 100644
--- a/indra/newview/rlvcommon.cpp
+++ b/indra/newview/rlvcommon.cpp
@@ -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:
diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h
index 0dc9e0e3c4..a9fb8d6ce7 100644
--- a/indra/newview/rlvcommon.h
+++ b/indra/newview/rlvcommon.h
@@ -56,7 +56,7 @@ class RlvObject;
struct RlvException;
typedef boost::variant RlvExceptionOption;
-typedef boost::variant RlvBehaviourModifierValue;
+typedef boost::variant RlvBehaviourModifierValue;
class RlvGCTimer;
diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h
index 2ae7d82b56..ceefa1c25a 100644
--- a/indra/newview/rlvdefines.h
+++ b/indra/newview/rlvdefines.h
@@ -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)
diff --git a/indra/newview/rlveffects.cpp b/indra/newview/rlveffects.cpp
new file mode 100644
index 0000000000..6da6a15825
--- /dev/null
+++ b/indra/newview/rlveffects.cpp
@@ -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 newValue)
+{
+ if (RlvOverlayEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ pEffect->m_nAlpha = (newValue) ? boost::get(newValue.value()) : c_DefaultAlpha;
+ }
+ return RLV_RET_SUCCESS;
+}
+
+// static
+ERlvCmdRet RlvOverlayEffect::onBlockTouchValueChanged(const LLUUID& idRlvObj, const boost::optional newValue)
+{
+ if (RlvOverlayEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ pEffect->m_fBlockTouch = (newValue) ? boost::get(newValue.value()) : false;
+ }
+ return RLV_RET_SUCCESS;
+}
+// static
+ERlvCmdRet RlvOverlayEffect::onColorValueChanged(const LLUUID& idRlvObj, const boost::optional newValue)
+{
+ if (RlvOverlayEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ pEffect->m_Color = LLColor3( (newValue) ? boost::get(newValue.value()).mV : c_DefaultColor);
+ }
+ return RLV_RET_SUCCESS;
+}
+
+// static
+ERlvCmdRet RlvOverlayEffect::onTextureChanged(const LLUUID& idRlvObj, const boost::optional newValue)
+{
+ if (RlvOverlayEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ if (newValue)
+ pEffect->setImage(boost::get(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 newValue)
+{
+ if (RlvSphereEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ pEffect->m_eMode = (ESphereMode)((newValue) ? boost::get(newValue.value()) : c_SphereDefaultMode);
+ }
+ return RLV_RET_SUCCESS;
+}
+
+// static
+ERlvCmdRet RlvSphereEffect::onOriginChanged(const LLUUID& idRlvObj, const boost::optional newValue)
+{
+ if (RlvSphereEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ pEffect->m_eOrigin = (ESphereOrigin)((newValue) ? boost::get(newValue.value()) : c_SphereDefaultOrigin);
+ }
+ return RLV_RET_SUCCESS;
+}
+
+// static
+ERlvCmdRet RlvSphereEffect::onColorChanged(const LLUUID& idRlvObj, const boost::optional newValue)
+{
+ if (RlvSphereEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ LLVector4 vecColor = (newValue) ? LLVector4(boost::get(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 newValue)
+{
+ if (RlvSphereEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ float nDistanceMin = (newValue) ? boost::get(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 newValue)
+{
+ if (RlvSphereEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ float nDistanceMax = (newValue) ? boost::get(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 newValue)
+{
+ if (RlvSphereEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ pEffect->m_eDistExtend = (ESphereDistExtend)((newValue) ? boost::get(newValue.value()) : c_SphereDefaultDistanceExtend);
+ }
+ return RLV_RET_SUCCESS;
+}
+
+// static
+ERlvCmdRet RlvSphereEffect::onParamsChanged(const LLUUID& idRlvObj, const boost::optional newValue)
+{
+ if (RlvSphereEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ LLVector4 params = LLVector4((newValue) ? boost::get(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 newValue)
+{
+ if (RlvSphereEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ pEffect->m_nTweenDuration = (newValue) ? boost::get(newValue.value()) : 0;
+ }
+ return RLV_RET_SUCCESS;
+}
+
+// static
+ERlvCmdRet RlvSphereEffect::onValueMinChanged(const LLUUID& idRlvObj, const boost::optional newValue)
+{
+ if (RlvSphereEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ float nValueMin = (newValue) ? boost::get(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 newValue)
+{
+ if (RlvSphereEffect* pEffect = dynamic_cast(LLVfxManager::instance().getEffect(idRlvObj)))
+ {
+ float nValueMax = (newValue) ? boost::get(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(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();
+}
+
+// ====================================================================================
diff --git a/indra/newview/rlveffects.h b/indra/newview/rlveffects.h
new file mode 100644
index 0000000000..0b55b2a500
--- /dev/null
+++ b/indra/newview/rlveffects.h
@@ -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 newValue);
+ static ERlvCmdRet onBlockTouchValueChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+ static ERlvCmdRet onColorValueChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+ static ERlvCmdRet onTextureChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+protected:
+ void clearImage();
+ void setImage(const LLUUID& idTexture);
+
+ /*
+ * Member variables
+ */
+protected:
+ LLTweenableValueLerp m_nAlpha;
+ bool m_fBlockTouch;
+ LLTweenableValueLerp m_Color;
+
+ LLPointer 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 newValue);
+ static ERlvCmdRet onOriginChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+ static ERlvCmdRet onColorChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+ static ERlvCmdRet onDistMinChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+ static ERlvCmdRet onDistMaxChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+ static ERlvCmdRet onDistExtendChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+ static ERlvCmdRet onParamsChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+ static ERlvCmdRet onTweenDurationChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+ static ERlvCmdRet onValueMinChanged(const LLUUID& idRlvObj, const boost::optional newValue);
+ static ERlvCmdRet onValueMaxChanged(const LLUUID& idRlvObj, const boost::optional 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 m_Params;
+ LLTweenableValueLerp m_nDistanceMin;
+ LLTweenableValueLerp m_nDistanceMax;
+ enum class ESphereDistExtend { Max = 0x01, Min = 0x02, Both = 0x03 };
+ ESphereDistExtend m_eDistExtend;
+ LLTweenableValueLerp m_nValueMin;
+ LLTweenableValueLerp m_nValueMax;
+ float m_nTweenDuration;
+};
+
+// ====================================================================================
diff --git a/indra/newview/rlvextensions.cpp b/indra/newview/rlvextensions.cpp
index 9a44df6778..faffcd5bb3 100644
--- a/indra/newview/rlvextensions.cpp
+++ b/indra/newview/rlvextensions.cpp
@@ -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("AvatarSex", DBG_READ | DBG_WRITE | DBG_PSEUDO));
+ m_DbgAllowed.insert(std::pair("AspectRatio", DBG_READ | DBG_PSEUDO));
m_DbgAllowed.insert(std::pair("RenderResolutionDivisor", DBG_READ | DBG_WRITE));
m_DbgAllowed.insert(std::pair(RlvSettingNames::ForbidGiveToRlv, DBG_READ));
m_DbgAllowed.insert(std::pair(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();
}
diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp
index 5f90fa1259..b0b089e138 100644
--- a/indra/newview/rlvfloaters.cpp
+++ b/indra/newview/rlvfloaters.cpp
@@ -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);
}
diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp
index 1ed14a45d5..19a8d49739 100644
--- a/indra/newview/rlvhandler.cpp
+++ b/indra/newview/rlvhandler.cpp
@@ -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::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::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::onCommand(const RlvC
return RLV_RET_SUCCESS;
}
-// Handles: @bhvr[:]=n|y
+// Handles: @bhvr=n, @bhvr:=n|y and @bhvr:=force
template<>
ERlvCmdRet RlvBehaviourGenericHandler::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:=n|y : if there is an option then it should specify a valid global modifier and if so we reference count
return RlvBehaviourGenericHandler::onCommand(rlvCmd, fRefCount);
+ }
+ else if (rlvCmd.getParamType() == RLV_TYPE_FORCE)
+ {
+ // @bhvr:=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::onCommandToggle(ERlvBehaviour eBhv
template<> template<>
void RlvBehaviourToggleHandler::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 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:=n|y changes
-template<>
-void RlvBehaviourModifierHandler::onValueChange() const
+// Handles: @setsphere=n|y
+template<> template<>
+ERlvCmdRet RlvBehaviourHandler::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::onCommand(rlvCmd, fRefCount);
+ if ( (RLV_RET_SUCCESS == eRet) && (!rlvCmd.isModifier()) )
{
- if (pBhvrModifier->hasValue())
- gRlvHandler.setOverlayImage(pBhvrModifier->getValue());
+ // 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[:]=n|y and @sendchannel_except[:]=n|y
@@ -2598,28 +2613,31 @@ ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand&
return eRet;
}
-// Handles: @shownametags[:]=n|y toggles
-template<> template<>
-void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
+// Handles: @shownametags[:] value changes
+template<>
+void RlvBehaviourModifierHandler::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[:]=n|y
+// Handles: @shownametags[:]=n|y
template<> template<>
ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount)
{
- ERlvCmdRet eRet = RlvBehaviourGenericHandler::onCommand(rlvCmd, fRefCount);
- if ( (RLV_RET_SUCCESS == eRet) && (rlvCmd.hasOption()) )
- LLVOAvatar::invalidateNameTag(RlvCommandOptionHelper::parseOption(rlvCmd.getOption()));
- return eRet;
+ LLUUID idOption;
+ if ( (rlvCmd.hasOption()) && (RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), idOption)) )
+ {
+ ERlvCmdRet eRet = RlvBehaviourGenericHandler::onCommand(rlvCmd, fRefCount);
+ if (RLV_RET_SUCCESS == eRet)
+ LLVOAvatar::invalidateNameTag(idOption);
+ fRefCount = false;
+ return eRet;
+ }
+ return RlvBehaviourGenericHandler::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::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
+{
+ if (fHasBhvr)
+ {
+ LLDrawPoolAlpha::sShowDebugAlpha = false;
+ }
+}
+
+// Handles: @viewwireframe toggles
+template<> template<>
+void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
+{
+ if (fHasBhvr)
+ {
+ set_use_wireframe(false);
+ }
+}
+
// ============================================================================
// Command handlers (RLV_TYPE_FORCE)
//
@@ -2691,7 +2729,7 @@ ERlvCmdRet RlvForceGenericHandler::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::onCommand(const RlvCommand& rl
template<> template<>
ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd)
{
+ RlvObject* pRlvObj = gRlvHandler.getObject(rlvCmd.getObjectID());
+ if (!pRlvObj)
+ return RLV_RET_FAILED_NOBEHAVIOUR;
+
+ RlvOverlayEffect* pOverlayEffect = LLVfxManager::instance().getEffect(rlvCmd.getObjectID());
+ if (!pOverlayEffect)
+ return RLV_RET_FAILED_LOCK;
+
std::vector optionList;
if ( (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) || (3 != optionList.size()) )
return RLV_RET_FAILED_OPTION;
@@ -3058,12 +3104,18 @@ ERlvCmdRet RlvForceHandler::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()) &&
- (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();
- gGL.color4f(overlayTint.mV[0], overlayTint.mV[1], overlayTint.mV[2], llclamp(RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_ALPHA)->getValue(), 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);
-}
-
// ============================================================================
diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h
index c5b20de417..01da4b6269 100644
--- a/indra/newview/rlvhandler.h
+++ b/indra/newview/rlvhandler.h
@@ -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& 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 m_PendingGroupChange; // @setgroup=force
std::pair m_GroupChangeExpiration; // @setgroup=force
- LLPointer 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(&itObj->second) : nullptr;
+}
+
inline bool RlvHandler::hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const
{
return hasBehaviourExcept(eBhvr, strOption, LLUUID::null);
diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp
index e333350d68..3ca2a4d725 100644
--- a/indra/newview/rlvhelper.cpp
+++ b/indra/newview/rlvhelper.cpp
@@ -26,6 +26,7 @@
// 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("edit"));
addEntry(new RlvBehaviourGenericProcessor("editobj", RLV_BHVR_EDITOBJ));
+ addEntry(new RlvBehaviourGenericToggleProcessor("viewtransparent", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
+ addEntry(new RlvBehaviourGenericToggleProcessor("viewwireframe", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvBehaviourGenericProcessor("emote", RLV_BHVR_EMOTE));
addEntry(new RlvBehaviourGenericProcessor("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("showloc", RLV_BHVR_SHOWLOC));
addEntry(new RlvBehaviourGenericProcessor("showminimap", RLV_BHVR_SHOWMINIMAP));
addEntry(new RlvBehaviourToggleProcessor("shownames", RlvBehaviourInfo::BHVR_STRICT));
- addEntry(new RlvBehaviourToggleProcessor("shownametags", RlvBehaviourInfo::BHVR_STRICT ));
+ addEntry(new RlvBehaviourProcessor("shownametags", RlvBehaviourInfo::BHVR_STRICT));
+ addModifier(RLV_BHVR_SHOWNAMETAGS, RLV_MODIFIER_SHOWNAMETAGSDIST, new RlvBehaviourModifierHandler("Name Tags - Visible Distance", 0.0f, true, new RlvBehaviourModifierCompMin));
addEntry(new RlvBehaviourGenericToggleProcessor("shownearby", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvBehaviourGenericToggleProcessor("showself", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvBehaviourGenericToggleProcessor("showselfhead", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
@@ -219,17 +223,28 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addEntry(new RlvBehaviourGenericToggleProcessor("camunlock", RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));
// Overlay
- addEntry(new RlvBehaviourGenericToggleProcessor("setoverlay", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
- addModifier(new RlvForceGenericProcessor("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("setoverlay_texture", RLV_BHVR_SETOVERLAY_TEXTURE, RlvBehaviourInfo::BHVR_EXPERIMENTAL),
- RLV_MODIFIER_OVERLAY_TEXTURE, new RlvBehaviourModifierHandler("Overlay - Texture", LLUUID::null, false, new RlvBehaviourModifierComp()));
- addModifier(new RlvForceGenericProcessor("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("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("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("setoverlay_tween", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
+ // Sphere
+ RlvBehaviourInfo* pSetSphereBhvr = new RlvBehaviourProcessor("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& 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
//
diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h
index 68a41615d7..1577510c01 100644
--- a/indra/newview/rlvhelper.h
+++ b/indra/newview/rlvhelper.h
@@ -38,7 +38,10 @@ struct RlvBehaviourModifierComp;
class RlvBehaviourInfo
{
+ typedef std::function)> modifier_handler_func_t;
public:
+ typedef std::map> 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& 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 const T& getValue() const { return boost::get(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 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 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
+inline bool RlvObject::getModifierValue(ERlvLocalBhvrModifier eBhvrModifier, T& value) const
+{
+ auto itBhvrModifierValue = m_Modifiers.find(eBhvrModifier);
+ if (m_Modifiers.end() != itBhvrModifierValue)
+ {
+ value = boost::get(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)
{
diff --git a/indra/newview/rlvmodifiers.cpp b/indra/newview/rlvmodifiers.cpp
deleted file mode 100644
index ce082254f2..0000000000
--- a/indra/newview/rlvmodifiers.cpp
+++ /dev/null
@@ -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(curTween.startValue), boost::get(curTween.endValue), curFactor), curTween.idObject);
- else if (typeid(int) == valueType)
- pBhvrModifier->setValue(lerp(boost::get(curTween.startValue), boost::get(curTween.endValue), curFactor), curTween.idObject);
- else if (typeid(LLVector3) == valueType)
- pBhvrModifier->setValue(lerp(boost::get(curTween.startValue), boost::get(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();
-}
-
- // ====================================================================================
diff --git a/indra/newview/rlvmodifiers.h b/indra/newview/rlvmodifiers.h
index 832e01de1e..374ef58567 100644
--- a/indra/newview/rlvmodifiers.h
+++ b/indra/newview/rlvmodifiers.h
@@ -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
-{
- 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
- {
- public:
- AnimationTimer();
- BOOL tick() override;
- };
-
- /*
- * Member variables
- */
-protected:
- LLHandle m_TimerHandle;
- std::list< RlvBehaviourModifierTween> m_Tweens;
-};
-
// ====================================================================================
// RlvCachedBehaviourModifier - Provides an optimized way to access a modifier that's frequently accessed and rarely updated
//
diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml
index 27e1a4cdf5..36968b04fc 100644
--- a/indra/newview/skins/default/xui/da/notifications.xml
+++ b/indra/newview/skins/default/xui/da/notifications.xml
@@ -68,7 +68,7 @@ Fejl detaljer: Beskeden kaldet '[_NAME]' blev ikke fundet i notificati
- 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.
diff --git a/indra/newview/skins/default/xui/de/floater_fs_asset_blacklist.xml b/indra/newview/skins/default/xui/de/floater_fs_asset_blacklist.xml
index ef4fb0f1b5..b3eaed78e0 100644
--- a/indra/newview/skins/default/xui/de/floater_fs_asset_blacklist.xml
+++ b/indra/newview/skins/default/xui/de/floater_fs_asset_blacklist.xml
@@ -34,5 +34,7 @@
+
+
diff --git a/indra/newview/skins/default/xui/de/menu_url_group.xml b/indra/newview/skins/default/xui/de/menu_url_group.xml
index 6bd86414bc..e9a0129be1 100644
--- a/indra/newview/skins/default/xui/de/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_group.xml
@@ -1,6 +1,10 @@
+
+
+
+
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index 6f4488c46d..0b106075a7 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -82,7 +82,7 @@ Fehlerdetails: The notification called '[_NAME]' was not found in noti
- 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.
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_UI.xml b/indra/newview/skins/default/xui/de/panel_preferences_UI.xml
index bab6df298b..8ec019d1cd 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_UI.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_UI.xml
@@ -104,6 +104,20 @@
+
+ Zeitformat:
+
+
+
+
+
+
+
+
+
+
+
+
Navigations- und Favoriten-Leiste:
diff --git a/indra/newview/skins/default/xui/de/rlva_strings.xml b/indra/newview/skins/default/xui/de/rlva_strings.xml
index f1ac38cf4b..6c0e648605 100644
--- a/indra/newview/skins/default/xui/de/rlva_strings.xml
+++ b/indra/newview/skins/default/xui/de/rlva_strings.xml
@@ -81,6 +81,11 @@
value
"[OBJECT]" wurde aufgrund von RLV-Einschränkungen verweigert, dich zu teleportieren.
+ blocked_scriptdialog
+
+ value
+ Skript-Dialog oder Textbox kann aufgrund von RLV-Einschränkungen nicht angezeigt werden.
+
blocked_startim
value
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index fe60ca8beb..da1e977f14 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -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.
- 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.
- 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.
- 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.
- 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.
Dieser Einwohner hat den Empfang Ihrer Nachrichten blockiert.
@@ -6692,10 +6692,10 @@ Support-Bereich der Website Secondlife.com und melden Sie das Problem.
Unbekannt; Bitte die Debugeinstellung RenderQualityPerformance prüfen!
- 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.
- 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.
LSL-Brücke wird bereits erstellt. Bitte einige Minuten vor einem erneuten Versuch warten.
@@ -6771,10 +6771,29 @@ Ihre aktuelle Position: [AVATAR_POS]
Skript-Info: Fehlerhafte Antwort von LSL-Brücke erhalten. Bitte erneut versuchen.
- 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“ > „Avatar-Befinden“ > „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“ > „Avatar-Befinden“ > „LSL-Brücke neu erstellen“ neu erstellen.
- 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“ > „Avatar-Befinden“ > „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“ > „Avatar-Befinden“ > „LSL-Brücke neu erstellen“ neu erstellen. Falls dieser Hinweis erneut angezeigt wurde, bitte die Brücke in einer anderen Region neu erstellen.
+
+
+
+ [APP_NAME] Animation Overrider aktiviert.
+
+
+ [APP_NAME] Animation Overrider deaktiviert.
+
+
+ Pausiert durch geskripteten Anhang.
+
+
+ Fortgesetzt durch geskripteten Anhang.
+
+
+ Stand-Animationen pausiert durch geskripteten Anhang.
+
+
+ Stand-Animationen fortgesetzt durch geskripteten Anhang.
@@ -7147,4 +7166,13 @@ Ihre aktuelle Position: [AVATAR_POS]
Importiere Windlight...
+
+ Keine Elemente
+
+
+ 1 Element
+
+
+ [NUM_ELEMENTS] Elemente
+
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 9250b08b4e..932effd92c 100644
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -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.
+
[UNKNOWN] Template item
[UNKNOWN] Template item
@@ -120,6 +124,26 @@
left_pad="10"
bottom="-6"
follows="left|bottom"/>
+
+
+ blocked_scriptdialog
+
+ value
+ Unable to show script dialog or textbox due to RLV restrictions
+
blocked_startim
value
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 7122d13ef3..1a00dcbbae 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -1244,10 +1244,10 @@ If you continue to receive this message, please contact Second Life support for
This resident has turned on Unavailable mode and will see your message later.
- The Resident you messaged has activated Firestorm viewer's 'autorespond mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.
- The Resident you messaged has activated Firestorm viewer's 'autorespond mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.
- The Resident you messaged has activated Firestorm viewer's 'reject all teleport offers and requests mode' which means they have requested not to be disturbed with teleport offers and requests. You may still send an IM message manually.
- The Resident you messaged has activated Firestorm viewer's 'reject all friendship requests mode' which means they have requested not to be disturbed with friendship requests. You may still send an IM message manually.
+ The Resident you messaged has activated [APP_NAME] viewer's 'autorespond mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.
+ The Resident you messaged has activated [APP_NAME] viewer's 'autorespond mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.
+ The Resident you messaged has activated [APP_NAME] viewer's 'reject all teleport offers and requests mode' which means they have requested not to be disturbed with teleport offers and requests. You may still send an IM message manually.
+ The Resident you messaged has activated [APP_NAME] viewer's 'reject all friendship requests mode' which means they have requested not to be disturbed with friendship requests. You may still send an IM message manually.
The Resident you messaged has blocked you from sending them any messages.
The Resident you messaged is currently away from keyboard. Your message will still be shown in their IM panel for later viewing.
@@ -2980,19 +2980,19 @@ and report the problem.
Ultra (7/7)
Unknown, beyond the normal range, check RenderQualityPerformance debug setting
- Firestorm cannot create the LSL bridge if "Enable LSL-Client Bridge" is disabled in Preferences.
- Firestorm could not create an LSL bridge. Please enable your library and relog.
+ [APP_NAME] cannot create the LSL bridge if "Enable LSL-Client Bridge" is disabled in Preferences.
+ [APP_NAME] could not create an LSL bridge. Please enable your library and relog.
Bridge creation in process, cannot start another. Please wait a few minutes before trying again.
Creating the bridge. This might take a moment, please wait.
Bridge not created. The bridge script could not be created.
- Bridge not created. The bridge is named incorrectly. Please use the Firestorm 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge.
- Bridge not created. The bridge couldn't be found in inventory. Please use the Firestorm 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge.
- Bridge failed to attach. This is not the current bridge version. Please use the Firestorm 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge.
- Bridge failed to attach. The bridge wasn't found in the right inventory location. Please use the Firestorm 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge.
- Bridge failed to attach. Something else was using the bridge attachment point. Please use the Firestorm 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge.
+ Bridge not created. The bridge is named incorrectly. Please use the [APP_NAME] 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge.
+ Bridge not created. The bridge couldn't be found in inventory. Please use the [APP_NAME] 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge.
+ Bridge failed to attach. This is not the current bridge version. Please use the [APP_NAME] 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge.
+ Bridge failed to attach. The bridge wasn't found in the right inventory location. Please use the [APP_NAME] 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge.
+ Bridge failed to attach. Something else was using the bridge attachment point. Please use the [APP_NAME] 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge.
The bridge object could not be found. Cannot proceed with its creation, exiting.
The bridge inventory contains unexpected items.
- The bridge has not finished creating, you may need to use the Firestorm 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate it before using.
+ The bridge has not finished creating, you may need to use the [APP_NAME] 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate it before using.
Bridge detached.
Bridge created.
Script info: '[OBJECT_NAME]': [[OBJECT_RUNNING_SCRIPT_COUNT]/[OBJECT_TOTAL_SCRIPT_COUNT]] running scripts, [OBJECT_SCRIPT_MEMORY] KB allowed memory size limit, [OBJECT_SCRIPT_TIME] ms of CPU time consumed.[PATHFINDING_TEXT]
@@ -3021,8 +3021,16 @@ Your current position: [AVATAR_POS]
Script info: Object to check is invalid or out of range.
Script info: Received malformed response from bridge. Try again.
- NOTICE: One or more scripts have been added to your Firestorm bridge! If you did not expect this message, use the Firestorm 'Avatar/Avatar Health/Recreate Bridge' menu option to re-create your bridge now.
- NOTICE: Bridge script is using old LSO (16 KB memory limit) instead of new Mono (64 KB memory limit) virtual machine, which creates high probability of stack-heap collision and bridge failure by running out of memory. Please use the Firestorm 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge. If you'll see this message again - please try again in a different region.
+ NOTICE: One or more scripts have been added to your [APP_NAME] bridge! If you did not expect this message, use the [APP_NAME] 'Avatar/Avatar Health/Recreate Bridge' menu option to re-create your bridge now.
+ NOTICE: Bridge script is using old LSO (16 KB memory limit) instead of new Mono (64 KB memory limit) virtual machine, which creates high probability of stack-heap collision and bridge failure by running out of memory. Please use the [APP_NAME] 'Avatar/Avatar Health/Recreate Bridge' menu option to recreate the bridge. If you'll see this message again - please try again in a different region.
+
+
+ [APP_NAME] Animation Overrider enabled.
+ [APP_NAME] Animation Overrider disabled.
+ Paused by scripted attachment.
+ Resumed by scripted attachment.
+ Standing animations paused by scripted attachment.
+ Standing animations resumed by scripted attachment.
Draw Distance
@@ -3182,7 +3190,7 @@ Your current position: [AVATAR_POS]
Noto Sans
Celestia Medium Redux
Unknown Mode
- Firestorm
+ [APP_NAME]
Phoenix
[VIEWER_GENERATION]
Hybrid
@@ -3200,4 +3208,9 @@ Your current position: [AVATAR_POS]
L$[COST]
Importing Windlights...
+
+
+ No Elements
+ 1 Element
+ [NUM_ELEMENTS] Elements
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index c4c275d776..9c1c15d9b5 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -79,7 +79,7 @@ Detalles del error: la notificación de nombre '[_NAME]' no se ha enco
- Ha habido un error actualizando [APP_NAME]. Por favor, [http://get.secondlife.com descarga la última versión] del Visor.
+ Ha habido un error actualizando [APP_NAME]. Por favor, [https://www.firestormviewer.org/downloads descarga la última versión] del Visor.
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index d62f5b7ecd..d8b82fac14 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -82,7 +82,7 @@ Détails de l'erreur : La notification, appelée '[_NAME]', est i
- Une erreur est survenue lors de la mise à jour de [APP_NAME]. Veuillez [http://get.secondlife.com télécharger la dernière version] du client.
+ Une erreur est survenue lors de la mise à jour de [APP_NAME]. Veuillez [https://www.firestormviewer.org/downloads télécharger la dernière version] du client.
diff --git a/indra/newview/skins/default/xui/fr/panel_experiences.xml b/indra/newview/skins/default/xui/fr/panel_experiences.xml
index b0aceb00d5..a702fd6a86 100644
--- a/indra/newview/skins/default/xui/fr/panel_experiences.xml
+++ b/indra/newview/skins/default/xui/fr/panel_experiences.xml
@@ -1,2 +1,6 @@
-
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/fr/panel_group_general.xml b/indra/newview/skins/default/xui/fr/panel_group_general.xml
index 5953e210e5..e83e46ab98 100644
--- a/indra/newview/skins/default/xui/fr/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_group_general.xml
@@ -1,7 +1,7 @@
- L'onglet Général contient les informations générales et les préférences du groupe ainsi que la liste et les options des membres.
+ L'onglet Général contient les informations générales et les préférences du groupe ainsi que la liste et les options des membres.
Faites glisser le pointeur de la souris sur les options pour en savoir plus.
@@ -11,48 +11,58 @@ Faites glisser le pointeur de la souris sur les options pour en savoir plus.
Extraction des données du résident en cours
-
-
-
- Fondateur :
+
+
+ UUID du groupe :
-
-
+
+
+
+ Fondateur/trice :
+
+
+
+
+ Charte du groupe
+
+
Gratuit
-
-
-
- Indiquez ici la charte de votre groupe
-
-
-
-
-
-
-
- Moi
-
-
- Mon titre :
-
-
-
-
-
-
- Groupe
-
-
-
-
-
-
- - Catégorie de contenu -
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ Paramètres personnels
+
+
+
+
+
+ Mon titre actif :
+
+
+
+
+
+ Paramètres du groupe :
+
+
+
+
+
+
+
+ - Sélectionner la classification du contenu -
+
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 368df127b7..bb3eef9f17 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -31,7 +31,7 @@ Dettagli errore: La notifica denominata '[_NAME]' non è stata trovata
- Il programma [APP_NAME] ha riscontrato un'errore durante il tentativo di aggiornamento. [http://get.secondlife.com Scarica l'ultima versione] del viewer.
+ Il programma [APP_NAME] ha riscontrato un'errore durante il tentativo di aggiornamento. [https://www.firestormviewer.org/downloads Scarica l'ultima versione] del viewer.
Non è possibile collegarsi alla [SECOND_LIFE_GRID].
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index d5b27a2596..5e8f9f85ef 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -81,7 +81,7 @@
- [APP_NAME] をアップデート中にエラーが発生しました。 ビューワの [http://get.secondlife.com 最新バージョンをダウンロード] してください。
+ [APP_NAME] をアップデート中にエラーが発生しました。 ビューワの [https://www.firestormviewer.org/downloads 最新バージョンをダウンロード] してください。
diff --git a/indra/newview/skins/default/xui/pl/floater_fs_asset_blacklist.xml b/indra/newview/skins/default/xui/pl/floater_fs_asset_blacklist.xml
index 9c53693499..d8ceccaac4 100644
--- a/indra/newview/skins/default/xui/pl/floater_fs_asset_blacklist.xml
+++ b/indra/newview/skins/default/xui/pl/floater_fs_asset_blacklist.xml
@@ -33,5 +33,7 @@
+
+
diff --git a/indra/newview/skins/default/xui/pl/floater_joystick.xml b/indra/newview/skins/default/xui/pl/floater_joystick.xml
index d3bded4ab4..e0543a27e0 100644
--- a/indra/newview/skins/default/xui/pl/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/pl/floater_joystick.xml
@@ -1,16 +1,15 @@
-
- nie wykryto urządzenia
+
+ Brak
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/pl/menu_url_group.xml b/indra/newview/skins/default/xui/pl/menu_url_group.xml
index 61ddd37bd5..32f7bd86a3 100644
--- a/indra/newview/skins/default/xui/pl/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_group.xml
@@ -1,6 +1,10 @@
+
+
+
+
diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml
index 1691db195c..569ceced89 100644
--- a/indra/newview/skins/default/xui/pl/notifications.xml
+++ b/indra/newview/skins/default/xui/pl/notifications.xml
@@ -31,7 +31,7 @@ Szczegóły błędu: Błąd o nazwie '[_NAME]' nie został odnaleziony
- Podczas aktualizacji [APP_NAME] wystąpił błąd. Proszę [http://get.secondlife.com odwiedzić stronę] aby ściągnąć ostatnią wersję klienta.
+ Instalacja [APP_NAME] jest uszkodzona. Proszę [https://www.firestormviewer.org/downloads pobrać nową kopię] przeglądarki i ponownie ją zainstalować.
Nie można połączyć z [SECOND_LIFE_GRID].
@@ -3832,6 +3832,9 @@ Jeżeli wciąż masz problemy sprawdź: [SUPPORT_SITE].
- Pamięć Twojego systemu nie spełnia minimalnych wymagań.
+
+ Nie udało się uruchomić usługi aktualizatora [UPDATER_APP]. Sprawdź, czy przeglądarka jest poprawnie zainstalowana i czy ma niezbędne uprawnienia do uruchomienia. Jeśli nadal będziesz mieć problemy, odwiedź [SUPPORT_SITE].
+
Jeśli jesteś właścicielem działki, to możesz ustawić na niej miejsce startu.
W innym przypadku możesz poszukać na mapie miejsc oznaczonych jako "Infohub".
@@ -5108,4 +5111,8 @@ Pamiętaj, że nie można wybrać "otoczenia współdzielonego" i "bazowanego na
Zakończył się zbiorowy import Windlightów.
+
+ Animator Firestorma: [AO_MESSAGE]
+
+
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_UI.xml b/indra/newview/skins/default/xui/pl/panel_preferences_UI.xml
index 82f2e915e5..8d4349ec5e 100644
--- a/indra/newview/skins/default/xui/pl/panel_preferences_UI.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_UI.xml
@@ -98,6 +98,20 @@
+
+ Format czasu:
+
+
+
+
+
+
+
+
+
+
+
+
Paski nawigacji i ulubionych:
diff --git a/indra/newview/skins/default/xui/pl/rlva_strings.xml b/indra/newview/skins/default/xui/pl/rlva_strings.xml
index 4e69243079..4f25d06224 100644
--- a/indra/newview/skins/default/xui/pl/rlva_strings.xml
+++ b/indra/newview/skins/default/xui/pl/rlva_strings.xml
@@ -124,6 +124,11 @@
value
Teleportacja poprzez obiekt '[OBJECT]' nie powiodła się ze względu na ograniczenia RLV
+ blocked_scriptdialog
+
+ value
+ Nie można wyświetlić okna dialogowego lub pola tekstowego skryptu ze względu na ograniczenia RLV
+
blocked_startim
value
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index e292f15d3a..7995b5c62c 100644
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -2625,16 +2625,16 @@ Jeśli ciągle otrzymujesz tą wiadomość, to skontaktuj się z pomocą technic
Rezydent, do którego wysłałeś/aś wiadomość prywatną znajduje się w trybie zajętości i nie chce, aby mu przeszkadzano. Oznacza to, iż Twoja wiadomość zostanie zapisana do przejrzenia na później.
- Rezydent, do którego wysłałeś/aś wiadomość prywatną aktywował w Firestormie tryb autoodpowiedzi i nie chce, aby mu przeszkadzano. Oznacza to, iż Twoja wiadomość zostanie zapisana do przejrzenia na później.
+ Rezydent, do którego wysłałeś/aś wiadomość prywatną aktywował w przeglądarce [APP_NAME] tryb autoodpowiedzi i nie chce, aby mu przeszkadzano. Oznacza to, iż Twoja wiadomość zostanie zapisana do przejrzenia na później.
- Rezydent, do którego wysłałeś/aś wiadomość prywatną aktywował w Firestormie tryb autoodpowiedzi i nie chce, aby mu przeszkadzano. Oznacza to, iż Twoja wiadomość zostanie zapisana do przejrzenia na później.
+ Rezydent, do którego wysłałeś/aś wiadomość prywatną aktywował w przeglądarce [APP_NAME] tryb autoodpowiedzi i nie chce, aby mu przeszkadzano. Oznacza to, iż Twoja wiadomość zostanie zapisana do przejrzenia na później.
- Rezydent, do którego wysłałeś/aś wiadomość aktywował w Firestormie tryb odrzucania próśb oraz propozycji teleportacji i nie chce, aby mu nimi przeszkadzano. Możesz w dalszym ciągu wysłać wiadomość prywatną ręcznie.
+ Rezydent, do którego wysłałeś/aś wiadomość aktywował w przeglądarce [APP_NAME] tryb odrzucania próśb oraz propozycji teleportacji i nie chce, aby mu nimi przeszkadzano. Możesz w dalszym ciągu wysłać wiadomość prywatną ręcznie.
- Rezydent, do którego wysłałeś/aś wiadomość aktywował w Firestormie tryb odrzucania zaproszeń do znajomych i nie chce, aby mu nimi przeszkadzano. Możesz w dalszym ciągu wysłać wiadomość prywatną ręcznie.
+ Rezydent, do którego wysłałeś/aś wiadomość aktywował w przeglądarce [APP_NAME] tryb odrzucania zaproszeń do znajomych i nie chce, aby mu nimi przeszkadzano. Możesz w dalszym ciągu wysłać wiadomość prywatną ręcznie.
Rezydent, do którego wysłałeś/aś wiadomość zablokował Cię.
@@ -5980,10 +5980,10 @@ do sekcji wsparcia witryny SecondLife.com i zgłoś problem.
Nieznana, poza normalnym zakresem, sprawdź ustawienie debugowania RenderQualityPerformance
- Firestorm nie może utworzyć Mostu LSL, jeśli "Włącz Most w LScript Language" jest wyłączone w Ustawieniach.
+ [APP_NAME] nie może utworzyć Mostu LSL, jeśli "Włącz Most w LScript Language" jest wyłączone w Ustawieniach.
- Firestorm nie mógł utworzyć Mostu LSL. Włącz swoją Bibliotekę i zaloguj się ponownie.
+ [APP_NAME] nie mógł utworzyć Mostu LSL. Włącz swoją Bibliotekę i zaloguj się ponownie.
Tworzenie Mostu LSL już trwa, nie można rozpocząć procesu budowania kolejnego. Poczekaj kilka minut, zanim spróbujesz ponownie.
@@ -6059,11 +6059,29 @@ Twoja aktualna pozycja: [AVATAR_POS]
Info o skryptach: Otrzymano uszkodzoną odpowiedź od Mostu LSL. Spróbuj ponownie.
- UWAGA: Jeden lub więcej skryptów zostało dodanych do Twojego Mostu LSL Firestorma! Jeśli ta wiadomość jest niespodziewana, to stwórz teraz Most LSL na nowo ('Kondycja awatara' w menu 'Awatar' na górze).
+ UWAGA: Jeden lub więcej skryptów został dodanych do Twojego Mostu LSL! Jeśli ta wiadomość jest niespodziewana, to stwórz teraz Most LSL na nowo ('Kondycja awatara' w menu 'Awatar' na górze).
UWAGA: Skrypt Mostu LSL używa starej maszyny wirtualnej LSO (16 KB limitu pamięci) zamiast nowej Mono, co stwarza wysokie prawdopodobieństwo kolizji sterty i stosu oraz awarii Mostu poprzez wyczerpanie się pamięci. Spróbuj stworzyć go na nowo ('Kondycja awatara' w menu 'Awatar' na górze). Jeśli ten komunikat pojawi się ponownie spróbuj jeszcze raz w innym regionie.
+
+ Animator przeglądarki [APP_NAME] włączony.
+
+
+ Animator przeglądarki [APP_NAME] wyłączony.
+
+
+ Wstrzymany przez oskryptowany dodatek.
+
+
+ Wznowiony przez oskryptowany dodatek.
+
+
+ Animacje stania w miejscu wstrzymane przez oskryptowany dodatek.
+
+
+ Animacje stania w miejscu wznowione przez oskryptowany dodatek.
+
Pole widzenia
@@ -6419,4 +6437,13 @@ Twoja aktualna pozycja: [AVATAR_POS]
Importowanie Windlightów...
+
+ Brak elementów
+
+
+ 1 element
+
+
+ [NUM_ELEMENTS] elementów
+
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index 25d2ee3052..56f61724fc 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -81,7 +81,7 @@ Detalhes do erro: O aviso '[_NAME]' não foi localizado no arquivo not
- Um erro ocorreu ao atualizar o [APP_NAME]. [http://get.secondlife.com Baixe a versão atual] do Visualizador.
+ Um erro ocorreu ao atualizar o [APP_NAME]. [https://www.firestormviewer.org/downloads Baixe a versão atual] do Visualizador.
diff --git a/indra/newview/skins/default/xui/ru/floater_fs_asset_blacklist.xml b/indra/newview/skins/default/xui/ru/floater_fs_asset_blacklist.xml
index e144adb338..6b7713bc5a 100644
--- a/indra/newview/skins/default/xui/ru/floater_fs_asset_blacklist.xml
+++ b/indra/newview/skins/default/xui/ru/floater_fs_asset_blacklist.xml
@@ -33,6 +33,8 @@
-
+
+
+
diff --git a/indra/newview/skins/default/xui/ru/floater_joystick.xml b/indra/newview/skins/default/xui/ru/floater_joystick.xml
index bf0bbf8cba..0f50433064 100644
--- a/indra/newview/skins/default/xui/ru/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/ru/floater_joystick.xml
@@ -1,16 +1,15 @@
-
- устройство не выбрано
+
+ никто
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -38,10 +37,10 @@
Масштаб по Z
- Масштаб уклона
+ Масштаб наклона
- Масштаб сгиба
+ Масштаб рыскания
Масштаб вращения
@@ -56,10 +55,10 @@
Невидимая зона по Z
- Невид. зона уклона
+ Невид. зона наклона
- Невид. зона сгиба
+ Невид. зона рыскания
Невид. зона вращения
diff --git a/indra/newview/skins/default/xui/ru/menu_url_group.xml b/indra/newview/skins/default/xui/ru/menu_url_group.xml
index 6b09459181..a36e55bfc0 100644
--- a/indra/newview/skins/default/xui/ru/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_group.xml
@@ -1,6 +1,10 @@
+
+
+
+
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index fa727883d2..04bab8a57b 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -37,7 +37,7 @@
[MESSAGE]
- Произошла ошибка при обновлении [APP_NAME]. [http://get.secondlife.com Загрузите последнюю версию] клиента.
+ Произошла ошибка при обновлении [APP_NAME]. [https://www.firestormviewer.org/downloads Загрузите последнюю версию] клиента.
Не удалось подключиться к [SECOND_LIFE_GRID].
@@ -3937,6 +3937,9 @@ URL: [AUDIOURL]
- Системная память вашего компьютера не удовлетворяет минимальным требованиям.
+
+ Не удалось запустить службу обновления [UPDATER_APP]. Убедитесь, что программа просмотра установлена правильно и имеет необходимые разрешения для запуска. Если у вас по-прежнему возникают проблемы, посетите [SUPPORT_SITE].
+
Если у вас есть участок земли, вы можете сделать его своим домом (домашним местоположением).
Если нет, посмотрите на карту и найдите места, подписанные "Инфохаб".
@@ -5224,4 +5227,8 @@ URL: [AUDIOURL]
Массовый импорт Окружающей среды завершен.
+
+ Диспетчер анимаций (AO): [AO_MESSAGE]
+
+
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_UI.xml b/indra/newview/skins/default/xui/ru/panel_preferences_UI.xml
index 73bc9e014a..7c8d8529bf 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_UI.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_UI.xml
@@ -102,6 +102,20 @@
+
+ Формат времени:
+
+
+
+
+
+
+
+
+
+
+
+
Панель навигации и закладок:
diff --git a/indra/newview/skins/default/xui/ru/rlva_strings.xml b/indra/newview/skins/default/xui/ru/rlva_strings.xml
index 76a29d7ab2..9f80ba7cd0 100644
--- a/indra/newview/skins/default/xui/ru/rlva_strings.xml
+++ b/indra/newview/skins/default/xui/ru/rlva_strings.xml
@@ -136,6 +136,11 @@
value
'[OBJECT]' было отказано в разрешении телепортировать вас из-за ограничений RLV
+ blocked_scriptdialog
+
+ value
+ Невозможно отобразить диалоговое окно или текстовое поле скрипта из-за ограничений RLV
+
blocked_startim
value
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 80df0a6de9..c1b14f96ec 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -1841,7 +1841,7 @@ http://www.firestormviewer.org/support за помощь в решении эт
Плата зависит от вашего уровня подписки. С подписок более высокого уровня взимаются более низкие сборы. [https://secondlife.com/my/account/membership.php? Узнать больше]
- Открыть сохраненные локации
+ Открыть сохраненные локации
Несвязанные
@@ -6592,10 +6592,10 @@ http://www.firestormviewer.org/support за помощь в решении эт
Неизвестное, за пределами нормального диапазона, проверьте настройки отладки RenderQualityPerformance
- Firestorm не может создать мост LSL если "Активировать мост LSL" отключено в настройках.
+ [APP_NAME] не может создать мост LSL если "Активировать мост LSL" отключено в настройках.
- Firestorm не может создать мост LSL. Пожалуйста включите библиотеку и перезайдите.
+ [APP_NAME] не может создать мост LSL. Пожалуйста включите библиотеку и перезайдите.
Создание моста в процессе. Пожалуйста, подождите несколько минут, прежде чем пытаться снова.
@@ -6607,19 +6607,19 @@ http://www.firestormviewer.org/support за помощь в решении эт
Мост не создан. Скрипт моста не может быть создан.
- Мост не создан. Мост назван неправильно. Используйте меню Firestorm 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
+ Мост не создан. Мост назван неправильно. Используйте меню [APP_NAME] 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
- Мост не создается. Мост не найден в инвентаре. Используйте меню Firestorm 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
+ Мост не создается. Мост не найден в инвентаре. Используйте меню [APP_NAME] 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
- Мост не удалось присоединить. Это не текущая версия моста. Используйте меню Firestorm 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
+ Мост не удалось присоединить. Это не текущая версия моста. Используйте меню [APP_NAME] 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
- Мост не удалось присоединить. Мост не был найден в нужном месте инвентаря. Используйте меню Firestorm 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
+ Мост не удалось присоединить. Мост не был найден в нужном месте инвентаря. Используйте меню [APP_NAME] 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
- Мост не удалось присоединить. Что-то еще использует место крепления моста. Используйте меню Firestorm 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
+ Мост не удалось присоединить. Что-то еще использует место крепления моста. Используйте меню [APP_NAME] 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
Объект моста не найден. Невозможно приступить к его созданию.
@@ -6628,7 +6628,7 @@ http://www.firestormviewer.org/support за помощь в решении эт
Инвентарь моста содержит непредвиденные предметы.
- Мост не закончил создание, используйте меню Firestorm 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
+ Мост не закончил создание, используйте меню [APP_NAME] 'Аватар/Исправление аватара/Пересоздать LSL мост', чтобы пересоздать мост.
Мост отсоединен
@@ -6671,11 +6671,20 @@ ID объекта: [INSPECTING_KEY]
Информация скрипта: Поступил неправильный ответ от моста. Попробуйте еще раз.
- ВНИМАНИЕ: Один или несколько скриптов были добавлены в ваш мост Firestorm! Если вы не ожидали этого сообщения, воспользуйтесь параметром меню Firestorm «Аватар/ Исправление аватара/Пересоздать LSL мост», чтобы заново создать мост.
+ ВНИМАНИЕ: Один или несколько скриптов были добавлены в ваш мост [APP_NAME]! Если вы не ожидали этого сообщения, воспользуйтесь параметром меню [APP_NAME] «Аватар/ Исправление аватара/Пересоздать LSL мост», чтобы заново создать мост.
- ВНИМАНИЕ: В скрипт моста использует старый LSO (ограничение памяти 16 КБ) вместо новой виртуальной машины Mono (ограничение памяти 64 КБ), что создает высокую вероятность коллизии стека и сбоя моста из-за нехватки памяти. Пожалуйста, используйте пункт меню Firestorm «Аватар/Исправление аватара/Пересоздать LSL мост» для воссоздания моста. Если вы снова увидите это сообщение - попробуйте еще раз в другом регионе.
+ ВНИМАНИЕ: В скрипт моста использует старый LSO (ограничение памяти 16 КБ) вместо новой виртуальной машины Mono (ограничение памяти 64 КБ), что создает высокую вероятность коллизии стека и сбоя моста из-за нехватки памяти. Пожалуйста, используйте пункт меню [APP_NAME] «Аватар/Исправление аватара/Пересоздать LSL мост» для воссоздания моста. Если вы снова увидите это сообщение - попробуйте еще раз в другом регионе.
+
+
+ Диспетчер анимаций [APP_NAME] включен.
+ Диспетчер анимаций [APP_NAME] выключен.
+ Приостановлено прикрепленным скриптом.
+ Возобновлено прикрепленным скриптом.
+ Стоячие анимации приостановлены прикрепленным скриптом.
+ Стоячие анимации возобновлены прикрепленным скриптом.
+
Дальность прорисовки
@@ -7028,4 +7037,9 @@ ID объекта: [INSPECTING_KEY]
Импорт окружающей среды ...
+
+
+ Нет элементов
+ 1 элемент
+ [NUM_ELEMENTS] элементов
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 8ebbd2ea6f..9d8e4f8c4a 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -82,7 +82,7 @@ Hata ayrıntıları: '[_NAME]' adlı bildirim notifications.xml içind
- [APP_NAME] güncellenirken bir hata oluştu. Lütfen Görüntüleyici'nin [http://get.secondlife.com son sürümünü karşıdan yükleyin].
+ [APP_NAME] güncellenirken bir hata oluştu. Lütfen Görüntüleyici'nin [https://www.firestormviewer.org/downloads son sürümünü karşıdan yükleyin].
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index 6387ba7878..e2a959859e 100644
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -82,7 +82,7 @@
- [APP_NAME] 更新時出錯。 請 [http://get.secondlife.com 下載] 最新版本的 Viewer。
+ [APP_NAME] 更新時出錯。 請 [https://www.firestormviewer.org/downloads 下載] 最新版本的 Viewer。
diff --git a/indra/newview/skins/starlight/xui/en/panel_group_notices.xml b/indra/newview/skins/starlight/xui/en/panel_group_notices.xml
index 381bc5cc9e..b5404023d9 100644
--- a/indra/newview/skins/starlight/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/starlight/xui/en/panel_group_notices.xml
@@ -44,6 +44,7 @@ Maximum 200 per group daily
right="-1"
name="notice_list"
sort_ascending="false"
+ sort_lazily="true"
sort_column="4"
top_pad="0"
width="304">
diff --git a/indra/newview/skins/starlight/xui/en/panel_status_bar.xml b/indra/newview/skins/starlight/xui/en/panel_status_bar.xml
index 30e50a876c..ad7da6fde1 100644
--- a/indra/newview/skins/starlight/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/starlight/xui/en/panel_status_bar.xml
@@ -336,7 +336,7 @@
font="SansSerifSmall"
text_color="TimeTextColor"
follows="right|top"
- halign="left"
+ halign="center"
height="16"
h_pad="2"
top="4"
diff --git a/indra/newview/skins/starlightcui/xui/en/panel_group_notices.xml b/indra/newview/skins/starlightcui/xui/en/panel_group_notices.xml
index 381bc5cc9e..b5404023d9 100644
--- a/indra/newview/skins/starlightcui/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/starlightcui/xui/en/panel_group_notices.xml
@@ -44,6 +44,7 @@ Maximum 200 per group daily
right="-1"
name="notice_list"
sort_ascending="false"
+ sort_lazily="true"
sort_column="4"
top_pad="0"
width="304">
diff --git a/indra/newview/skins/starlightcui/xui/en/panel_status_bar.xml b/indra/newview/skins/starlightcui/xui/en/panel_status_bar.xml
index 7228f074ae..e911fc9b6c 100644
--- a/indra/newview/skins/starlightcui/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/starlightcui/xui/en/panel_status_bar.xml
@@ -332,7 +332,7 @@
font="SansSerifSmall"
text_color="TimeTextColor"
follows="right|top"
- halign="left"
+ halign="center"
height="16"
h_pad="2"
top="4"