From 03d85bfb33f53e658256d8bedcf0b4262226cf90 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 9 Jun 2022 19:43:21 -0500
Subject: [PATCH] SL-17573 Add "dynamic" checkbox, also followup on SL-17551
 and do "Select Invisible Objects" checkbox instead of "Select Reflection
 Probes"

---
 indra/llprimitive/llprimitive.cpp             | 103 +++++++++++-------
 indra/llprimitive/llprimitive.h               |  15 +--
 indra/newview/app_settings/settings.xml       |   4 +-
 indra/newview/llpanelvolume.cpp               |  37 +++----
 indra/newview/llreflectionmap.cpp             |  14 ++-
 indra/newview/llreflectionmap.h               |   3 +
 indra/newview/llselectmgr.cpp                 |   6 +-
 indra/newview/lltoolselect.cpp                |  10 +-
 indra/newview/llviewermenu.cpp                |   8 +-
 indra/newview/llviewerwindow.cpp              |  46 ++++++--
 indra/newview/llviewerwindow.h                |   2 +-
 indra/newview/llvovolume.cpp                  |  36 ++++--
 indra/newview/llvovolume.h                    |   6 +-
 indra/newview/pipeline.cpp                    |   9 --
 .../skins/default/xui/en/floater_tools.xml    |  17 ++-
 .../skins/default/xui/en/menu_viewer.xml      |  10 +-
 16 files changed, 205 insertions(+), 121 deletions(-)

diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 6044048d095..9e0a079fd91 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -1819,92 +1819,117 @@ bool LLLightParams::fromLLSD(LLSD& sd)
 
 //============================================================================
 
+//============================================================================
+
 LLReflectionProbeParams::LLReflectionProbeParams()
 {
     mType = PARAMS_REFLECTION_PROBE;
 }
 
-BOOL LLReflectionProbeParams::pack(LLDataPacker& dp) const
+BOOL LLReflectionProbeParams::pack(LLDataPacker &dp) const
 {
-    dp.packF32(mAmbiance, "ambiance");
+	dp.packF32(mAmbiance, "ambiance");
     dp.packF32(mClipDistance, "clip_distance");
-    dp.packU8(mVolumeType, "volume_type");
-    return TRUE;
+    dp.packU8(mFlags, "flags");
+	return TRUE;
 }
 
-BOOL LLReflectionProbeParams::unpack(LLDataPacker& dp)
+BOOL LLReflectionProbeParams::unpack(LLDataPacker &dp)
 {
-    F32 ambiance;
+	F32 ambiance;
     F32 clip_distance;
-    U8 volume_type;
-
-    dp.unpackF32(ambiance, "ambiance");
-    setAmbiance(ambiance);
 
+	dp.unpackF32(ambiance, "ambiance");
+	setAmbiance(ambiance);
+	
     dp.unpackF32(clip_distance, "clip_distance");
-    setClipDistance(clip_distance);
-
-    dp.unpackU8(volume_type, "volume_type");
-    setVolumeType((EInfluenceVolumeType)volume_type);
-
-    return TRUE;
+	setClipDistance(clip_distance);
+	
+    dp.unpackU8(mFlags, "flags");
+	
+	return TRUE;
 }
 
 bool LLReflectionProbeParams::operator==(const LLNetworkData& data) const
 {
-    if (data.mType != PARAMS_REFLECTION_PROBE)
-    {
-        return false;
-    }
-    const LLReflectionProbeParams* param = (const LLReflectionProbeParams*)&data;
-    if (param->mAmbiance != mAmbiance)
-    {
-        return false;
-    }
+	if (data.mType != PARAMS_REFLECTION_PROBE)
+	{
+		return false;
+	}
+	const LLReflectionProbeParams *param = (const LLReflectionProbeParams*)&data;
+	if (param->mAmbiance != mAmbiance)
+	{
+		return false;
+	}
     if (param->mClipDistance != mClipDistance)
     {
         return false;
     }
-    if (param->mVolumeType != mVolumeType)
+    if (param->mFlags != mFlags)
     {
         return false;
     }
-    return true;
+	return true;
 }
 
 void LLReflectionProbeParams::copy(const LLNetworkData& data)
 {
-    const LLReflectionProbeParams* param = (LLReflectionProbeParams*)&data;
-    mType = param->mType;
-    mAmbiance = param->mAmbiance;
+	const LLReflectionProbeParams *param = (LLReflectionProbeParams*)&data;
+	mType = param->mType;
+	mAmbiance = param->mAmbiance;
     mClipDistance = param->mClipDistance;
-    mVolumeType = param->mVolumeType;
+    mFlags = param->mFlags;
 }
 
 LLSD LLReflectionProbeParams::asLLSD() const
 {
-    LLSD sd;
-    sd["ambiance"] = getAmbiance();
+	LLSD sd;
+	sd["ambiance"] = getAmbiance();
     sd["clip_distance"] = getClipDistance();
-    sd["volume_type"] = (U8) getVolumeType();
-    return sd;
+    sd["flags"] = mFlags;
+	return sd;
 }
 
 bool LLReflectionProbeParams::fromLLSD(LLSD& sd)
 {
     if (!sd.has("ambiance") ||
         !sd.has("clip_distance") ||
-        !sd.has("volume_type"))
+        !sd.has("flags"))
     {
         return false;
     }
 
-    setAmbiance((F32)sd["ambiance"].asReal());
+	setAmbiance((F32)sd["ambiance"].asReal());
     setClipDistance((F32)sd["clip_distance"].asReal());
-    setVolumeType((EInfluenceVolumeType)sd["volume_type"].asInteger());
-
+    mFlags = (U8) sd["flags"].asInteger();
+	
     return true;
 }
+
+void LLReflectionProbeParams::setIsBox(bool is_box)
+{
+    if (is_box)
+    {
+        mFlags |= FLAG_BOX_VOLUME;
+    }
+    else
+    {
+        mFlags &= ~FLAG_BOX_VOLUME;
+    }
+}
+
+void LLReflectionProbeParams::setIsDynamic(bool is_dynamic)
+{
+    if (is_dynamic)
+    {
+        mFlags |= FLAG_DYNAMIC;
+    }
+    else
+    {
+        mFlags &= ~FLAG_DYNAMIC;
+    }
+}
+
 //============================================================================
 LLFlexibleObjectData::LLFlexibleObjectData()
 {
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 2215133e169..25196fb894a 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -182,17 +182,16 @@ extern const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE;
 class LLReflectionProbeParams : public LLNetworkData
 {
 public:
-    enum EInfluenceVolumeType : U8
+    enum EFlags : U8
     {
-        VOLUME_TYPE_SPHERE = 0,  // use a sphere influence volume
-        VOLUME_TYPE_BOX = 1,      // use a box influence volume
-        DEFAULT_VOLUME_TYPE = VOLUME_TYPE_SPHERE
+        FLAG_BOX_VOLUME     = 0x01, // use a box influence volume
+        FLAG_DYNAMIC        = 0x02, // render dynamic objects (avatars) into this Reflection Probe
     };
 
 protected:
     F32 mAmbiance = REFLECTION_PROBE_DEFAULT_AMBIANCE;
     F32 mClipDistance = REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE;
-    EInfluenceVolumeType mVolumeType = DEFAULT_VOLUME_TYPE;
+    U8 mFlags = 0;
 
 public:
     LLReflectionProbeParams();
@@ -208,11 +207,13 @@ class LLReflectionProbeParams : public LLNetworkData
 
     void setAmbiance(F32 ambiance) { mAmbiance = llclamp(ambiance, REFLECTION_PROBE_MIN_AMBIANCE, REFLECTION_PROBE_MAX_AMBIANCE); }
     void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); }
-    void setVolumeType(EInfluenceVolumeType type) { mVolumeType = llclamp(type, VOLUME_TYPE_SPHERE, VOLUME_TYPE_BOX); }
+    void setIsBox(bool is_box);
+    void setIsDynamic(bool is_dynamic);
 
     F32 getAmbiance() const { return mAmbiance; }
     F32 getClipDistance() const { return mClipDistance; }
-    EInfluenceVolumeType getVolumeType() const { return mVolumeType; }
+    bool getIsBox() const { return (mFlags & FLAG_BOX_VOLUME) != 0; }
+    bool getIsDynamic() const { return (mFlags & FLAG_DYNAMIC) != 0; }
 };
 
 //-------------------------------------------------
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 6df71e1019d..327dfe69555 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11191,10 +11191,10 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>SelectReflectionProbes</key>
+    <key>SelectInvisibleObjects</key>
     <map>
       <key>Comment</key>
-      <string>Select reflection probes</string>
+      <string>Select invisible objects</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index fb2cf484f56..ddce22fa20a 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -147,8 +147,9 @@ BOOL	LLPanelVolume::postBuild()
 	
     // REFLECTION PROBE Parameters
     {
-        childSetCommitCallback("Reflection Probe Checkbox Ctrl", onCommitIsReflectionProbe, this);
-        childSetCommitCallback("Probe Volume Type Ctrl", onCommitProbe, this);
+        childSetCommitCallback("Reflection Probe", onCommitIsReflectionProbe, this);
+        childSetCommitCallback("Probe Dynamic", onCommitProbe, this);
+        childSetCommitCallback("Probe Volume Type", onCommitProbe, this);
         childSetCommitCallback("Probe Ambiance", onCommitProbe, this);
         childSetCommitCallback("Probe Near Clip", onCommitProbe, this);
 
@@ -372,25 +373,27 @@ void LLPanelVolume::getState( )
 
     // Reflection Probe
     BOOL is_probe = volobjp && volobjp->isReflectionProbe();
-    getChild<LLUICtrl>("Reflection Probe Checkbox Ctrl")->setValue(is_probe);
-    getChildView("Reflection Probe Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp);
+    getChild<LLUICtrl>("Reflection Probe")->setValue(is_probe);
+    getChildView("Reflection Probe")->setEnabled(editable && single_volume && volobjp);
 
     bool probe_enabled = is_probe && editable && single_volume;
 
-    getChildView("Probe Volume Type Ctrl")->setEnabled(probe_enabled);
+    getChildView("Probe Dynamic")->setEnabled(probe_enabled);
+    getChildView("Probe Volume Type")->setEnabled(probe_enabled);
     getChildView("Probe Ambiance")->setEnabled(probe_enabled);
     getChildView("Probe Near Clip")->setEnabled(probe_enabled);
 
     if (!probe_enabled)
     {
-        getChild<LLComboBox>("Probe Volume Type Ctrl", true)->clear();
+        getChild<LLComboBox>("Probe Volume Type", true)->clear();
         getChild<LLSpinCtrl>("Probe Ambiance", true)->clear();
         getChild<LLSpinCtrl>("Probe Near Clip", true)->clear();
+        getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->clear();
     }
     else
     {
         std::string volume_type;
-        if (volobjp->getReflectionProbeVolumeType() == LLReflectionProbeParams::VOLUME_TYPE_BOX)
+        if (volobjp->getReflectionProbeIsBox())
         {
             volume_type = "Box";
         }
@@ -399,9 +402,10 @@ void LLPanelVolume::getState( )
             volume_type = "Sphere";
         }
 
-        getChild<LLComboBox>("Probe Volume Type Ctrl", true)->setValue(volume_type);
+        getChild<LLComboBox>("Probe Volume Type", true)->setValue(volume_type);
         getChild<LLSpinCtrl>("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance());
         getChild<LLSpinCtrl>("Probe Near Clip", true)->setValue(volobjp->getReflectionProbeNearClip());
+        getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->setValue(volobjp->getReflectionProbeIsDynamic());
     }
 
     // Animated Mesh
@@ -692,7 +696,8 @@ void LLPanelVolume::clearCtrls()
 	getChildView("Light Falloff")->setEnabled(false);
 
     getChildView("Reflection Probe Checkbox Ctrl")->setEnabled(false);;
-    getChildView("Probe Volume Type Ctrl")->setEnabled(false);
+    getChildView("Probe Volume Type")->setEnabled(false);
+    getChildView("Probe Dynamic")->setEnabled(false);
     getChildView("Probe Ambiance")->setEnabled(false);
     getChildView("Probe Near Clip")->setEnabled(false);
     getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false);
@@ -1003,19 +1008,11 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
 
     volobjp->setReflectionProbeAmbiance((F32)self->getChild<LLUICtrl>("Probe Ambiance")->getValue().asReal());
     volobjp->setReflectionProbeNearClip((F32)self->getChild<LLUICtrl>("Probe Near Clip")->getValue().asReal());
+    volobjp->setReflectionProbeIsDynamic(self->getChild<LLUICtrl>("Probe Dynamic")->getValue().asBoolean());
 
-    std::string shape_type = self->getChild<LLUICtrl>("Probe Volume Type Ctrl")->getValue().asString();
-    LLReflectionProbeParams::EInfluenceVolumeType volume_type = LLReflectionProbeParams::DEFAULT_VOLUME_TYPE;
+    std::string shape_type = self->getChild<LLUICtrl>("Probe Volume Type")->getValue().asString();
 
-    if (shape_type == "Sphere")
-    {
-        volume_type = LLReflectionProbeParams::VOLUME_TYPE_SPHERE;
-    }
-    else if (shape_type == "Box")
-    {
-        volume_type = LLReflectionProbeParams::VOLUME_TYPE_BOX;
-    }
-    volobjp->setReflectionProbeVolumeType(volume_type);
+    volobjp->setReflectionProbeIsBox(shape_type == "Box");
 }
 
 // static
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
index 5991d7a1704..39e0841fc5d 100644
--- a/indra/newview/llreflectionmap.cpp
+++ b/indra/newview/llreflectionmap.cpp
@@ -51,7 +51,7 @@ void LLReflectionMap::update(U32 resolution, U32 face)
     {
         resolution /= 2;
     }
-    gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip());
+    gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip(), getIsDynamic());
 }
 
 bool LLReflectionMap::shouldUpdate()
@@ -243,6 +243,16 @@ F32 LLReflectionMap::getNearClip()
     return llmax(ret, MINIMUM_NEAR_CLIP);
 }
 
+bool LLReflectionMap::getIsDynamic()
+{
+    if (mViewerObject && mViewerObject->getVolume())
+    {
+        return ((LLVOVolume*)mViewerObject)->getReflectionProbeIsDynamic();
+    }
+
+    return false;
+}
+
 bool LLReflectionMap::getBox(LLMatrix4& box)
 { 
     if (mViewerObject)
@@ -252,7 +262,7 @@ bool LLReflectionMap::getBox(LLMatrix4& box)
         {
             LLVOVolume* vobjp = (LLVOVolume*)mViewerObject;
 
-            if (vobjp->getReflectionProbeVolumeType() == LLReflectionProbeParams::VOLUME_TYPE_BOX)
+            if (vobjp->getReflectionProbeIsBox())
             {
                 glh::matrix4f mv(gGLModelView);
                 glh::matrix4f scale;
diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h
index a358bf5fdf1..071568e53c0 100644
--- a/indra/newview/llreflectionmap.h
+++ b/indra/newview/llreflectionmap.h
@@ -61,6 +61,9 @@ class alignas(16) LLReflectionMap : public LLRefCount
     // Get the near clip plane distance to use for this probe
     F32 getNearClip();
 
+    // Return true if this probe should include avatars in its reflection map
+    bool getIsDynamic();
+
     // get the encoded bounding box of this probe's influence volume
     // will only return a box if this probe is associated with a VOVolume
     // with its reflection probe influence volume to to VOLUME_TYPE_BOX
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 7b4ba518590..853703b4d52 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1067,8 +1067,7 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
 	}
 	
     if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
-        || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced()))
-        || (!gSavedSettings.getBOOL("SelectReflectionProbes") && !objectp->isReflectionProbe()))
+        || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced())))
 	{
 		// only select my own objects
 		return;
@@ -7128,8 +7127,7 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object, BOOL ignore_select_own
 	if(!ignore_select_owned)
 	{
 		if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) ||
-				(gSavedSettings.getBOOL("SelectMovableOnly") && (!object->permMove() ||  object->isPermanentEnforced())) ||
-                (!gSavedSettings.getBOOL("SelectReflectionProbes") && object->isReflectionProbe()))
+				(gSavedSettings.getBOOL("SelectMovableOnly") && (!object->permMove() ||  object->isPermanentEnforced())))
 		{
 			// only select my own objects
 			return FALSE;
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index 790d9a8ec58..c6f3905ddca 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -65,7 +65,8 @@ BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	// do immediate pick query
     BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
-	mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged);
+    BOOL pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects");
+	mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged);
 
 	// Pass mousedown to agent
 	LLTool::handleMouseDown(x, y, mask);
@@ -84,15 +85,13 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
 	}
 	BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly");
 	BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly");
-    BOOL select_probe = gSavedSettings.getBOOL("SelectReflectionProbes");
 
-	// *NOTE: These settings must be cleaned up at bottom of function.
+    // *NOTE: These settings must be cleaned up at bottom of function.
 	if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar)
 	{
 		gSavedSettings.setBOOL("SelectOwnedOnly", FALSE);
 		gSavedSettings.setBOOL("SelectMovableOnly", FALSE);
-        gSavedSettings.setBOOL("SelectReflectionProbes", FALSE);
-		LLSelectMgr::getInstance()->setForceSelection(TRUE);
+    	LLSelectMgr::getInstance()->setForceSelection(TRUE);
 	}
 
 	BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL);
@@ -243,7 +242,6 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
 	{
 		gSavedSettings.setBOOL("SelectOwnedOnly", select_owned);
 		gSavedSettings.setBOOL("SelectMovableOnly", select_movable);
-        gSavedSettings.setBOOL("SelectReflectionProbes", select_probe);
 		LLSelectMgr::getInstance()->setForceSelection(FALSE);
 	}
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index b99299528c7..b7f94a7e0c2 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7971,13 +7971,13 @@ class LLToolsSelectOnlyMovableObjects : public view_listener_t
 	}
 };
 
-class LLToolsSelectReflectionProbes : public view_listener_t
+class LLToolsSelectInvisibleObjects : public view_listener_t
 {
     bool handleEvent(const LLSD& userdata)
     {
-        BOOL cur_val = gSavedSettings.getBOOL("SelectReflectionProbes");
+        BOOL cur_val = gSavedSettings.getBOOL("SelectInvisibleObjects");
 
-        gSavedSettings.setBOOL("SelectReflectionProbes", !cur_val);
+        gSavedSettings.setBOOL("SelectInvisibleObjects", !cur_val);
 
         return true;
     }
@@ -9212,7 +9212,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool");
 	view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects");
 	view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects");
-    view_listener_t::addMenu(new LLToolsSelectReflectionProbes(), "Tools.SelectReflectionProbes");
+    view_listener_t::addMenu(new LLToolsSelectInvisibleObjects(), "Tools.SelectInvisibleObjects");
 	view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding");
 	view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection");
 	view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius");
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 6613c8ac010..1230a6d327c 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4196,10 +4196,15 @@ void LLViewerWindow::pickAsync( S32 x,
 								BOOL pick_unselectable)
 {
 	// "Show Debug Alpha" means no object actually transparent
+    BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
     if (LLDrawPoolAlpha::sShowDebugAlpha)
     {
         pick_transparent = TRUE;
     }
+    else if (in_build_mode && !gSavedSettings.getBOOL("SelectInvisibleObjects"))
+    {
+        pick_transparent = FALSE;
+    }
 
 	LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, TRUE, pick_unselectable, callback);
 	schedulePick(pick_info);
@@ -4260,7 +4265,7 @@ void LLViewerWindow::returnEmptyPicks()
 LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle, BOOL pick_unselectable)
 {
 	BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
-	if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
+	if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha)
 	{
 		// build mode allows interaction with all transparent objects
 		// "Show Debug Alpha" means no object actually transparent
@@ -5267,7 +5272,7 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
 
 void display_cube_face();
 
-BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip)
+BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip, bool dynamic_render)
 {
     // NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot
     LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
@@ -5300,16 +5305,33 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
 
     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     
+    U32 dynamic_render_types[] = {
+        LLPipeline::RENDER_TYPE_AVATAR,
+        LLPipeline::RENDER_TYPE_CONTROL_AV,
+        LLPipeline::RENDER_TYPE_PARTICLES
+    };
+    constexpr U32 dynamic_render_type_count = sizeof(dynamic_render_types) / sizeof(U32);
+    bool prev_dynamic_render_type[dynamic_render_type_count];
+
+    
+    if (!dynamic_render)
+    {
+        for (int i = 0; i < dynamic_render_type_count; ++i)
+        {
+            prev_dynamic_render_type[i] = gPipeline.hasRenderType(dynamic_render_types[i]);
+            if (prev_dynamic_render_type[i])
+            {
+                gPipeline.toggleRenderType(dynamic_render_types[i]);
+            }
+        }
+    }
+
     BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
     if (prev_draw_ui != false)
     {
         LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
     }
-    BOOL prev_draw_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
-    if (prev_draw_particles)
-    {
-        gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
-    }
+    
     LLPipeline::sShowHUDAttachments = FALSE;
     LLRect window_rect = getWorldViewRectRaw();
 
@@ -5365,9 +5387,15 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
         }
     }
 
-    if (prev_draw_particles)
+    if (!dynamic_render)
     {
-        gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
+        for (int i = 0; i < dynamic_render_type_count; ++i)
+        {
+            if (prev_dynamic_render_type[i])
+            {
+                gPipeline.toggleRenderType(dynamic_render_types[i]);
+            }
+        }
     }
 
     LLPipeline::sShowHUDAttachments = TRUE;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 38ec0e1ac8b..387a2cb06f5 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -370,7 +370,7 @@ class LLViewerWindow : public LLWindowCallbacks
     // index - cube index in the array to use (cube index, not face-layer)
     // face - which cube face to update
     // near_clip - near clip setting to use
-    BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip);
+    BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip, bool render_avatars);
 
     
     // special implementation of simpleSnapshot for reflection maps
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 8f5d2d1c29a..3a619b4fcc9 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3545,14 +3545,27 @@ void LLVOVolume::setReflectionProbeNearClip(F32 near_clip)
     }
 }
 
-void LLVOVolume::setReflectionProbeVolumeType(LLReflectionProbeParams::EInfluenceVolumeType volume_type)
+void LLVOVolume::setReflectionProbeIsBox(bool is_box)
 {
     LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
     if (param_block)
     {
-        if (param_block->getVolumeType() != volume_type)
+        if (param_block->getIsBox() != is_box)
         {
-            param_block->setVolumeType(volume_type);
+            param_block->setIsBox(is_box);
+            parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+        }
+    }
+}
+
+void LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
+{
+    LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+    if (param_block)
+    {
+        if (param_block->getIsDynamic() != is_dynamic)
+        {
+            param_block->setIsDynamic(is_dynamic);
             parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
         }
     }
@@ -3603,17 +3616,26 @@ F32 LLVOVolume::getReflectionProbeNearClip() const
     }
 }
 
-LLReflectionProbeParams::EInfluenceVolumeType LLVOVolume::getReflectionProbeVolumeType() const
+bool LLVOVolume::getReflectionProbeIsBox() const
 {
     const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
     if (param_block)
     {
-        return param_block->getVolumeType();
+        return param_block->getIsBox();
     }
-    else
+    
+    return false;
+}
+
+bool LLVOVolume::getReflectionProbeIsDynamic() const
+{
+    const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+    if (param_block)
     {
-        return LLReflectionProbeParams::DEFAULT_VOLUME_TYPE;
+        return param_block->getIsDynamic();
     }
+
+    return false;
 }
 
 U32 LLVOVolume::getVolumeInterfaceID() const
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index ad7a2c56067..1ca6b49c7d8 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -289,12 +289,14 @@ class LLVOVolume : public LLViewerObject
     void setIsReflectionProbe(BOOL is_probe);
     void setReflectionProbeAmbiance(F32 ambiance);
     void setReflectionProbeNearClip(F32 near_clip);
-    void setReflectionProbeVolumeType(LLReflectionProbeParams::EInfluenceVolumeType volume_type);
+    void setReflectionProbeIsBox(bool is_box);
+    void setReflectionProbeIsDynamic(bool is_dynamic);
 
     BOOL isReflectionProbe() const override;
     F32 getReflectionProbeAmbiance() const;
     F32 getReflectionProbeNearClip() const;
-    LLReflectionProbeParams::EInfluenceVolumeType getReflectionProbeVolumeType() const;
+    bool getReflectionProbeIsBox() const;
+    bool getReflectionProbeIsDynamic() const;
 
 	// Flexible Objects
 	U32 getVolumeInterfaceID() const;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 20a21a685c0..28dc3781baa 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6734,15 +6734,6 @@ void LLPipeline::toggleRenderType(U32 type)
 //static
 void LLPipeline::toggleRenderTypeControl(U32 type)
 {
-	U32 bit = (1<<type);
-	if (gPipeline.hasRenderType(type))
-	{
-		LL_INFOS() << "Toggling render type mask " << std::hex << bit << " off" << std::dec << LL_ENDL;
-	}
-	else
-	{
-		LL_INFOS() << "Toggling render type mask " << std::hex << bit << " on" << std::dec << LL_ENDL;
-	}
 	gPipeline.toggleRenderType(type);
 }
 
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index ae4eb642647..449bf8fa3a9 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2317,7 +2317,7 @@ even though the user gets a free copy.
              left="10"
              name="Light Checkbox Ctrl"
              tool_tip="Causes object to emit light"
-             top_pad="15"
+             top_pad="10"
              width="60" />
             <color_swatch
              can_apply_immediately="true"
@@ -2425,16 +2425,16 @@ even though the user gets a free copy.
              label="Reflection Probe"
              layout="topleft"
              left="10"
-             name="Reflection Probe Checkbox Ctrl"
+             name="Reflection Probe"
              tool_tip="Adjusts how objects within this volume receive reflections when PBR is enabled"
-             top_pad="15"
+             top_pad="10"
              width="60" />
           <combo_box
 			   height="19"
 			   top_delta="0"
          left="144"
 			   follows="left|top"
-			   name="Probe Volume Type Ctrl"
+			   name="Probe Volume Type"
 			   tool_tip="Choose the probe influence volume"
 			   width="108">
             <combo_box.item
@@ -2446,6 +2446,15 @@ even though the user gets a free copy.
              name="Box"
              value="Box"/>
           </combo_box>
+          <check_box
+             height="16"
+             label="Dynamic"
+             layout="topleft"
+             left="10"
+             name="Probe Dynamic"
+             tool_tip="When enabled, Avatars will appear in reflections within this probe's influence volume."
+             bottom_delta="19"
+             width="60" />
           <spinner bottom_delta="19"
                    decimal_digits="3"
                    follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 159b9aebd00..7a5c2099eb5 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1418,13 +1418,13 @@ function="World.EnvPreset"
                      parameter="movable" />
                 </menu_item_check>
             <menu_item_check
-                 label="Select Reflection Probes"
-                 name="Select Reflection Probes">
+                 label="Select Invisible Objects"
+                 name="Select Invisible Objects">
                     <menu_item_check.on_check
-                     control="SelectReflectionProbes" />
+                     control="SelectInvisibleObjects" />
                     <menu_item_check.on_click
-                     function="Tools.SelectReflectionProbes"
-                     parameter="probes" />
+                     function="Tools.SelectInvisibleObjects"
+                     parameter="invisible" />
             </menu_item_check>
                 <menu_item_check
                  label="Select By Surrounding"
-- 
GitLab