From 25aee5e983a8de712565d8241cbdb18da832a4d1 Mon Sep 17 00:00:00 2001
From: "Jonathan \"Geenz\" Goodman" <geenz@geenzo.com>
Date: Fri, 8 Sep 2023 15:54:52 -0700
Subject: [PATCH] Some more modes for mirrors to place the probe.

DRTVWR-583
---
 .../shaders/class3/deferred/softenLightF.glsl |   3 +
 indra/newview/llheroprobemanager.cpp          | 165 +++++++++++-------
 indra/newview/llviewerobject.cpp              |  93 ++++++----
 3 files changed, 171 insertions(+), 90 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 742b52b0740..24833552052 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -280,6 +280,9 @@ void main()
 
             // add radiance map
             applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
+
+            color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - spec.a) * 11).xyz * spec.rgb;
+
         }
 
         color.rgb = mix(color.rgb, baseColor.rgb, baseColor.a);
diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp
index 166321930fd..64c9ab15278 100644
--- a/indra/newview/llheroprobemanager.cpp
+++ b/indra/newview/llheroprobemanager.cpp
@@ -105,75 +105,121 @@ void LLHeroProbeManager::update()
     
     LLVector4a probe_pos;
     LLVector3 camera_pos = LLViewerCamera::instance().mOrigin;
+    if (mHeroVOList.size() > 0)
     {
-        // Get the nearest hero.
-        float distance = F32_MAX;
-        
-        if (mNearestHero != nullptr)
         {
-            distance = mNearestHero->mDrawable->mDistanceWRTCamera;
-        }
-        
-        for (auto drawable : mHeroVOList)
-        {
-            if (drawable != nullptr && drawable != mNearestHero && drawable->mDrawable.notNull())
+            if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull())
             {
-                if (drawable->mDrawable->mDistanceWRTCamera < distance)
-                {
-                    mIsInTransition = true;
-                    mNearestHero = drawable;
+                LLVector3 hero_pos = mNearestHero->getPosition();
+                
+                // Make sure our camera is clamped to the hero's bounding box.
+                camera_pos.clamp(mNearestHero->getBoundingBoxAgent().getMinAgent(), mNearestHero->getBoundingBoxAgent().getMaxAgent());
+                bool hit = false;
+                LLVector4a hit_pos;
+                LLVector3 focus_point;
+                LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
+                LLQuaternion camera_rot;
+                
+                switch (mNearestHero->mirrorPlacementMode()) {
+                    case 0:
+                        probe_pos.set(camera_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]);
+                        break;
+                    case 1:
+                        
+                        probe_pos.set(hero_pos.mV[0], camera_pos.mV[1], hero_pos.mV[2]);
+                        break;
+                    case 2:
+                        
+                        probe_pos.set(hero_pos.mV[0], hero_pos.mV[1], camera_pos.mV[2]);
+                        break;
+                        
+                    case 3:
+                        // Find the nearest point relative to the camera on the VOVolume.
+                        hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]),
+                                                                      LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]),
+                                                                      -1,
+                                                                      FALSE,
+                                                                      FALSE,
+                                                                      FALSE,
+                                                                      NULL,
+                                                                      &hit_pos);
+                        if (hit)
+                            probe_pos = hit_pos;
+                        break;
+                        
+                    case 4:
+                        probe_pos.load3(hero_pos.mV);
+                        break;
+                    case 5:
+                        focus_point.set(hero_pos.mV[0] - mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[0], hero_pos.mV[1], hero_pos.mV[2]);
+                        probe_pos.load3(focus_point.mV);
+                        break;
+                    case 6:
+                        focus_point.set(hero_pos.mV[0] + mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[0], hero_pos.mV[1], hero_pos.mV[2]);
+                        probe_pos.load3(focus_point.mV);
+                        break;
+                    case 7:
+
+                        if (obj && obj->mDrawable && obj->isSelected())
+                        { // focus on selected media object
+                            S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
+                            if (obj && obj->mDrawable)
+                            {
+                                LLFace* face = obj->mDrawable->getFace(face_idx);
+                                if (face)
+                                {
+                                    focus_point = face->getPositionAgent();
+                                }
+                            }
+                        }
+
+                        if (focus_point.isExactlyZero())
+                        {
+                            if (LLViewerJoystick::getInstance()->getOverrideCamera())
+                            { // focus on point under cursor
+                                focus_point.set(gDebugRaycastIntersection.getF32ptr());
+                            }
+                            else if (gAgentCamera.cameraMouselook())
+                            { // focus on point under mouselook crosshairs
+                                LLVector4a result;
+                                result.clear();
+
+                                gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, TRUE, NULL, &result);
+
+                                focus_point.set(result.getF32ptr());
+                            }
+                            else
+                            {
+                                // focus on alt-zoom target
+                                LLViewerRegion* region = gAgent.getRegion();
+                                if (region)
+                                {
+                                    focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
+                                }
+                            }
+                        }
+                        
+                        probe_pos.load3(focus_point.mV);
+                        
+                        break;
+                    case 8:
+                        camera_rot.setAngleAxis(180, 0, 0, 1);
+                        focus_point = camera_pos - hero_pos;
+                        focus_point.rotVec(camera_rot);
+                        probe_pos.load3((camera_pos + focus_point).mV);
+                        break;
                 }
             }
+            
+            mHeroProbeStrength = 1;
         }
     }
-    
-    if (mIsInTransition && mHeroProbeStrength > 0.f)
-    {
-        mHeroProbeStrength -= 0.05f;
-    }
     else
     {
-        
-        if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull())
-        {
-            
-            LLVector3 hero_pos = mNearestHero->mDrawable->mXform.getPosition();
-            switch (mNearestHero->mirrorPlacementMode()) {
-                case 0:
-                    probe_pos.set(camera_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]);
-                    break;
-                case 1:
-                    
-                    probe_pos.set(hero_pos.mV[0], camera_pos.mV[1], hero_pos.mV[2]);
-                    break;
-                case 2:
-                    
-                    probe_pos.set(hero_pos.mV[0], hero_pos.mV[1], camera_pos.mV[2]);
-                    break;
-                    
-                case 3:
-                    // Find the nearest point relative to the camera on the VOVolume.
-                    LLVector4a hit_pos;
-                    bool hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]),
-                                                                  LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]),
-                                                                  -1,
-                                                                  FALSE,
-                                                                  FALSE,
-                                                                  FALSE,
-                                                                  NULL,
-                                                                  &hit_pos);
-                    if (hit)
-                        probe_pos = hit_pos;
-                    
-                    break;
-            }
-        }
-        
-        
-        if (mHeroProbeStrength < 1.f)
-            mHeroProbeStrength += 0.05f;
+        probe_pos.load3(camera_pos.mV);
     }
     
+    
     static LLCachedControl<S32> sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1);
     static LLCachedControl<S32> sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3);
 
@@ -224,7 +270,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face)
     LLGLDepthTest depth(GL_FALSE, GL_FALSE);
     LLGLDisable cull(GL_CULL_FACE);
     LLGLDisable blend(GL_BLEND);
-
+    
     // downsample to placeholder map
     {
         gGL.matrixMode(gGL.MM_MODELVIEW);
@@ -558,6 +604,7 @@ void LLHeroProbeManager::doOcclusion()
 
 void LLHeroProbeManager::registerHeroDrawable(LLVOVolume* drawablep)
 {
+    mNearestHero = drawablep;
         if (mHeroVOList.find(drawablep) == mHeroVOList.end())
         {
             mHeroVOList.insert(drawablep);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 7032ce41d58..adb4683af05 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -314,7 +314,9 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mLastUpdateCached(FALSE),
 	mCachedMuteListUpdateTime(0),
 	mCachedOwnerInMuteList(false),
-	mRiggedAttachedWarned(false)
+	mRiggedAttachedWarned(false),
+mIsMirror(false),
+mMirrorPlacementMode(3)
 {
 	if (!is_global)
 	{
@@ -1148,6 +1150,61 @@ U32 LLViewerObject::extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector
 	return parent_id;
 }
 
+void detectMirror(const std::string &str, bool &mirror, U8 &mode)
+{
+    
+    std::stringstream ss(str);
+    std::string word;
+    while (ss >> word)
+    {
+        if (word == "IsMirror")
+        {
+            mirror = true;
+        }
+        else if (word == "XAlign" && mirror)
+        {
+            LL_INFOS() << "Mirror wants camera X placement." << LL_ENDL;
+            mode = 0;
+        }
+        else if (word == "YAlign" && mirror)
+        {
+            LL_INFOS() << "Mirror wants camera Y placement." << LL_ENDL;
+            mode = 1;
+        }
+        else if (word == "ZAlign" && mirror)
+        {
+            LL_INFOS() << "Mirror wants camera Z placement." << LL_ENDL;
+            mode = 2;
+        }
+        else if (word == "NearestPoint" && mirror)
+        {
+            LL_INFOS() << "Mirror wants nearest point placement." << LL_ENDL;
+            mode = 3;
+        }
+        else if (word == "Center" && mirror)
+        {
+            LL_INFOS() << "Mirror wants center of object." << LL_ENDL;
+            mode = 4;
+        }
+        else if (word == "XMin" && mirror)
+        {
+            mode = 5;
+        }
+        else if (word == "XMax" && mirror)
+        {
+            mode = 6;
+        }
+        else if (word == "FocusPoint" && mirror)
+        {
+            mode = 7;
+        }
+        else if (word == "Reflected" && mirror)
+        {
+            mode = 8;
+        }
+    }
+}
+
 U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 					 void **user_data,
 					 U32 block_num,
@@ -1524,33 +1581,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 					std::string temp_string;
 					mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num );
 					
-                    std::stringstream ss(temp_string);
-                    std::string word;
-                    bool mirror_detected = false;
-                    while (ss >> word)
-                    {
-                        if (word == "Mirror")
-                        {
-                            mirror_detected = true;
-                            mIsMirror = true;
-                        }
-                        else if (word == "XAlign" && mIsMirror)
-                        {
-                            mMirrorPlacementMode = 0;
-                        }
-                        else if (word == "YAlign" && mIsMirror)
-                        {
-                            mMirrorPlacementMode = 1;
-                        }
-                        else if (word == "ZAlign" && mIsMirror)
-                        {
-                            mMirrorPlacementMode = 2;
-                        }
-                        else if (word == "NearestPoint" && mIsMirror)
-                        {
-                            mMirrorPlacementMode = 3;
-                        }
-                    }
+                    detectMirror(temp_string, mIsMirror, mMirrorPlacementMode);
                     
 					LLColor4U coloru;
 					mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num);
@@ -1558,9 +1589,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 					// alpha was flipped so that it zero encoded better
 					coloru.mV[3] = 255 - coloru.mV[3];
                     
-                    if (mirror_detected)
-                        coloru.mV[3] = 0;
-                    
 					mText->setColor(LLColor4(coloru));
 					mText->setString(temp_string);
 
@@ -1940,6 +1968,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 				{
 					std::string temp_string;
 					dp->unpackString(temp_string, "Text");
+                    
+                    detectMirror(temp_string, mIsMirror, mMirrorPlacementMode);
+                    
 					LLColor4U coloru;
 					dp->unpackBinaryDataFixed(coloru.mV, 4, "Color");
 					coloru.mV[3] = 255 - coloru.mV[3];
-- 
GitLab