From 5fba55f58e35e52485f161d069f323120ec68b6d Mon Sep 17 00:00:00 2001
From: Monroe Linden <monroe@lindenlab.com>
Date: Fri, 6 Nov 2009 19:30:52 -0800
Subject: [PATCH] Partial fix for DEV-42153.

This code seems to work on some objects and not on others.  I suspect I'm not doing something quite right in LLVOVolume::getApproximateFaceNormal().
---
 indra/newview/llviewermediafocus.cpp | 10 +++++--
 indra/newview/llvovolume.cpp         | 39 ++++++++++++++++++++++++++++
 indra/newview/llvovolume.h           |  2 ++
 3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index b2a0fa4b1c7..70a7d835a36 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -499,8 +499,14 @@ void LLViewerMediaFocus::focusZoomOnMedia(LLUUID media_id)
 			S32 face = obj->getFaceIndexWithMediaImpl(impl, -1);
 			
 			// We don't have a proper pick normal here, and finding a face's real normal is... complicated.
-			// For now, use +z to look at the top of the object.
-			LLVector3 normal(0.0f, 0.0f, 1.0f);
+			LLVector3 normal = obj->getApproximateFaceNormal(face);
+			if(normal.isNull())
+			{
+				// If that didn't work, use the inverse of the camera "look at" axis, which should keep the camera pointed in the same direction.
+//				llinfos << "approximate face normal invalid, using camera direction." << llendl;
+				normal = LLViewerCamera::getInstance()->getAtAxis();
+				normal *= (F32)-1.0f;
+			}
 			
 			// Attempt to focus/zoom on that face.
 			setFocusFace(obj, face, impl, normal);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 78f534bacd8..021fc746488 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1638,6 +1638,45 @@ bool LLVOVolume::hasMedia() const
 	return result;
 }
 
+LLVector3 LLVOVolume::getApproximateFaceNormal(U8 face_id)
+{
+	LLVector3 result = LLVector3::zero;
+	
+	LLFace* facep = mDrawable->getFace(face_id);
+	if(facep)
+	{
+		LLStrider<LLVector3> verticesp;
+		LLStrider<LLVector3> normalsp;
+		LLStrider<LLVector2> texCoordsp;
+		LLStrider<U16> indicesp;
+		S32 index_offset;
+		index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
+		
+		if(index_offset != -1 && (normalsp.get() != NULL))
+		{
+			U16 count = facep->getGeomCount();
+			U16 i;
+			
+			for(i=0; i < count; i++)
+			{
+				LLVector3 normal = *normalsp++;
+//				llinfos << "adding " << normal << llendl;
+				result += normal;
+			}
+		}
+	}
+	
+	if(!result.isNull())
+	{
+//		llinfos << "before conversion: " << result << llendl;
+		result = volumeDirectionToAgent(result);
+		result.normalize();
+//		llinfos << "after conversion: " << result << llendl;
+	}
+	
+	return result;
+}
+
 void LLVOVolume::requestMediaDataUpdate()
 {
     sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this));
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 0574d3e3856..784ef16ba36 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -263,6 +263,8 @@ class LLVOVolume : public LLViewerObject
 	F64 getTotalMediaInterest() const;
    
 	bool hasMedia() const;
+	
+	LLVector3 getApproximateFaceNormal(U8 face_id);
 
 protected:
 	S32	computeLODDetail(F32	distance, F32 radius);
-- 
GitLab