From ee51eee6275d6238a606da028a779bb07dc3b64c Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 19 Jul 2016 19:33:50 +0300
Subject: [PATCH] MAINT-6259 rigged items' LOD should be size dependent, not
 only avatar dependent

---
 indra/newview/app_settings/settings.xml | 11 +++++++++++
 indra/newview/llappviewer.cpp           |  1 +
 indra/newview/llviewercontrol.cpp       |  7 +++++++
 indra/newview/llvovolume.cpp            | 26 ++++++++++++++++---------
 indra/newview/llvovolume.h              |  3 ++-
 5 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 90ad5a605db..c3d7d67c86c 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10218,6 +10218,17 @@
       <key>Value</key>
       <real>1.0</real>
     </map>
+    <key>RenderRiggedFactorMultiplier</key>
+    <map>
+      <key>Comment</key>
+      <string>Affects level of detail for worn rigged meshes</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>7.5</real>
+    </map>
     <key>RenderWater</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 724eb56286e..950692a788b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -587,6 +587,7 @@ static void settings_to_globals()
 	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic");
 	LLImageGL::sCompressTextures		= gSavedSettings.getBOOL("RenderCompressTextures");
 	LLVOVolume::sLODFactor				= gSavedSettings.getF32("RenderVolumeLODFactor");
+	LLVOVolume::sRiggedFactorMultiplier	= gSavedSettings.getF32("RenderRiggedFactorMultiplier");
 	LLVOVolume::sDistanceFactor			= 1.f-LLVOVolume::sLODFactor * 0.1f;
 	LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
 	LLVOTree::sTreeFactor				= gSavedSettings.getF32("RenderTreeLODFactor");
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 16f40fb7473..5e74e9f0193 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -207,6 +207,12 @@ static bool handleVolumeLODChanged(const LLSD& newvalue)
 	return true;
 }
 
+static bool handleRiggedLODChanged(const LLSD& newvalue)
+{
+    LLVOVolume::sRiggedFactorMultiplier = (F32)newvalue.asReal();
+    return true;
+}
+
 static bool handleAvatarLODChanged(const LLSD& newvalue)
 {
 	LLVOAvatar::sLODFactor = (F32) newvalue.asReal();
@@ -619,6 +625,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
+	gSavedSettings.getControl("RenderRiggedFactorMultiplier")->getSignal()->connect(boost::bind(&handleRiggedLODChanged, _2));
 	gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
 	gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));
 	gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2));
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index fde997d54ea..5fc571bf1d9 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -86,6 +86,7 @@ BOOL gAnimateTextures = TRUE;
 //extern BOOL gHideSelectedObjects;
 
 F32 LLVOVolume::sLODFactor = 1.f;
+F32 LLVOVolume::sRiggedFactorMultiplier = 6.f;
 F32	LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop 
 F32 LLVOVolume::sDistanceFactor = 1.0f;
 S32 LLVOVolume::sNumLODChanges = 0;
@@ -1213,18 +1214,18 @@ void LLVOVolume::sculpt()
 	}
 }
 
-S32	LLVOVolume::computeLODDetail(F32 distance, F32 radius)
+S32	LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor)
 {
 	S32	cur_detail;
 	if (LLPipeline::sDynamicLOD)
 	{
 		// We've got LOD in the profile, and in the twist.  Use radius.
-		F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance;
+		F32 tan_angle = (lod_factor*radius) / distance;
 		cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f));
 	}
 	else
 	{
-		cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3);		
+		cur_detail = llclamp((S32)(sqrtf(radius)*lod_factor*4.f), 0, 3);
 	}
 	return cur_detail;
 }
@@ -1240,6 +1241,7 @@ BOOL LLVOVolume::calcLOD()
 	
 	F32 radius;
 	F32 distance;
+	F32 lod_factor = LLVOVolume::sLODFactor;
 
 	if (mDrawable->isState(LLDrawable::RIGGED))
 	{
@@ -1251,22 +1253,27 @@ BOOL LLVOVolume::calcLOD()
 			return FALSE;
 		}
 
+		// Note: when changing, take note that a lot of rigged meshes have only one LOD.
+		lod_factor *= LLVOVolume::sRiggedFactorMultiplier;
 		distance = avatar->mDrawable->mDistanceWRTCamera;
-		radius = avatar->getBinRadius();
+		F32 avatar_radius = avatar->getBinRadius();
+		F32 object_radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length();
+		radius = object_radius * LLVOVolume::sRiggedFactorMultiplier;
+		radius = llmin(radius, avatar_radius);
 	}
 	else
 	{
 		distance = mDrawable->mDistanceWRTCamera;
 		radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length();
 	}
-	
+
 	//hold onto unmodified distance for debugging
 	//F32 debug_distance = distance;
-	
+
 	distance *= sDistanceFactor;
 
-	F32 rampDist = LLVOVolume::sLODFactor * 2;
-	
+	F32 rampDist = lod_factor * 2;
+
 	if (distance < rampDist)
 	{
 		// Boost LOD when you're REALLY close
@@ -1279,7 +1286,8 @@ BOOL LLVOVolume::calcLOD()
 	distance *= F_PI/3.f;
 
 	cur_detail = computeLODDetail(ll_round(distance, 0.01f), 
-									ll_round(radius, 0.01f));
+									ll_round(radius, 0.01f),
+									lod_factor);
 
 
 	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index a3319083200..ca9917069b0 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -327,7 +327,7 @@ class LLVOVolume : public LLViewerObject
 	void clearRiggedVolume();
 
 protected:
-	S32	computeLODDetail(F32	distance, F32 radius);
+	S32	computeLODDetail(F32	distance, F32 radius, F32 lod_factor);
 	BOOL calcLOD();
 	LLFace* addFace(S32 face_index);
 	void updateTEData();
@@ -379,6 +379,7 @@ class LLVOVolume : public LLViewerObject
 public:
 	static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
 	static F32 sLODFactor;				// LOD scale factor
+	static F32 sRiggedFactorMultiplier;	// Worn rigged LOD scale factor multiplier
 	static F32 sDistanceFactor;			// LOD distance factor
 
 	static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
-- 
GitLab