From 40e942b4910d69043b00de4cf64299ae8932f47d Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Mon, 6 Mar 2023 13:58:33 -0800
Subject: [PATCH] SL-19345: Fix Blinn-Phong normspec materials not having
 texture transforms on their normal/specular textures

---
 indra/newview/llface.cpp | 120 +++++++++++++++++++++++++--------------
 1 file changed, 76 insertions(+), 44 deletions(-)

diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index d05e367c12c..87abb06285d 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1322,39 +1322,75 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 		}
 	}
 	
+
+    LLMaterial* mat = tep->getMaterialParams().get();
+    LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial();
+
 	F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
-	bool do_xform = false;
-	if (rebuild_tcoord)
-	{
-		if (tep)
-		{
-			r  = tep->getRotation();
-			os = tep->mOffsetS;
-			ot = tep->mOffsetT;
-			ms = tep->mScaleS;
-			mt = tep->mScaleT;
-			cos_ang = cos(r);
-			sin_ang = sin(r);
-
-			if (cos_ang != 1.f || 
-				sin_ang != 0.f ||
-				os != 0.f ||
-				ot != 0.f ||
-				ms != 1.f ||
-				mt != 1.f)
-			{
-				do_xform = true;
-			}
-			else
-			{
-				do_xform = false;
-			}	
-		}
-		else
-		{
-			do_xform = false;
-		}
-	}
+
+    constexpr S32 XFORM_NONE = 0;
+    constexpr S32 XFORM_BLINNPHONG_COLOR = 1;
+    constexpr S32 XFORM_BLINNPHONG_NORMAL = 1 << 1;
+    constexpr S32 XFORM_BLINNPHONG_SPECULAR = 1 << 2;
+
+    S32 xforms = XFORM_NONE;
+    // For GLTF, transforms will be applied later
+    if (rebuild_tcoord && tep && !gltf_mat)
+    {
+        r  = tep->getRotation();
+        os = tep->mOffsetS;
+        ot = tep->mOffsetT;
+        ms = tep->mScaleS;
+        mt = tep->mScaleT;
+        cos_ang = cos(r);
+        sin_ang = sin(r);
+
+        if (cos_ang != 1.f ||
+            sin_ang != 0.f ||
+            os != 0.f ||
+            ot != 0.f ||
+            ms != 1.f ||
+            mt != 1.f)
+        {
+            xforms |= XFORM_BLINNPHONG_COLOR;
+        }
+        if (mat)
+        {
+            F32 r_norm = 0, os_norm = 0, ot_norm = 0, ms_norm = 0, mt_norm = 0, cos_ang_norm = 0, sin_ang_norm = 0;
+            mat->getNormalOffset(os_norm, ot_norm);
+            mat->getNormalRepeat(ms_norm, mt_norm);
+            r_norm = mat->getNormalRotation();
+            cos_ang_norm = cos(r_norm);
+            sin_ang_norm = sin(r_norm);
+            if (cos_ang_norm != 1.f ||
+                sin_ang_norm != 0.f ||
+                os_norm != 0.f ||
+                ot_norm != 0.f ||
+                ms_norm != 1.f ||
+                mt_norm != 1.f)
+            {
+                xforms |= XFORM_BLINNPHONG_NORMAL;
+            }
+        }
+        if (mat)
+        {
+            F32 r_spec = 0, os_spec = 0, ot_spec = 0, ms_spec = 0, mt_spec = 0, cos_ang_spec = 0, sin_ang_spec = 0;
+            mat->getSpecularOffset(os_spec, ot_spec);
+            mat->getSpecularRepeat(ms_spec, mt_spec);
+            r_spec = mat->getSpecularRotation();
+            cos_ang_spec = cos(r_spec);
+            sin_ang_spec = sin(r_spec);
+            if (cos_ang_spec != 1.f ||
+                sin_ang_spec != 0.f ||
+                os_spec != 0.f ||
+                ot_spec != 0.f ||
+                ms_spec != 1.f ||
+                mt_spec != 1.f)
+            {
+                xforms |= XFORM_BLINNPHONG_SPECULAR;
+            }
+        }
+    }
 	
     const LLMeshSkinInfo* skin = nullptr;
     LLMatrix4a mat_vert;
@@ -1495,7 +1531,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 					sin_ang = 0.f;
 					ms = mt = 1.f;
 
-					do_xform = false;
+                    xforms = XFORM_NONE;
 				}
 
 				if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED))
@@ -1507,15 +1543,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 			LLVector4a scalea;
 			scalea.load3(scale.mV);
 
-			LLMaterial* mat = tep->getMaterialParams().get();
-            LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial();
-
-            if (gltf_mat)
-            {
-                // Transforms will be applied later
-                do_xform = false;
-            }
-
 			bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
 
 			if ((mat || gltf_mat) && !do_bump)
@@ -1536,7 +1563,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
                     LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen");
 					if (!do_tex_mat)
 					{
-						if (!do_xform)
+						if (xforms == XFORM_NONE)
 						{
                             LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("ggv - texgen 1");
 							S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
@@ -1615,7 +1642,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 							*tex_coords0++ = tc;	
 						}
 					}
-					else if (do_xform)
+					else if (xforms != XFORM_NONE)
 					{
 						for (S32 i = 0; i < num_vertices; i++)
 						{	
@@ -1662,12 +1689,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 				for (U32 ch = 0; ch < 3; ++ch)
 				{
+                    S32 xform_channel = XFORM_NONE;
 					switch (ch)
 					{
 						case 0: 
+                            xform_channel = XFORM_BLINNPHONG_COLOR;
 							mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount); 
 							break;
 						case 1:
+                            xform_channel = XFORM_BLINNPHONG_NORMAL;
 							if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
 							{
 								mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount);
@@ -1688,6 +1718,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 							}
 							break;
 						case 2:
+                            xform_channel = XFORM_BLINNPHONG_SPECULAR;
 							if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))
 							{
 								mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount);
@@ -1707,6 +1738,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 							}
 							break;
 					}
+                    const bool do_xform = (xforms & xform_channel) != XFORM_NONE;
 					
 
                     for (S32 i = 0; i < num_vertices; i++)
-- 
GitLab