From 3e86dd7df0f757a8f59a91ef4a3bb3af6a49b51d Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Thu, 14 May 2015 18:46:04 +0200
Subject: [PATCH] Apply runtime changes to field of view & view distance

---
 apps/openmw/mwrender/renderingmanager.cpp | 42 ++++++++++++++++++-----
 apps/openmw/mwrender/renderingmanager.hpp |  7 ++++
 apps/openmw/mwworld/worldimp.cpp          |  2 +-
 files/settings-default.cfg                |  3 ++
 4 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp
index 49e6ba06fa..7822ccb30d 100644
--- a/apps/openmw/mwrender/renderingmanager.cpp
+++ b/apps/openmw/mwrender/renderingmanager.cpp
@@ -128,8 +128,10 @@ namespace MWRender
 
         osg::Camera::CullingMode cullingMode = osg::Camera::DEFAULT_CULLING|osg::Camera::FAR_PLANE_CULLING;
 
-        // for consistent benchmarks against the ogre branch. remove later
-        cullingMode &= ~(osg::CullStack::SMALL_FEATURE_CULLING);
+        if (!Settings::Manager::getBool("small feature culling", "Viewing distance"))
+            cullingMode &= ~(osg::CullStack::SMALL_FEATURE_CULLING);
+        else
+            cullingMode |= osg::CullStack::SMALL_FEATURE_CULLING;
 
         viewer.getCamera()->setCullingMode( cullingMode );
 
@@ -137,13 +139,8 @@ namespace MWRender
         mViewer.getCamera()->setCullingMode(cullingMode);
 
         mViewDistance = Settings::Manager::getFloat("viewing distance", "Viewing distance");
-
-        double fovy, aspect, zNear, zFar;
-        mViewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
-        fovy = 55.f;
-        zNear = 5.f;
-        zFar = mViewDistance;
-        mViewer.getCamera()->setProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
+        mFieldOfView = Settings::Manager::getFloat("field of view", "General");
+        updateProjectionMatrix();
     }
 
     RenderingManager::~RenderingManager()
@@ -325,4 +322,31 @@ namespace MWRender
         //mWater->addEmitter(ptr);
     }
 
+    void RenderingManager::updateProjectionMatrix()
+    {
+        double fovy, aspect, zNear, zFar;
+        mViewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
+        fovy = mFieldOfView;
+        zNear = 5.f;
+        zFar = mViewDistance;
+        mViewer.getCamera()->setProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
+    }
+
+    void RenderingManager::processChangedSettings(const Settings::CategorySettingVector &changed)
+    {
+        for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it)
+        {
+            if (it->first == "General" && it->second == "field of view")
+            {
+                mFieldOfView = Settings::Manager::getFloat("field of view", "General");
+                updateProjectionMatrix();
+            }
+            else if (it->first == "Viewing distance" && it->second == "viewing distance")
+            {
+                mViewDistance = Settings::Manager::getFloat("viewing distance", "Viewing distance");
+                updateProjectionMatrix();
+            }
+        }
+    }
+
 }
diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp
index 7d902b8545..b13dffb8ca 100644
--- a/apps/openmw/mwrender/renderingmanager.hpp
+++ b/apps/openmw/mwrender/renderingmanager.hpp
@@ -4,6 +4,8 @@
 #include <osg/ref_ptr>
 #include <osg/Light>
 
+#include <components/settings/settings.hpp>
+
 #include "objects.hpp"
 
 #include "renderinginterface.hpp"
@@ -93,7 +95,11 @@ namespace MWRender
         void setupPlayer(const MWWorld::Ptr& player);
         void renderPlayer(const MWWorld::Ptr& player);
 
+        void processChangedSettings(const Settings::CategorySettingVector& settings);
+
     private:
+        void updateProjectionMatrix();
+
         osgViewer::Viewer& mViewer;
         osg::ref_ptr<osg::Group> mRootNode;
         osg::ref_ptr<osg::Group> mLightRoot;
@@ -111,6 +117,7 @@ namespace MWRender
         osg::ref_ptr<StateUpdater> mStateUpdater;
 
         float mViewDistance;
+        float mFieldOfView;
 
         void operator = (const RenderingManager&);
         RenderingManager(const RenderingManager&);
diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp
index 32eb92d2af..bbd98be561 100644
--- a/apps/openmw/mwworld/worldimp.cpp
+++ b/apps/openmw/mwworld/worldimp.cpp
@@ -1971,7 +1971,7 @@ namespace MWWorld
 
     void World::processChangedSettings(const Settings::CategorySettingVector& settings)
     {
-        //mRendering->processChangedSettings(settings);
+        mRendering->processChangedSettings(settings);
     }
 
     bool World::isFlying(const MWWorld::Ptr &ptr) const
diff --git a/files/settings-default.cfg b/files/settings-default.cfg
index 7f2185b62d..eeea0e6e18 100644
--- a/files/settings-default.cfg
+++ b/files/settings-default.cfg
@@ -132,6 +132,9 @@ fog start factor = 0.5
 # Distance at which fog ends (proportional to viewing distance)
 fog end factor = 1.0
 
+# Culling of objects smaller than a pixel
+small feature culling = true
+
 [Terrain]
 distant land = false