From 861393910a47a367799567e0641769731ecc4e00 Mon Sep 17 00:00:00 2001
From: Howard Stearns <howard@highfidelity.io>
Date: Wed, 2 Dec 2015 12:12:57 -0800
Subject: [PATCH] Add an avatar LOD preference called "Minimum Avatar Display
 Distance"

---
 interface/src/avatar/AvatarManager.cpp | 13 ++++-
 interface/src/avatar/AvatarManager.h   |  4 +-
 interface/src/ui/PreferencesDialog.cpp |  2 +
 interface/ui/preferencesDialog.ui      | 79 ++++++++++++++++++++++++++
 4 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp
index 9df597109c..e094f2e263 100644
--- a/interface/src/avatar/AvatarManager.cpp
+++ b/interface/src/avatar/AvatarManager.cpp
@@ -27,6 +27,8 @@
 
 #include <PerfStat.h>
 #include <RegisteredMetaTypes.h>
+#include <Rig.h>
+#include <SettingHandle.h>
 #include <UUID.h>
 
 #include "Application.h"
@@ -35,7 +37,6 @@
 #include "Menu.h"
 #include "MyAvatar.h"
 #include "SceneScriptingInterface.h"
-#include <Rig.h>
 
 // 70 times per second - target is 60hz, but this helps account for any small deviations
 // in the update loop
@@ -75,6 +76,13 @@ AvatarManager::AvatarManager(QObject* parent) :
     packetReceiver.registerListener(PacketType::AvatarBillboard, this, "processAvatarBillboardPacket");
 }
 
+const float SMALLEST_REASONABLE_HORIZON = 5.0f; // meters
+Setting::Handle<float> avatarRenderDistanceHighLimit("avatarRenderDistanceHighLimit", 1.0f / SMALLEST_REASONABLE_HORIZON);
+void AvatarManager::setRenderDistanceHighLimit(float newValue) {
+    avatarRenderDistanceHighLimit.set(newValue);
+     _renderDistanceController.setControlledValueHighLimit(newValue);
+}
+
 void AvatarManager::init() {
     _myAvatar->init();
     {
@@ -93,8 +101,7 @@ void AvatarManager::init() {
 
     const float target_fps = qApp->getTargetFrameRate();
     _renderDistanceController.setMeasuredValueSetpoint(target_fps);
-    const float SMALLEST_REASONABLE_HORIZON = 5.0f; // meters
-    _renderDistanceController.setControlledValueHighLimit(1.0f / SMALLEST_REASONABLE_HORIZON);
+    _renderDistanceController.setControlledValueHighLimit(avatarRenderDistanceHighLimit.get());
     _renderDistanceController.setControlledValueLowLimit(1.0f / (float) TREE_SCALE);
     // Advice for tuning parameters:
     // See PIDController.h. There's a section on tuning in the reference.
diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h
index 96383b7e60..ddc40d8490 100644
--- a/interface/src/avatar/AvatarManager.h
+++ b/interface/src/avatar/AvatarManager.h
@@ -70,6 +70,8 @@ public:
     
     // Expose results and parameter-tuning operations to other systems, such as stats and javascript.
     Q_INVOKABLE float getRenderDistance() { return _renderDistance; }
+    Q_INVOKABLE float getRenderDistanceLowLimit() { return _renderDistanceController.getControlledValueLowLimit(); }
+    Q_INVOKABLE float getRenderDistanceHighLimit() { return _renderDistanceController.getControlledValueHighLimit(); }
     Q_INVOKABLE int getNumberInRenderRange() { return _renderedAvatarCount; }
     Q_INVOKABLE bool getRenderDistanceControllerIsLogging() { return _renderDistanceController.getIsLogging(); }
     Q_INVOKABLE void setRenderDistanceControllerHistory(QString label, int size) { return _renderDistanceController.setHistorySize(label, size); }
@@ -77,7 +79,7 @@ public:
     Q_INVOKABLE void setRenderDistanceKI(float newValue) { _renderDistanceController.setKI(newValue); }
     Q_INVOKABLE void setRenderDistanceKD(float newValue) { _renderDistanceController.setKD(newValue); }
     Q_INVOKABLE void setRenderDistanceLowLimit(float newValue) { _renderDistanceController.setControlledValueLowLimit(newValue); }
-    Q_INVOKABLE void setRenderDistanceHighLimit(float newValue) { _renderDistanceController.setControlledValueHighLimit(newValue); }
+    Q_INVOKABLE void setRenderDistanceHighLimit(float newValue);
    
 public slots:
     void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; }
diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp
index c37755b823..69ece359e9 100644
--- a/interface/src/ui/PreferencesDialog.cpp
+++ b/interface/src/ui/PreferencesDialog.cpp
@@ -204,6 +204,7 @@ void PreferencesDialog::loadPreferences() {
     auto lodManager = DependencyManager::get<LODManager>();
     ui.desktopMinimumFPSSpin->setValue(lodManager->getDesktopLODDecreaseFPS());
     ui.hmdMinimumFPSSpin->setValue(lodManager->getHMDLODDecreaseFPS());
+    ui.avatarRenderSmallestReasonableHorizon->setValue(1.0f / DependencyManager::get<AvatarManager>()->getRenderDistanceHighLimit());
 }
 
 void PreferencesDialog::savePreferences() {
@@ -294,4 +295,5 @@ void PreferencesDialog::savePreferences() {
     auto lodManager = DependencyManager::get<LODManager>();
     lodManager->setDesktopLODDecreaseFPS(ui.desktopMinimumFPSSpin->value());
     lodManager->setHMDLODDecreaseFPS(ui.hmdMinimumFPSSpin->value());
+    DependencyManager::get<AvatarManager>()->setRenderDistanceHighLimit(1.0f / ui.avatarRenderSmallestReasonableHorizon->value());
 }
diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui
index a1137a2bf2..e6a5e2228d 100644
--- a/interface/ui/preferencesDialog.ui
+++ b/interface/ui/preferencesDialog.ui
@@ -912,6 +912,85 @@
         </layout>
        </item>
 
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_111yz">
+         <property name="spacing">
+          <number>0</number>
+         </property>
+         <property name="topMargin">
+          <number>7</number>
+         </property>
+         <property name="rightMargin">
+          <number>0</number>
+         </property>
+         <property name="bottomMargin">
+          <number>7</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="label_9yz">
+           <property name="font">
+            <font>
+             <family>Arial</family>
+            </font>
+           </property>
+           <property name="styleSheet">
+            <string notr="true"/>
+           </property>
+           <property name="text">
+            <string>Minimum Avatar Display Distance</string>
+           </property>
+           <property name="indent">
+            <number>0</number>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_111yz">
+           <property name="font">
+            <font>
+             <family>Arial</family>
+            </font>
+           </property>
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>0</width>
+             <height>0</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QSpinBox" name="avatarRenderSmallestReasonableHorizon">
+           <property name="minimumSize">
+            <size>
+             <width>100</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>95</width>
+             <height>36</height>
+            </size>
+           </property>
+           <property name="font">
+            <font>
+             <family>Arial</family>
+            </font>
+           </property>
+           <property name="minimum">
+            <number>5</number>
+           </property>
+           <property name="maximum">
+            <number>32768</number>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
 
        <item>
         <spacer name="verticalSpacer_8">