Merge branch 'rlva/feature/effect-sphere' into rlva/development
commit
35564009af
|
|
@ -1344,6 +1344,14 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("sunAngle2");
|
||||
|
||||
mReservedUniforms.push_back("camPosLocal");
|
||||
// [RLVa:KB] - @setsphere
|
||||
mReservedUniforms.push_back("rlvEffectMode");
|
||||
mReservedUniforms.push_back("rlvEffectParam1");
|
||||
mReservedUniforms.push_back("rlvEffectParam2");
|
||||
mReservedUniforms.push_back("rlvEffectParam3");
|
||||
mReservedUniforms.push_back("rlvEffectParam4");
|
||||
mReservedUniforms.push_back("rlvEffectParam5");
|
||||
// [/RLV:KB]
|
||||
|
||||
mReservedUniforms.push_back("gWindDir");
|
||||
mReservedUniforms.push_back("gSinWaveParams");
|
||||
|
|
|
|||
|
|
@ -205,6 +205,14 @@ public:
|
|||
WATER_SUN_ANGLE2,
|
||||
|
||||
WL_CAMPOSLOCAL,
|
||||
// [RLVa:KB] - @setsphere
|
||||
RLV_EFFECT_MODE,
|
||||
RLV_EFFECT_PARAM1,
|
||||
RLV_EFFECT_PARAM2,
|
||||
RLV_EFFECT_PARAM3,
|
||||
RLV_EFFECT_PARAM4,
|
||||
RLV_EFFECT_PARAM5,
|
||||
// [/RLVa:KB]
|
||||
|
||||
AVATAR_WIND,
|
||||
AVATAR_SINWAVE,
|
||||
|
|
|
|||
|
|
@ -731,14 +731,14 @@ set(viewer_SOURCE_FILES
|
|||
pipeline.cpp
|
||||
rlvactions.cpp
|
||||
rlvenvironment.cpp
|
||||
rlvhandler.cpp
|
||||
rlvhelper.cpp
|
||||
rlvcommon.cpp
|
||||
rlvlocks.cpp
|
||||
rlvinventory.cpp
|
||||
rlveffects.cpp
|
||||
rlvextensions.cpp
|
||||
rlvfloaters.cpp
|
||||
rlvmodifiers.cpp
|
||||
rlvhandler.cpp
|
||||
rlvhelper.cpp
|
||||
rlvinventory.cpp
|
||||
rlvlocks.cpp
|
||||
rlvui.cpp
|
||||
)
|
||||
|
||||
|
|
@ -1365,15 +1365,16 @@ set(viewer_HEADER_FILES
|
|||
noise.h
|
||||
pipeline.h
|
||||
rlvactions.h
|
||||
rlvenvironment.h
|
||||
rlvdefines.h
|
||||
rlvhandler.h
|
||||
rlvhelper.h
|
||||
rlvcommon.h
|
||||
rlvlocks.h
|
||||
rlvinventory.h
|
||||
rlvdefines.h
|
||||
rlveffects.h
|
||||
rlvenvironment.h
|
||||
rlvextensions.h
|
||||
rlvfloaters.h
|
||||
rlvhandler.h
|
||||
rlvhelper.h
|
||||
rlvinventory.h
|
||||
rlvlocks.h
|
||||
rlvmodifiers.h
|
||||
rlvui.h
|
||||
roles_constants.h
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
*
|
||||
* 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 color (not used for blur)
|
||||
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_COLOUR rlvEffectParam4.rgb
|
||||
#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 image, vec2 uv, 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 += texture2D(image, uv) * 0.1964825501511404;
|
||||
|
||||
color += texture2D(image, uv + off1) * 0.2969069646728344;
|
||||
color += texture2D(image, uv - off1) * 0.2969069646728344;
|
||||
|
||||
color += texture2D(image, uv + off2) * 0.09447039785044732;
|
||||
color += texture2D(image, uv - off2) * 0.09447039785044732;
|
||||
|
||||
color += texture2D(image, uv + off3) * 0.010381362401148057;
|
||||
color += texture2D(image, uv - off3) * 0.010381362401148057;
|
||||
|
||||
return color.xyz;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 fragTC = vary_fragcoord.st;
|
||||
float fragDepth = texture2DRect(depthMap, fragTC).x;
|
||||
vec3 fragPosLocal = getPosition_d(fragTC, fragDepth).xyz;
|
||||
vec3 fragColor = texture2DRect(diffuseRect, fragTC).rgb;
|
||||
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);
|
||||
|
||||
switch (rlvEffectMode)
|
||||
{
|
||||
case 0: // Blend
|
||||
fragColor = mix(fragColor, SPHERE_COLOUR, effectStrength);
|
||||
break;
|
||||
case 1: // Blur
|
||||
fragColor = blur13(diffuseRect, fragTC, effectStrength * BLUR_DIRECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
frag_color.rgb = fragColor;
|
||||
frag_color.a = 0.0;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -618,7 +618,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::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
|
||||
LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
|
||||
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
|
||||
|
|
|
|||
|
|
@ -419,9 +419,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();
|
||||
|
|
@ -443,7 +455,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();
|
||||
|
|
@ -647,7 +662,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));
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@
|
|||
#include "llpostprocess.h"
|
||||
#include "llscenemonitor.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]
|
||||
|
||||
|
|
@ -1046,6 +1047,15 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
{
|
||||
gPipeline.renderDeferredLighting(&gPipeline.mScreen);
|
||||
}
|
||||
// [RLVa:KB] - @setsphere
|
||||
else if (LLRenderTarget::sUseFBO && LLPipeline::sUseDepthTexture)
|
||||
{
|
||||
if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE))
|
||||
{
|
||||
LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere);
|
||||
}
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
LLPipeline::sUnderWaterRender = FALSE;
|
||||
|
||||
|
|
@ -1323,9 +1333,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();
|
||||
|
|
|
|||
|
|
@ -246,6 +246,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];
|
||||
|
|
@ -341,6 +344,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()
|
||||
|
|
@ -4087,6 +4093,9 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
|
|||
gWLCloudProgram.unload();
|
||||
gWLSunProgram.unload();
|
||||
gWLMoonProgram.unload();
|
||||
// [RLVa:KB] - @setsphere
|
||||
gRlvSphereProgram.unload();
|
||||
// [/RLVa:KB]
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -4120,6 +4129,18 @@ 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));
|
||||
gRlvSphereProgram.mShaderFiles.push_back(make_pair("deferred/rlvF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||
gRlvSphereProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
|
||||
success = gRlvSphereProgram.createShader(NULL, NULL);
|
||||
}
|
||||
// [/RLV:KB]
|
||||
|
||||
if (success)
|
||||
{
|
||||
gWLSunProgram.mName = "Windlight Sun Program";
|
||||
|
|
|
|||
|
|
@ -333,6 +333,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];
|
||||
|
|
|
|||
|
|
@ -214,6 +214,8 @@
|
|||
#include "llcleanup.h"
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c)
|
||||
#include "rlvactions.h"
|
||||
#include "rlveffects.h"
|
||||
#include "rlvhandler.h"
|
||||
// [/RLVa:KB]
|
||||
|
||||
|
|
@ -5692,11 +5694,12 @@ void LLPickInfo::fetchResults()
|
|||
mPickPt = mMousePt;
|
||||
|
||||
// [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay)
|
||||
if ( (gRlvHandler.isEnabled()) && (hit_object) && (!hit_object->isHUDAttachment()) )
|
||||
if ( (RlvActions::hasBehaviour(RLV_BHVR_SETOVERLAY)) && (hit_object) && (!hit_object->isHUDAttachment()) )
|
||||
{
|
||||
if (gRlvHandler.hitTestOverlay(mMousePt))
|
||||
if (auto* pOverlayEffect = LLVfxManager::instance().getEffect<RlvOverlayEffect>(EVisualEffect::RlvOverlay))
|
||||
{
|
||||
hit_object = nullptr;
|
||||
if (pOverlayEffect->hitTest(mMousePt))
|
||||
hit_object = nullptr;
|
||||
}
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
@ -362,6 +363,9 @@ F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f;
|
|||
// [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;
|
||||
|
|
@ -987,8 +991,21 @@ 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;
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
// mDeferredDepth.release();
|
||||
// mOcclusionDepth.release();
|
||||
|
||||
if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
|
||||
}
|
||||
|
|
@ -4478,7 +4495,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;
|
||||
|
|
@ -9118,6 +9145,12 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)
|
|||
}
|
||||
|
||||
screen_target->flush();
|
||||
// [RLVa:KB] - @setsphere
|
||||
if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE))
|
||||
{
|
||||
LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere);
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
}
|
||||
|
||||
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
|
||||
|
|
|
|||
|
|
@ -605,6 +605,9 @@ public:
|
|||
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
|
||||
static bool sRenderTextures;
|
||||
// [/SL:KB]
|
||||
// [RLVa:KB] - @setsphere
|
||||
static bool sUseDepthTexture;
|
||||
// [/RLVa:KB]
|
||||
|
||||
static LLTrace::EventStatHandle<S64> sStatBatchSize;
|
||||
|
||||
|
|
|
|||
|
|
@ -243,12 +243,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 +255,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)
|
||||
|
|
@ -286,6 +279,26 @@ 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
|
||||
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
|
||||
|
||||
Unknown,
|
||||
};
|
||||
|
||||
enum ERlvBehaviourOptionType
|
||||
{
|
||||
RLV_OPTION_NONE, // Behaviour takes no parameters
|
||||
|
|
|
|||
|
|
@ -0,0 +1,411 @@
|
|||
/**
|
||||
*
|
||||
* 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))
|
||||
{
|
||||
if (RlvObject* pRlvObj = gRlvHandler.getObject(idRlvObj))
|
||||
{
|
||||
float nAlpha;
|
||||
if (pRlvObj->getModifierValue<float>(ERlvLocalBhvrModifier::OverlayAlpha, nAlpha))
|
||||
m_nAlpha = nAlpha;
|
||||
|
||||
pRlvObj->getModifierValue<bool>(ERlvLocalBhvrModifier::OverlayTouch, m_fBlockTouch);
|
||||
|
||||
LLVector3 vecColor;
|
||||
if (pRlvObj->getModifierValue<LLVector3>(ERlvLocalBhvrModifier::OverlayTint, vecColor))
|
||||
m_Color = LLColor3(vecColor.mV);
|
||||
|
||||
LLUUID idTexture;
|
||||
if ( (pRlvObj) && (pRlvObj->getModifierValue<LLUUID>(ERlvLocalBhvrModifier::OverlayTexture, idTexture)) )
|
||||
setImage(idTexture);
|
||||
}
|
||||
}
|
||||
|
||||
RlvOverlayEffect::~RlvOverlayEffect()
|
||||
{
|
||||
clearImage();
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvOverlayEffect::onAlphaValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvOverlayEffect* pEffect = dynamic_cast<RlvOverlayEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_nAlpha = (newValue) ? boost::get<float>(newValue.value()) : c_DefaultAlpha;
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvOverlayEffect::onBlockTouchValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvOverlayEffect* pEffect = dynamic_cast<RlvOverlayEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_fBlockTouch = (newValue) ? boost::get<bool>(newValue.value()) : false;
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
// static
|
||||
ERlvCmdRet RlvOverlayEffect::onColorValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvOverlayEffect* pEffect = dynamic_cast<RlvOverlayEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_Color = LLColor3( (newValue) ? boost::get<LLVector3>(newValue.value()).mV : c_DefaultColor);
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvOverlayEffect::onTextureChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvOverlayEffect* pEffect = dynamic_cast<RlvOverlayEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
if (newValue)
|
||||
pEffect->setImage(boost::get<LLUUID>(newValue.value()));
|
||||
else
|
||||
pEffect->clearImage();
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
void RlvOverlayEffect::clearImage()
|
||||
{
|
||||
if (m_pImage)
|
||||
{
|
||||
m_pImage->setBoostLevel(m_nImageOrigBoost);
|
||||
m_pImage = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool RlvOverlayEffect::hitTest(const LLCoordGL& ptMouse) const
|
||||
{
|
||||
if (!m_pImage)
|
||||
return false;
|
||||
|
||||
return (m_fBlockTouch) && (m_pImage->getMask(LLVector2((float)ptMouse.mX / gViewerWindow->getWorldViewWidthScaled(), (float)ptMouse.mY / gViewerWindow->getWorldViewHeightScaled())));
|
||||
}
|
||||
|
||||
void RlvOverlayEffect::setImage(const LLUUID& idTexture)
|
||||
{
|
||||
if ( (m_pImage) && (m_pImage->getID() == idTexture) )
|
||||
return;
|
||||
|
||||
clearImage();
|
||||
m_pImage = LLViewerTextureManager::getFetchedTexture(idTexture, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
m_nImageOrigBoost = m_pImage->getBoostLevel();
|
||||
m_pImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
|
||||
m_pImage->forceToSaveRawImage(0);
|
||||
}
|
||||
|
||||
void RlvOverlayEffect::run()
|
||||
{
|
||||
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[3] = { 0.0f, 0.0f, 0.0f };
|
||||
const float c_SphereDefaultDistance = 0.0f;
|
||||
const int c_SphereDefaultDistanceExtend = 0;
|
||||
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_Color(LLColor3(c_SphereDefaultColor))
|
||||
, m_nDistanceMin(c_SphereDefaultDistance), m_nDistanceMax(c_SphereDefaultDistance)
|
||||
, m_eDistExtend((ESphereDistExtend)0)
|
||||
, m_nValueMin(c_SphereDefaultAlpha), m_nValueMax(c_SphereDefaultAlpha)
|
||||
{
|
||||
if (RlvObject* pRlvObj = gRlvHandler.getObject(idRlvObj))
|
||||
{
|
||||
int nNumber;
|
||||
if (pRlvObj->getModifierValue<int>(ERlvLocalBhvrModifier::SphereMode, nNumber))
|
||||
m_eMode = (ESphereMode)nNumber;
|
||||
if (pRlvObj->getModifierValue<int>(ERlvLocalBhvrModifier::SphereOrigin, nNumber))
|
||||
m_eOrigin = (ESphereOrigin)nNumber;
|
||||
|
||||
LLVector3 vecColor;
|
||||
if (pRlvObj->getModifierValue<LLVector3>(ERlvLocalBhvrModifier::SphereColor, vecColor))
|
||||
m_Color = LLColor3(vecColor.mV);
|
||||
|
||||
float nFloat;
|
||||
if (pRlvObj->getModifierValue<float>(ERlvLocalBhvrModifier::SphereDistMin, nFloat))
|
||||
m_nDistanceMin = nFloat;
|
||||
if (pRlvObj->getModifierValue<float>(ERlvLocalBhvrModifier::SphereDistMax, nFloat))
|
||||
m_nDistanceMax = nFloat;
|
||||
if (pRlvObj->getModifierValue<int>(ERlvLocalBhvrModifier::SphereDistExtend, nNumber))
|
||||
m_eDistExtend = (ESphereDistExtend)nNumber;
|
||||
|
||||
if (pRlvObj->getModifierValue<float>(ERlvLocalBhvrModifier::SphereValueMin, nFloat))
|
||||
m_nValueMin = nFloat;
|
||||
if (pRlvObj->getModifierValue<float>(ERlvLocalBhvrModifier::SphereValueMax, nFloat))
|
||||
m_nValueMax = nFloat;
|
||||
}
|
||||
}
|
||||
|
||||
RlvSphereEffect::~RlvSphereEffect()
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvSphereEffect::onModeChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_eMode = (ESphereMode)((newValue) ? boost::get<int>(newValue.value()) : c_SphereDefaultMode);
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvSphereEffect::onOriginChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_eOrigin = (ESphereOrigin)((newValue) ? boost::get<int>(newValue.value()) : c_SphereDefaultOrigin);
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvSphereEffect::onColorChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_Color = LLColor3((newValue) ? boost::get<LLVector3>(newValue.value()).mV : c_SphereDefaultColor);
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvSphereEffect::onDistMinChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_nDistanceMin = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultDistance;
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvSphereEffect::onDistMaxChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_nDistanceMax = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultDistance;
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvSphereEffect::onDistExtendChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_eDistExtend = (ESphereDistExtend)((newValue) ? boost::get<int>(newValue.value()) : c_SphereDefaultDistanceExtend);
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvSphereEffect::onValueMinChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_nValueMin = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultAlpha;
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// static
|
||||
ERlvCmdRet RlvSphereEffect::onValueMaxChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue)
|
||||
{
|
||||
if (RlvSphereEffect* pEffect = dynamic_cast<RlvSphereEffect*>(LLVfxManager::instance().getEffect(idRlvObj)))
|
||||
{
|
||||
pEffect->m_nValueMax = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultAlpha;
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
void RlvSphereEffect::setShaderUniforms(LLGLSLShader* pShader, LLRenderTarget* pRenderTarget)
|
||||
{
|
||||
pShader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, get_current_projection().inverse().m);
|
||||
pShader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, pRenderTarget->getWidth(), pRenderTarget->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 = gGL.getModelviewMatrix();
|
||||
mvMatrix.mult_matrix_vec(posSphereOriginGl);
|
||||
pShader->uniform4fv(LLShaderMgr::RLV_EFFECT_PARAM1, 1, posSphereOriginGl.v);
|
||||
|
||||
// Pack min/max distance and alpha together
|
||||
const glh::vec4f sphereParams(m_nValueMin, m_nDistanceMin, m_nValueMax, m_nDistanceMax);
|
||||
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 color
|
||||
const glh::vec4f sphereColor(m_Color.mV, 1.0);
|
||||
pShader->uniform4fv(LLShaderMgr::RLV_EFFECT_PARAM4, 1, sphereColor.v);
|
||||
}
|
||||
|
||||
void RlvSphereEffect::renderPass(LLGLSLShader* pShader) const
|
||||
{
|
||||
gPipeline.mScreen.bindTarget();
|
||||
|
||||
S32 nDiffuseChannel = pShader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, gPipeline.mScreen.getUsage());
|
||||
if (nDiffuseChannel > -1)
|
||||
{
|
||||
gPipeline.mScreen.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);
|
||||
|
||||
gPipeline.mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
|
||||
gPipeline.mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
|
||||
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.popMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
gGL.popMatrix();
|
||||
|
||||
pShader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, gPipeline.mScreen.getUsage());
|
||||
pShader->disableTexture(LLShaderMgr::DEFERRED_DEPTH, gPipeline.mScreen.getUsage());
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(0)->activate();
|
||||
|
||||
gPipeline.mScreen.flush();
|
||||
}
|
||||
|
||||
LLTrace::BlockTimerStatHandle FTM_RLV_EFFECT_SPHERE("Post-process (RLVa sphere)");
|
||||
|
||||
void RlvSphereEffect::run()
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RLV_EFFECT_SPHERE);
|
||||
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
|
||||
|
||||
gRlvSphereProgram.bind();
|
||||
setShaderUniforms(&gRlvSphereProgram, &gPipeline.mScreen);
|
||||
|
||||
switch (m_eMode)
|
||||
{
|
||||
case ESphereMode::Blend:
|
||||
renderPass(&gRlvSphereProgram);
|
||||
break;
|
||||
case ESphereMode::Blur:
|
||||
gRlvSphereProgram.uniform2f(LLShaderMgr::RLV_EFFECT_PARAM5, 1.f, 0.f);
|
||||
renderPass(&gRlvSphereProgram);
|
||||
gRlvSphereProgram.uniform2f(LLShaderMgr::RLV_EFFECT_PARAM5, 0.f, 1.f);
|
||||
renderPass(&gRlvSphereProgram);
|
||||
break;
|
||||
}
|
||||
|
||||
gRlvSphereProgram.unbind();
|
||||
}
|
||||
|
||||
// ====================================================================================
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/**
|
||||
*
|
||||
* 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() override;
|
||||
void tweenAlpha(float endAlpha, double duration) { m_nAlpha.start(endAlpha, duration); }
|
||||
void tweenColor(LLColor3 endColor, double duration) { m_Color.start(endColor, duration); }
|
||||
static ERlvCmdRet onAlphaValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
static ERlvCmdRet onBlockTouchValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
static ERlvCmdRet onColorValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
static ERlvCmdRet onTextureChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
protected:
|
||||
void clearImage();
|
||||
void setImage(const LLUUID& idTexture);
|
||||
|
||||
/*
|
||||
* Member variables
|
||||
*/
|
||||
protected:
|
||||
LLTweenableValueLerp<float> m_nAlpha;
|
||||
bool m_fBlockTouch;
|
||||
LLTweenableValueLerp<LLColor3> m_Color;
|
||||
|
||||
LLPointer<LLViewerFetchedTexture> m_pImage = nullptr;
|
||||
int m_nImageOrigBoost = 0;
|
||||
};
|
||||
|
||||
// ====================================================================================
|
||||
// RlvSphereEffect class
|
||||
//
|
||||
|
||||
class RlvSphereEffect : public LLVisualEffect
|
||||
{
|
||||
public:
|
||||
RlvSphereEffect(const LLUUID& idRlvObj);
|
||||
~RlvSphereEffect();
|
||||
|
||||
public:
|
||||
void run() override;
|
||||
static ERlvCmdRet onModeChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
static ERlvCmdRet onOriginChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
static ERlvCmdRet onColorChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
static ERlvCmdRet onDistMinChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
static ERlvCmdRet onDistMaxChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
static ERlvCmdRet onDistExtendChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
static ERlvCmdRet onValueMinChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
static ERlvCmdRet onValueMaxChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue);
|
||||
protected:
|
||||
void renderPass(LLGLSLShader* pShader) const;
|
||||
void setShaderUniforms(LLGLSLShader* pShader, LLRenderTarget* pRenderTarget);
|
||||
|
||||
/*
|
||||
* Member variables
|
||||
*/
|
||||
protected:
|
||||
enum class ESphereMode { Blend = 0, SoftBlur, Blur, Count };
|
||||
ESphereMode m_eMode;
|
||||
enum class ESphereOrigin { Avatar = 0, Camera, Count };
|
||||
ESphereOrigin m_eOrigin;
|
||||
LLColor3 m_Color;
|
||||
float m_nDistanceMin;
|
||||
float m_nDistanceMax;
|
||||
enum class ESphereDistExtend { Max = 0x01, Min = 0x02, Both = 0x03 };
|
||||
ESphereDistExtend m_eDistExtend;
|
||||
float m_nValueMin;
|
||||
float m_nValueMax;
|
||||
};
|
||||
|
||||
// ====================================================================================
|
||||
|
|
@ -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"
|
||||
|
|
@ -178,7 +180,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
|
||||
|
|
@ -1779,7 +1780,7 @@ ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_MODIFIER>::onCommand(const RlvC
|
|||
// There should be an option and it should specify a valid modifier (RlvBehaviourModifier performs the appropriate type checks)
|
||||
RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(rlvCmd.getBehaviourType());
|
||||
RlvBehaviourModifierValue modValue;
|
||||
if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), modValue)) )
|
||||
if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), pBhvrModifier->getType(), modValue)) )
|
||||
return RLV_RET_FAILED_OPTION;
|
||||
|
||||
// HACK-RLVa: reference counting doesn't happen until control returns to our caller but the modifier callbacks will happen now so we need to adjust the reference counts here
|
||||
|
|
@ -1800,15 +1801,22 @@ ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_MODIFIER>::onCommand(const RlvC
|
|||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// Handles: @bhvr[:<modifier>]=n|y
|
||||
// Handles: @bhvr=n, @bhvr:<global modifier>=n|y and @bhvr:<local modifier>=force
|
||||
template<>
|
||||
ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_MODIFIER>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount)
|
||||
{
|
||||
// If there is an option then it should specify a valid modifier (and reference count)
|
||||
if (rlvCmd.hasOption())
|
||||
if ( (rlvCmd.getParamType() & RLV_TYPE_ADDREM) && (rlvCmd.hasOption()) )
|
||||
{
|
||||
// @bhvr:<global modifier>=n|y : if there is an option then it should specify a valid global modifier and if so we reference count
|
||||
return RlvBehaviourGenericHandler<RLV_OPTION_MODIFIER>::onCommand(rlvCmd, fRefCount);
|
||||
}
|
||||
else if (rlvCmd.getParamType() == RLV_TYPE_FORCE)
|
||||
{
|
||||
// @bhvr:<local modifier>=force : local modifiers hide behind their primary behaviour which knows how to handle them
|
||||
return rlvCmd.getBehaviourInfo()->processModifier(rlvCmd);
|
||||
}
|
||||
|
||||
// Add the default option on an empty modifier if needed
|
||||
// @bhvr=n : add the default option on an empty modifier if needed
|
||||
RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(rlvCmd.getBehaviourType());
|
||||
if ( (pBhvrModifier) && (pBhvrModifier->getAddDefault()) )
|
||||
{
|
||||
|
|
@ -2044,36 +2052,37 @@ void RlvBehaviourToggleHandler<RLV_BHVR_PAY>::onCommandToggle(ERlvBehaviour eBhv
|
|||
template<> template<>
|
||||
void RlvBehaviourToggleHandler<RLV_BHVR_SETOVERLAY>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
|
||||
{
|
||||
// Once an object has exclusive control over the overlay only its behaviours should be active. This affects:
|
||||
// - behaviour modifiers => handled for us once we set the primary object
|
||||
|
||||
LLUUID idRlvObject;
|
||||
if (fHasBhvr)
|
||||
{
|
||||
// Get the UUID of the primary object (there should only be one)
|
||||
std::list<const RlvObject*> lObjects;
|
||||
gRlvHandler.findBehaviour(RLV_BHVR_SETOVERLAY, lObjects);
|
||||
RLV_ASSERT(lObjects.size() == 1);
|
||||
idRlvObject = lObjects.front()->getObjectID();
|
||||
}
|
||||
|
||||
RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_ALPHA)->setPrimaryObject(idRlvObject);
|
||||
RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TINT)->setPrimaryObject(idRlvObject);
|
||||
RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TEXTURE)->setPrimaryObject(idRlvObject);
|
||||
RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TOUCH)->setPrimaryObject(idRlvObject);
|
||||
LLVfxManager::instance().addEffect(new RlvOverlayEffect(gRlvHandler.getCurrentObject()));
|
||||
else
|
||||
LLVfxManager::instance().removeEffect(gRlvHandler.getCurrentObject());
|
||||
}
|
||||
|
||||
// Handles: @setoverlay_texture:<uuid>=n|y changes
|
||||
template<>
|
||||
void RlvBehaviourModifierHandler<RLV_MODIFIER_OVERLAY_TEXTURE>::onValueChange() const
|
||||
// Handles: @setsphere=n|y
|
||||
template<> template<>
|
||||
ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETSPHERE>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount)
|
||||
{
|
||||
if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TEXTURE))
|
||||
ERlvCmdRet eRet = RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_MODIFIER>::onCommand(rlvCmd, fRefCount);
|
||||
if ( (RLV_RET_SUCCESS == eRet) && (!rlvCmd.isModifier()) )
|
||||
{
|
||||
if (pBhvrModifier->hasValue())
|
||||
gRlvHandler.setOverlayImage(pBhvrModifier->getValue<LLUUID>());
|
||||
// If we're not using deferred but are using Windlight shaders we need to force use of FBO and depthmap texture
|
||||
if ( (!LLPipeline::RenderDeferred) && (LLPipeline::WindLightUseAtmosShaders) && (!LLPipeline::sUseDepthTexture) )
|
||||
{
|
||||
LLRenderTarget::sUseFBO = true;
|
||||
LLPipeline::sUseDepthTexture = true;
|
||||
|
||||
gPipeline.releaseGLBuffers();
|
||||
gPipeline.createGLBuffers();
|
||||
gPipeline.resetVertexBuffers();
|
||||
LLViewerShaderMgr::instance()->setShaders();
|
||||
}
|
||||
|
||||
if (gRlvHandler.hasBehaviour(rlvCmd.getObjectID(), rlvCmd.getBehaviourType()))
|
||||
LLVfxManager::instance().addEffect(new RlvSphereEffect(rlvCmd.getObjectID()));
|
||||
else
|
||||
gRlvHandler.clearOverlayImage();
|
||||
LLVfxManager::instance().removeEffect(gRlvHandler.getCurrentObject());
|
||||
}
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// Handles: @sendchannel[:<channel>]=n|y and @sendchannel_except[:<channel>]=n|y
|
||||
|
|
@ -2632,7 +2641,7 @@ ERlvCmdRet RlvForceGenericHandler<RLV_OPTION_MODIFIER>::onCommand(const RlvComma
|
|||
// There should be an option and it should specify a valid modifier (RlvBehaviourModifier performs the appropriate type checks)
|
||||
RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(rlvCmd.getBehaviourType());
|
||||
RlvBehaviourModifierValue modValue;
|
||||
if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), modValue)) )
|
||||
if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), pBhvrModifier->getType(), modValue)) )
|
||||
return RLV_RET_FAILED_OPTION;
|
||||
|
||||
pBhvrModifier->setValue(modValue, rlvCmd.getObjectID());
|
||||
|
|
@ -2987,6 +2996,14 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SETCAM_MODE>::onCommand(const RlvCommand& rl
|
|||
template<> template<>
|
||||
ERlvCmdRet RlvForceHandler<RLV_BHVR_SETOVERLAY_TWEEN>::onCommand(const RlvCommand& rlvCmd)
|
||||
{
|
||||
RlvObject* pRlvObj = gRlvHandler.getObject(rlvCmd.getObjectID());
|
||||
if (!pRlvObj)
|
||||
return RLV_RET_FAILED_NOBEHAVIOUR;
|
||||
|
||||
RlvOverlayEffect* pOverlayEffect = LLVfxManager::instance().getEffect<RlvOverlayEffect>(rlvCmd.getObjectID());
|
||||
if (!pOverlayEffect)
|
||||
return RLV_RET_FAILED_LOCK;
|
||||
|
||||
std::vector<std::string> optionList;
|
||||
if ( (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) || (3 != optionList.size()) )
|
||||
return RLV_RET_FAILED_OPTION;
|
||||
|
|
@ -2999,12 +3016,18 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SETOVERLAY_TWEEN>::onCommand(const RlvComman
|
|||
// Process the overlay alpha tween (if there is one and it is a valid value)
|
||||
float overlayAlpha = .0f;
|
||||
if (RlvCommandOptionHelper::parseOption(optionList[0], overlayAlpha))
|
||||
RlvBehaviourModifierAnimator::instance().addTween(rlvCmd.getObjectID(), RLV_MODIFIER_OVERLAY_ALPHA, RlvBehaviourModifierAnimationType::Lerp, overlayAlpha, tweenDuration);
|
||||
{
|
||||
pOverlayEffect->tweenAlpha(overlayAlpha, tweenDuration);
|
||||
pRlvObj->setModifierValue(ERlvLocalBhvrModifier::OverlayAlpha, overlayAlpha);
|
||||
}
|
||||
|
||||
// Process the overlay tint tween (if there is one and it is a valid value)
|
||||
LLVector3 overlayColor;
|
||||
if (RlvCommandOptionHelper::parseOption(optionList[1], overlayColor))
|
||||
RlvBehaviourModifierAnimator::instance().addTween(rlvCmd.getObjectID(), RLV_MODIFIER_OVERLAY_TINT, RlvBehaviourModifierAnimationType::Lerp, overlayColor, tweenDuration);
|
||||
{
|
||||
pOverlayEffect->tweenColor(LLColor3(overlayColor.mV), tweenDuration);
|
||||
pRlvObj->setModifierValue(ERlvLocalBhvrModifier::OverlayTint, overlayColor);
|
||||
}
|
||||
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
|
@ -3786,76 +3809,4 @@ ERlvCmdRet RlvHandler::onGetPath(const RlvCommand& rlvCmd, std::string& strReply
|
|||
// Command specific helper functions - @setoverlay
|
||||
//
|
||||
|
||||
void RlvHandler::clearOverlayImage()
|
||||
{
|
||||
if (m_pOverlayImage)
|
||||
{
|
||||
m_pOverlayImage->setBoostLevel(m_nOverlayOrigBoost);
|
||||
m_pOverlayImage = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool RlvHandler::hitTestOverlay(const LLCoordGL& ptMouse) const
|
||||
{
|
||||
if (!m_pOverlayImage)
|
||||
return false;
|
||||
|
||||
RlvBehaviourModifier* pTouchModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TOUCH);
|
||||
return (pTouchModifier) && (pTouchModifier->hasValue()) && (pTouchModifier->getValue<bool>()) &&
|
||||
(m_pOverlayImage->getMask(LLVector2((float)ptMouse.mX / gViewerWindow->getWorldViewWidthScaled(), (float)ptMouse.mY / gViewerWindow->getWorldViewHeightScaled())));
|
||||
}
|
||||
|
||||
void RlvHandler::renderOverlay()
|
||||
{
|
||||
if ( (hasBehaviour(RLV_BHVR_SETOVERLAY)) && (m_pOverlayImage) )
|
||||
{
|
||||
if (LLGLSLShader::sNoFixedFunction)
|
||||
{
|
||||
gUIProgram.bind();
|
||||
}
|
||||
|
||||
int nWidth = gViewerWindow->getWorldViewWidthScaled();
|
||||
int nHeight = gViewerWindow->getWorldViewHeightScaled();
|
||||
|
||||
m_pOverlayImage->addTextureStats(nWidth * nHeight);
|
||||
m_pOverlayImage->setKnownDrawSize(nWidth, nHeight);
|
||||
|
||||
gGL.pushMatrix();
|
||||
LLGLSUIDefault glsUI;
|
||||
gViewerWindow->setup2DRender();
|
||||
|
||||
const LLVector2& displayScale = gViewerWindow->getDisplayScale();
|
||||
gGL.scalef(displayScale.mV[VX], displayScale.mV[VY], 1.f);
|
||||
|
||||
gGL.getTexUnit(0)->bind(m_pOverlayImage);
|
||||
const LLVector3 overlayTint = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TINT)->getValue<LLVector3>();
|
||||
gGL.color4f(overlayTint.mV[0], overlayTint.mV[1], overlayTint.mV[2], llclamp(RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_ALPHA)->getValue<float>(), 0.0f, 1.0f));
|
||||
|
||||
gl_rect_2d_simple_tex(nWidth, nHeight);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
gGL.popMatrix();
|
||||
gGL.flush();
|
||||
gViewerWindow->setup3DRender();
|
||||
|
||||
if (LLGLSLShader::sNoFixedFunction)
|
||||
{
|
||||
gUIProgram.unbind();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RlvHandler::setOverlayImage(const LLUUID& idTexture)
|
||||
{
|
||||
if ( (m_pOverlayImage) && (m_pOverlayImage->getID() == idTexture) )
|
||||
return;
|
||||
|
||||
clearOverlayImage();
|
||||
m_pOverlayImage = LLViewerTextureManager::getFetchedTexture(idTexture, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
m_nOverlayOrigBoost = m_pOverlayImage->getBoostLevel();
|
||||
m_pOverlayImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
|
||||
m_pOverlayImage->forceToSaveRawImage(0);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
|
|
|||
|
|
@ -23,13 +23,9 @@
|
|||
#include "rlvcommon.h"
|
||||
#include "rlvhelper.h"
|
||||
|
||||
// ============================================================================
|
||||
// Forward declarations
|
||||
//
|
||||
|
||||
class LLViewerFetchedTexture;
|
||||
|
||||
// ============================================================================
|
||||
// RlvHandler class
|
||||
//
|
||||
|
||||
class RlvHandler : public LLOldEvents::LLSimpleListener, public LLParticularGroupObserver
|
||||
{
|
||||
|
|
@ -56,6 +52,8 @@ public:
|
|||
public:
|
||||
// Returns a list of all objects containing the specified behaviour
|
||||
bool findBehaviour(ERlvBehaviour eBhvr, std::list<const RlvObject*>& lObjects) const;
|
||||
// Returns a pointer to an RLV object instance (DO NOT STORE THIS!)
|
||||
RlvObject* getObject(const LLUUID& idRlvObj) const;
|
||||
// Returns TRUE is at least one object contains the specified behaviour (and optional option)
|
||||
bool hasBehaviour(ERlvBehaviour eBhvr) const { return (eBhvr < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBhvr]) : false; }
|
||||
bool hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const;
|
||||
|
|
@ -123,9 +121,7 @@ public:
|
|||
|
||||
// Command specific helper functions
|
||||
bool filterChat(std::string& strUTF8Text, bool fFilterEmote) const; // @sendchat, @recvchat and @redirchat
|
||||
bool hitTestOverlay(const LLCoordGL& ptMouse) const; // @setoverlay
|
||||
bool redirectChatOrEmote(const std::string& strUTF8Test) const; // @redirchat and @rediremote
|
||||
void renderOverlay(); // @setoverlay
|
||||
|
||||
// Command processing helper functions
|
||||
ERlvCmdRet processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj);
|
||||
|
|
@ -144,11 +140,9 @@ public:
|
|||
protected:
|
||||
// Command specific helper functions (NOTE: these generally do not perform safety checks)
|
||||
bool checkActiveGroupThrottle(const LLUUID& idRlvObj); // @setgroup=force
|
||||
void clearOverlayImage(); // @setoverlay=n
|
||||
void setActiveGroup(const LLUUID& idGroup); // @setgroup=force
|
||||
void setActiveGroupRole(const LLUUID& idGroup, const std::string& strRole); // @setgroup=force
|
||||
void setCameraOverride(bool fOverride); // @setcam family
|
||||
void setOverlayImage(const LLUUID& idTexture); // @setoverlay=n
|
||||
|
||||
void onIMQueryListResponse(const LLSD& sdNotification, const LLSD sdResponse);
|
||||
|
||||
|
|
@ -275,8 +269,6 @@ protected:
|
|||
mutable LLUUID m_idAgentGroup; // @setgroup=n
|
||||
std::pair<LLUUID, std::string> m_PendingGroupChange; // @setgroup=force
|
||||
std::pair<LLTimer, LLUUID> m_GroupChangeExpiration; // @setgroup=force
|
||||
LLPointer<LLViewerFetchedTexture> m_pOverlayImage = nullptr; // @setoverlay=n
|
||||
int m_nOverlayOrigBoost = 0; // @setoverlay=n
|
||||
|
||||
std::string m_strCameraPresetRestore; // @setcam_eyeoffset, @setcam_eyeoffsetscale and @setcam_focusoffset
|
||||
|
||||
|
|
@ -313,6 +305,12 @@ inline RlvHandler* RlvHandler::getInstance()
|
|||
return &gRlvHandler;
|
||||
}
|
||||
|
||||
inline RlvObject* RlvHandler::getObject(const LLUUID& idRlvObj) const
|
||||
{
|
||||
auto itObj = m_Objects.find(idRlvObj);
|
||||
return (m_Objects.end() != itObj) ? const_cast<RlvObject*>(&itObj->second) : nullptr;
|
||||
}
|
||||
|
||||
inline bool RlvHandler::hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const
|
||||
{
|
||||
return hasBehaviourExcept(eBhvr, strOption, LLUUID::null);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "llviewerobjectlist.h"
|
||||
|
||||
#include "rlvcommon.h"
|
||||
#include "rlveffects.h"
|
||||
#include "rlvhelper.h"
|
||||
#include "rlvhandler.h"
|
||||
#include "rlvinventory.h"
|
||||
|
|
@ -215,17 +216,26 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
|
|||
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETCAM_UNLOCK, RLV_OPTION_NONE>("camunlock", RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));
|
||||
|
||||
// Overlay
|
||||
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETOVERLAY, RLV_OPTION_NONE>("setoverlay", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
|
||||
addModifier(new RlvForceGenericProcessor<RLV_OPTION_MODIFIER>("setoverlay_alpha", RLV_BHVR_SETOVERLAY_ALPHA, RlvBehaviourInfo::BHVR_EXPERIMENTAL),
|
||||
RLV_MODIFIER_OVERLAY_ALPHA, new RlvBehaviourModifier("Overlay - Alpha", 1.0f, false, new RlvBehaviourModifierComp()));
|
||||
addModifier(new RlvForceGenericProcessor<RLV_OPTION_MODIFIER>("setoverlay_texture", RLV_BHVR_SETOVERLAY_TEXTURE, RlvBehaviourInfo::BHVR_EXPERIMENTAL),
|
||||
RLV_MODIFIER_OVERLAY_TEXTURE, new RlvBehaviourModifierHandler<RLV_MODIFIER_OVERLAY_TEXTURE>("Overlay - Texture", LLUUID::null, false, new RlvBehaviourModifierComp()));
|
||||
addModifier(new RlvForceGenericProcessor<RLV_OPTION_MODIFIER>("setoverlay_tint", RLV_BHVR_SETOVERLAY_TINT, RlvBehaviourInfo::BHVR_EXPERIMENTAL),
|
||||
RLV_MODIFIER_OVERLAY_TINT, new RlvBehaviourModifier("Overlay - Tint", LLVector3(1.0f, 1.0f, 1.0f), false, new RlvBehaviourModifierComp()));
|
||||
addModifier(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_MODIFIER>("setoverlay_touch", RLV_BHVR_SETOVERLAY_TOUCH, RlvBehaviourInfo::BHVR_EXPERIMENTAL),
|
||||
RLV_MODIFIER_OVERLAY_TOUCH, new RlvBehaviourModifier("Overlay - Touch", true, true, new RlvBehaviourModifierComp()));
|
||||
RlvBehaviourInfo* pSetOverlayBhvr = new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETOVERLAY, RLV_OPTION_NONE_OR_MODIFIER>("setoverlay");
|
||||
pSetOverlayBhvr->addModifier(ERlvLocalBhvrModifier::OverlayAlpha, typeid(float), "alpha", &RlvOverlayEffect::onAlphaValueChanged);
|
||||
pSetOverlayBhvr->addModifier(ERlvLocalBhvrModifier::OverlayTexture, typeid(LLUUID), "texture", &RlvOverlayEffect::onTextureChanged);
|
||||
pSetOverlayBhvr->addModifier(ERlvLocalBhvrModifier::OverlayTint, typeid(LLVector3), "tint", &RlvOverlayEffect::onColorValueChanged);
|
||||
pSetOverlayBhvr->addModifier(ERlvLocalBhvrModifier::OverlayTouch, typeid(LLVector3), "touch", &RlvOverlayEffect::onBlockTouchValueChanged);
|
||||
addEntry(pSetOverlayBhvr);
|
||||
addEntry(new RlvForceProcessor<RLV_BHVR_SETOVERLAY_TWEEN>("setoverlay_tween", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
|
||||
|
||||
// Sphere
|
||||
RlvBehaviourInfo* pSetSphereBhvr = new RlvBehaviourProcessor<RLV_BHVR_SETSPHERE>("setsphere", RlvBehaviourInfo::BHVR_EXPERIMENTAL);
|
||||
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereMode, typeid(int), "mode", &RlvSphereEffect::onModeChanged);
|
||||
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereOrigin, typeid(int), "origin", &RlvSphereEffect::onOriginChanged);
|
||||
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereColor, typeid(LLVector3), "color", &RlvSphereEffect::onColorChanged);
|
||||
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereDistMin, typeid(float), "distmin", &RlvSphereEffect::onDistMinChanged);
|
||||
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereDistMax, typeid(float), "distmax", &RlvSphereEffect::onDistMaxChanged);
|
||||
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereDistExtend, typeid(int), "distextend", &RlvSphereEffect::onDistExtendChanged);
|
||||
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereValueMin, typeid(float), "valuemin", &RlvSphereEffect::onValueMinChanged);
|
||||
pSetSphereBhvr->addModifier(ERlvLocalBhvrModifier::SphereValueMax, typeid(float), "valuemax", &RlvSphereEffect::onValueMaxChanged);
|
||||
addEntry(pSetSphereBhvr);
|
||||
|
||||
//
|
||||
// Force-wear
|
||||
//
|
||||
|
|
@ -394,20 +404,36 @@ void RlvBehaviourDictionary::clearModifiers(const LLUUID& idRlvObj)
|
|||
}
|
||||
}
|
||||
|
||||
const RlvBehaviourInfo* RlvBehaviourDictionary::getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict) const
|
||||
const RlvBehaviourInfo* RlvBehaviourDictionary::getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict, ERlvLocalBhvrModifier* peBhvrModifier) const
|
||||
{
|
||||
bool fStrict = boost::algorithm::ends_with(strBhvr, "_sec");
|
||||
size_t idxBhvrLastPart = strBhvr.find_last_of('_');
|
||||
std::string strBhvrLastPart((std::string::npos != idxBhvrLastPart) && (idxBhvrLastPart < strBhvr.size()) ? strBhvr.substr(idxBhvrLastPart + 1) : LLStringUtil::null);
|
||||
|
||||
bool fStrict = (strBhvrLastPart.compare("sec") == 0);
|
||||
if (pfStrict)
|
||||
*pfStrict = fStrict;
|
||||
ERlvLocalBhvrModifier eBhvrModifier = ERlvLocalBhvrModifier::Unknown;
|
||||
|
||||
rlv_string2info_map_t::const_iterator itBhvr = m_String2InfoMap.find(std::make_pair( (!fStrict) ? strBhvr : strBhvr.substr(0, strBhvr.size() - 4), (eParamType & RLV_TYPE_ADDREM) ? RLV_TYPE_ADDREM : eParamType));
|
||||
return ( (itBhvr != m_String2InfoMap.end()) && ((!fStrict) || (itBhvr->second->hasStrict())) ) ? itBhvr->second : NULL;
|
||||
if ( (m_String2InfoMap.end() == itBhvr) && (!fStrict) && (!strBhvrLastPart.empty()) && (RLV_TYPE_FORCE == eParamType) )
|
||||
{
|
||||
// No match found but it could still be a local scope modifier
|
||||
auto itBhvrMod = m_String2InfoMap.find(std::make_pair(strBhvr.substr(0, idxBhvrLastPart), RLV_TYPE_ADDREM));
|
||||
if ( (m_String2InfoMap.end() != itBhvrMod) && (eBhvrModifier = itBhvrMod->second->lookupBehaviourModifier(strBhvrLastPart)) != ERlvLocalBhvrModifier::Unknown)
|
||||
itBhvr = itBhvrMod;
|
||||
}
|
||||
|
||||
if (peBhvrModifier)
|
||||
*peBhvrModifier = eBhvrModifier;
|
||||
return ( (itBhvr != m_String2InfoMap.end()) && ((!fStrict) || (itBhvr->second->hasStrict())) ) ? itBhvr->second : nullptr;
|
||||
}
|
||||
|
||||
ERlvBehaviour RlvBehaviourDictionary::getBehaviourFromString(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict) const
|
||||
{
|
||||
const RlvBehaviourInfo* pBhvrInfo = getBehaviourInfo(strBhvr, eParamType, pfStrict);
|
||||
return (pBhvrInfo) ? pBhvrInfo->getBehaviourType() : RLV_BHVR_UNKNOWN;
|
||||
ERlvLocalBhvrModifier eBhvrModifier;
|
||||
const RlvBehaviourInfo* pBhvrInfo = getBehaviourInfo(strBhvr, eParamType, pfStrict, &eBhvrModifier);
|
||||
// Filter out locally scoped modifier commands since they don't actually have a unique behaviour value of their own
|
||||
return (pBhvrInfo && ERlvLocalBhvrModifier::Unknown != eBhvrModifier) ? pBhvrInfo->getBehaviourType() : RLV_BHVR_UNKNOWN;
|
||||
}
|
||||
|
||||
bool RlvBehaviourDictionary::getCommands(const std::string& strMatch, ERlvParamType eParamType, std::list<std::string>& cmdList) const
|
||||
|
|
@ -456,6 +482,42 @@ void RlvBehaviourDictionary::toggleBehaviourFlag(const std::string& strBhvr, ERl
|
|||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// RlvBehaviourInfo
|
||||
//
|
||||
|
||||
// virtual
|
||||
ERlvCmdRet RlvBehaviourInfo::processModifier(const RlvCommand& rlvCmd) const
|
||||
{
|
||||
// The object should be holding at least one active behaviour
|
||||
if (!gRlvHandler.hasBehaviour(rlvCmd.getObjectID()))
|
||||
return RLV_RET_FAILED_NOBEHAVIOUR;
|
||||
|
||||
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
|
||||
//
|
||||
|
|
@ -495,7 +557,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();
|
||||
|
|
@ -570,21 +631,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))
|
||||
|
|
@ -593,7 +655,7 @@ bool RlvBehaviourModifier::convertOptionValue(const std::string& optionValue, Rl
|
|||
return true;
|
||||
}
|
||||
}
|
||||
else if (typeid(LLUUID) == m_DefaultValue.type())
|
||||
else if (modType == typeid(LLUUID))
|
||||
{
|
||||
LLUUID idOption;
|
||||
if (LLUUID::parseUUID(optionValue, &idOption))
|
||||
|
|
@ -615,7 +677,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))
|
||||
{
|
||||
|
|
@ -643,7 +705,7 @@ 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)
|
||||
|
|
@ -1103,6 +1165,20 @@ std::string RlvObject::getStatusString(const std::string& strFilter, const std::
|
|||
return strStatus;
|
||||
}
|
||||
|
||||
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
|
||||
//
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ struct RlvBehaviourModifierComp;
|
|||
|
||||
class RlvBehaviourInfo
|
||||
{
|
||||
typedef std::function<ERlvCmdRet(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue>)> modifier_handler_func_t;
|
||||
public:
|
||||
enum EBehaviourFlags
|
||||
{
|
||||
|
|
@ -65,24 +66,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; }
|
||||
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;
|
||||
typedef std::map<std::string, std::tuple<ERlvLocalBhvrModifier, std::type_index, modifier_handler_func_t>> modifier_lookup_t;
|
||||
modifier_lookup_t m_BhvrModifiers;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
|
|
@ -106,7 +112,7 @@ 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(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict = nullptr, ERlvLocalBhvrModifier* peBhvrModifier = nullptr) const;
|
||||
bool getCommands(const std::string& strMatch, ERlvParamType eParamType, std::list<std::string>& cmdList) const;
|
||||
bool getHasStrict(ERlvBehaviour eBhvr) const;
|
||||
RlvBehaviourModifier* getModifier(ERlvBehaviourModifier eBhvrMod) const { return (eBhvrMod < RLV_MODIFIER_COUNT) ? m_BehaviourModifiers[eBhvrMod] : nullptr; }
|
||||
|
|
@ -244,12 +250,13 @@ protected:
|
|||
virtual void onValueChange() const {}
|
||||
public:
|
||||
bool addValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj, ERlvBehaviour eBhvr = RLV_BHVR_UNKNOWN);
|
||||
bool convertOptionValue(const std::string& optionValue, RlvBehaviourModifierValue& modValue) const;
|
||||
static bool convertOptionValue(const std::string& optionValue, const std::type_index& modType, RlvBehaviourModifierValue& modValue);
|
||||
void clearValues(const LLUUID& idRlvObj);
|
||||
bool getAddDefault() const { return m_fAddDefaultOnEmpty; }
|
||||
const RlvBehaviourModifierValue& getDefaultValue() const { return m_DefaultValue; }
|
||||
const LLUUID& getPrimaryObject() const;
|
||||
const std::string& getName() const { return m_strName; }
|
||||
const std::type_info& getType() const { return m_DefaultValue.type(); }
|
||||
const RlvBehaviourModifierValue& getValue() const { return (hasValue()) ? std::get<0>(m_Values.front()) : m_DefaultValue; }
|
||||
template<typename T> const T& getValue() const { return boost::get<T>(getValue()); }
|
||||
bool hasValue() const;
|
||||
|
|
@ -289,14 +296,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 +326,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 +463,14 @@ public:
|
|||
bool hasLookup() const { return m_fLookup; }
|
||||
const rlv_command_list_t& getCommandList() const { return m_Commands; }
|
||||
|
||||
/*
|
||||
* Local-scope modifiers
|
||||
*/
|
||||
public:
|
||||
void clearModifierValue(ERlvLocalBhvrModifier eBhvrMod);
|
||||
template<typename T> bool getModifierValue(ERlvLocalBhvrModifier eBhvrModifier, T& value) const;
|
||||
void setModifierValue(ERlvLocalBhvrModifier eBhvrMod, const RlvBehaviourModifierValue& modValue);
|
||||
|
||||
/*
|
||||
* Member variables
|
||||
*/
|
||||
|
|
@ -462,6 +481,8 @@ protected:
|
|||
bool m_fLookup; // TRUE if the object existed in gObjectList at one point in time
|
||||
S16 m_nLookupMisses; // Count of unsuccessful lookups in gObjectList by the GC
|
||||
rlv_command_list_t m_Commands; // List of behaviours held by this object (in the order they were received)
|
||||
typedef std::map<ERlvLocalBhvrModifier, RlvBehaviourModifierValue> bhvr_modifier_map_t;
|
||||
bhvr_modifier_map_t m_Modifiers; // List of (local scope) modifiers set on this object
|
||||
|
||||
friend class RlvHandler;
|
||||
};
|
||||
|
|
@ -671,6 +692,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)
|
||||
|
|
@ -695,6 +729,18 @@ inline bool RlvCommand::operator ==(const RlvCommand& rhs) const
|
|||
( (RLV_TYPE_UNKNOWN != m_eParamType) ? (m_eParamType == rhs.m_eParamType) : (m_strParam == rhs.m_strParam) );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool RlvObject::getModifierValue(ERlvLocalBhvrModifier eBhvrModifier, T& value) const
|
||||
{
|
||||
auto itBhvrModifierValue = m_Modifiers.find(eBhvrModifier);
|
||||
if (m_Modifiers.end() != itBhvrModifierValue)
|
||||
{
|
||||
value = boost::get<T>(itBhvrModifierValue->second);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checked: 2010-04-05 (RLVa-1.2.0d) | Modified: RLVa-1.2.0d
|
||||
inline bool RlvForceWear::isWearableItem(const LLInventoryItem* pItem)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,115 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (c) 2009-2018, Kitty Barnett
|
||||
*
|
||||
* The source code in this file is provided to you under the terms of the
|
||||
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
|
||||
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge that
|
||||
* you have read and understood your obligations described above, and agree to
|
||||
* abide by those obligations.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "rlvmodifiers.h"
|
||||
|
||||
// ====================================================================================
|
||||
// RlvBehaviourModifierAnimator
|
||||
//
|
||||
|
||||
RlvBehaviourModifierAnimator::~RlvBehaviourModifierAnimator()
|
||||
{
|
||||
if (!m_TimerHandle.isDead())
|
||||
m_TimerHandle.markDead();
|
||||
}
|
||||
|
||||
void RlvBehaviourModifierAnimator::addTween(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod, RlvBehaviourModifierAnimationType eAnimType, const RlvBehaviourModifierValue& endValue, float nDuration)
|
||||
{
|
||||
// Make sure we don't run two animations on the same modifier for the same object
|
||||
const auto itTween = std::find_if(m_Tweens.begin(), m_Tweens.end(), [&idObject, eBhvrMod](const RlvBehaviourModifierTween& t) { return t.idObject == idObject && t.eBhvrMod == eBhvrMod; });
|
||||
if (m_Tweens.end() != itTween)
|
||||
m_Tweens.erase(itTween);
|
||||
|
||||
if (const RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(eBhvrMod))
|
||||
{
|
||||
RlvBehaviourModifierTween newTween;
|
||||
newTween.idObject = idObject;
|
||||
newTween.eBhvrMod = eBhvrMod;
|
||||
newTween.eAnimType = RlvBehaviourModifierAnimationType::Lerp;
|
||||
newTween.nStartTime = LLTimer::getElapsedSeconds();
|
||||
newTween.nDuration = nDuration;
|
||||
newTween.startValue = pBhvrModifier->getValue();
|
||||
newTween.endValue = endValue;
|
||||
if (newTween.startValue.which() == newTween.endValue.which())
|
||||
{
|
||||
if (m_TimerHandle.isDead())
|
||||
m_TimerHandle = (new AnimationTimer())->getHandle();
|
||||
m_Tweens.emplace_back(std::move(newTween));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RlvBehaviourModifierAnimator::clearTweens(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod)
|
||||
{
|
||||
m_Tweens.erase(std::remove_if(m_Tweens.begin(), m_Tweens.end(),
|
||||
[&idObject, eBhvrMod](const RlvBehaviourModifierTween& cmpTween)
|
||||
{
|
||||
return cmpTween.idObject == idObject && ((cmpTween.eBhvrMod == eBhvrMod) || (RLV_MODIFIER_UNKNOWN == eBhvrMod));
|
||||
}), m_Tweens.end());
|
||||
}
|
||||
|
||||
// ====================================================================================
|
||||
// RlvBehaviourModifierAnimator timer
|
||||
//
|
||||
|
||||
RlvBehaviourModifierAnimator::AnimationTimer::AnimationTimer()
|
||||
: LLEventTimer(1.f / RLV_MODIFIER_ANIMATION_FREQUENCY)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BOOL RlvBehaviourModifierAnimator::AnimationTimer::tick()
|
||||
{
|
||||
RlvBehaviourModifierAnimator& modAnimatior = RlvBehaviourModifierAnimator::instance();
|
||||
const double curTime = LLTimer::getElapsedSeconds();
|
||||
|
||||
const auto activeTweens = modAnimatior.m_Tweens;
|
||||
for (const auto& curTween : activeTweens)
|
||||
{
|
||||
if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(curTween.eBhvrMod))
|
||||
{
|
||||
// Update the modifier's value
|
||||
float curFactor = (curTime - curTween.nStartTime) / curTween.nDuration;
|
||||
if (curFactor < 1.0)
|
||||
{
|
||||
const auto& valueType = curTween.startValue.type();
|
||||
if (typeid(float) == valueType)
|
||||
pBhvrModifier->setValue(lerp(boost::get<float>(curTween.startValue), boost::get<float>(curTween.endValue), curFactor), curTween.idObject);
|
||||
else if (typeid(int) == valueType)
|
||||
pBhvrModifier->setValue(lerp(boost::get<int>(curTween.startValue), boost::get<int>(curTween.endValue), curFactor), curTween.idObject);
|
||||
else if (typeid(LLVector3) == valueType)
|
||||
pBhvrModifier->setValue(lerp(boost::get<LLVector3>(curTween.startValue), boost::get<LLVector3>(curTween.endValue), curFactor), curTween.idObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
pBhvrModifier->setValue(curTween.endValue, curTween.idObject);
|
||||
auto itTween = std::find_if(modAnimatior.m_Tweens.begin(), modAnimatior.m_Tweens.end(),
|
||||
[&curTween](const RlvBehaviourModifierTween& t)
|
||||
{
|
||||
// NOTE: implementation leak - taking advantage of the fact that we know there can only be one active tween per object/modifier/type combination
|
||||
return t.idObject == curTween.idObject && t.eBhvrMod == curTween.eBhvrMod && t.eAnimType == curTween.eAnimType;
|
||||
});
|
||||
modAnimatior.m_Tweens.erase(itTween);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modAnimatior.m_Tweens.empty();
|
||||
}
|
||||
|
||||
// ====================================================================================
|
||||
|
|
@ -73,56 +73,6 @@ struct RlvBehaviourModifierCompMax : public RlvBehaviourModifierComp
|
|||
}
|
||||
};
|
||||
|
||||
// ====================================================================================
|
||||
// RlvBehaviourModifierAnimator - A class to animate behaviour modifiers
|
||||
//
|
||||
|
||||
enum class RlvBehaviourModifierAnimationType { Lerp };
|
||||
|
||||
struct RlvBehaviourModifierTween
|
||||
{
|
||||
LLUUID idObject;
|
||||
ERlvBehaviourModifier eBhvrMod;
|
||||
RlvBehaviourModifierAnimationType eAnimType;
|
||||
double nStartTime;
|
||||
float nDuration;
|
||||
RlvBehaviourModifierValue startValue;
|
||||
RlvBehaviourModifierValue endValue;
|
||||
};
|
||||
|
||||
class RlvBehaviourModifierAnimator : public LLSingleton<RlvBehaviourModifierAnimator>
|
||||
{
|
||||
LLSINGLETON_EMPTY_CTOR(RlvBehaviourModifierAnimator);
|
||||
public:
|
||||
~RlvBehaviourModifierAnimator() override;
|
||||
|
||||
/*
|
||||
* Member functions
|
||||
*/
|
||||
public:
|
||||
void addTween(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod, RlvBehaviourModifierAnimationType eAnimType, const RlvBehaviourModifierValue& endValue, float nDuration);
|
||||
void clearTweens(const LLUUID& idObject) { clearTweens(idObject, RLV_MODIFIER_UNKNOWN); }
|
||||
void clearTweens(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod);
|
||||
|
||||
/*
|
||||
* Animation timer
|
||||
*/
|
||||
protected:
|
||||
class AnimationTimer : public LLEventTimer, public LLHandleProvider<AnimationTimer>
|
||||
{
|
||||
public:
|
||||
AnimationTimer();
|
||||
BOOL tick() override;
|
||||
};
|
||||
|
||||
/*
|
||||
* Member variables
|
||||
*/
|
||||
protected:
|
||||
LLHandle<AnimationTimer> m_TimerHandle;
|
||||
std::list< RlvBehaviourModifierTween> m_Tweens;
|
||||
};
|
||||
|
||||
// ====================================================================================
|
||||
// RlvCachedBehaviourModifier - Provides an optimized way to access a modifier that's frequently accessed and rarely updated
|
||||
//
|
||||
|
|
|
|||
Loading…
Reference in New Issue