diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp
index 9295233de..51c77e68e 100644
--- a/apps/openmw/mwinput/inputmanagerimp.cpp
+++ b/apps/openmw/mwinput/inputmanagerimp.cpp
@@ -242,7 +242,8 @@ private:
         player(_player),
         windows(_windows),
         mEngine (engine),
-        mDragDrop(false)
+        mDragDrop(false),
+        mPreviewPOVDelay(0.f)
     {
       using namespace OEngine::Input;
       using namespace OEngine::Render;
diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp
index 6e0012d43..68def64e8 100644
--- a/apps/openmw/mwrender/player.cpp
+++ b/apps/openmw/mwrender/player.cpp
@@ -22,7 +22,8 @@ namespace MWRender
       mFirstPersonView(true),
       mPreviewMode(false),
       mHeight(128.f),
-      mCameraDistance(400.f)
+      mCameraDistance(300.f),
+      mDistanceAdjusted(false)
     {
         mVanity.enabled = false;
         mVanity.allowed = true;
@@ -32,7 +33,7 @@ namespace MWRender
         mCameraNode->setPosition(0.f, 0.f, mHeight);
 
         mPreviewCam.yaw = 0.f;
-        mPreviewCam.offset = 600.f;
+        mPreviewCam.offset = 400.f;
     }
     
     bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
@@ -167,7 +168,7 @@ namespace MWRender
         mVanity.enabled = enable;
         mVanity.forced = force && enable;
 
-        float offset = 300.f;
+        float offset = mPreviewCam.offset;
         Ogre::Vector3 rot(0.f, 0.f, 0.f);
         if (mVanity.enabled) {
             mPlayerNode->setVisible(true, false);
@@ -267,32 +268,45 @@ namespace MWRender
         node->addChild(mCameraNode);
     }
 
-    void Player::setCameraDistance(float dist, bool adjust)
+    void Player::setCameraDistance(float dist, bool adjust, bool override)
     {
-        /// \note non-Morrowind feature: allow to change camera distance
-        /// int 3d-person mode
-        /// \todo review and simplify condition if possible
-        if (mPreviewMode ||
-            mVanity.forced ||
-            (!mVanity.enabled && !mFirstPersonView))
-        {
-            Ogre::Vector3 v(0.f, 0.f, dist);
-            if (adjust) {
-                v += mCamera->getPosition();
-            }
-            if (v.z > 800.f) {
-                v.z = 800.f;
-            } else if (v.z < 100.f) {
-                v.z = 100.f;
-            }
-            mCamera->setPosition(v);
+        if (mFirstPersonView && !mPreviewMode && !mVanity.enabled) {
+            return;
+        }
+        Ogre::Vector3 v(0.f, 0.f, dist);
+        if (adjust) {
+            v += mCamera->getPosition();
+        }
+        if (v.z > 800.f) {
+            v.z = 800.f;
+        } else if (v.z < 10.f) {
+            v.z = 10.f;
+        }
+        mCamera->setPosition(v);
 
-            if (!mVanity.enabled && !mFirstPersonView) {
+        if (override) {
+            if (mVanity.enabled || mPreviewMode) {
+                mPreviewCam.offset = v.z;
+            } else if (!mFirstPersonView) {
                 mCameraDistance = v.z;
             }
+        } else {
+            mDistanceAdjusted = true;
         }
     }
 
+    void Player::setCameraDistance()
+    {
+        if (mDistanceAdjusted) {
+            if (mVanity.enabled || mPreviewMode) {
+                mCamera->setPosition(0, 0, mPreviewCam.offset);
+            } else if (!mFirstPersonView) {
+                mCamera->setPosition(0, 0, mCameraDistance);
+            }
+        }
+        mDistanceAdjusted = false;
+    }
+
     void Player::setAnimation(NpcAnimation *anim)
     {
         mAnimation = anim;
@@ -307,6 +321,16 @@ namespace MWRender
 
     float Player::getHeight()
     {
-        return mHeight;
+        return mHeight * mPlayerNode->getScale().z;
+    }
+
+    bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera)
+    {
+        float xch;
+        camera = mCamera->getRealPosition();
+        xch = camera.z, camera.z = camera.y, camera.y = -xch;
+        player = mPlayerNode->getPosition();
+
+        return mFirstPersonView && !mVanity.enabled && !mPreviewMode;
     }
 }
diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp
index 8c1b3ed9f..c3585db9d 100644
--- a/apps/openmw/mwrender/player.hpp
+++ b/apps/openmw/mwrender/player.hpp
@@ -43,6 +43,8 @@ namespace MWRender
         float mHeight, mCameraDistance;
         CamData mMainCam, mPreviewCam;
 
+        bool mDistanceAdjusted;
+
         float mTimeIdle;
         int mUpdates;
 
@@ -84,12 +86,23 @@ namespace MWRender
 
         void update(float duration);
 
-        void setCameraDistance(float dist, bool adjust = false);
+        /// Set camera distance for current mode. Don't work on 1st person view.
+        /// \param adjust Indicates should distance be adjusted or set.
+        /// \param override If true new distance will be used as default.
+        /// If false, default distance can be restored with setCameraDistance().
+        void setCameraDistance(float dist, bool adjust = false, bool override = true);
+
+        /// Restore default camera distance for current mode.
+        void setCameraDistance();
 
         void setAnimation(MWRender::NpcAnimation *anim);
 
         void setHeight(float height);
         float getHeight();
+
+        /// Stores player and camera world positions in passed arguments
+        /// \return true if camera at the eye-place
+        bool getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera);
     };
 }
 
diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp
index 87faba3e7..f1d2029bb 100644
--- a/apps/openmw/mwrender/renderingmanager.cpp
+++ b/apps/openmw/mwrender/renderingmanager.cpp
@@ -41,7 +41,7 @@ using namespace Ogre;
 namespace MWRender {
 
 RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine)
-    :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0)
+    :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine)
 {
     // select best shader mode
     bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos);
@@ -296,7 +296,22 @@ RenderingManager::moveObjectToCell(
     child->setPosition(pos);
 }
 
-void RenderingManager::update (float duration){
+void RenderingManager::update (float duration)
+{
+    Ogre::Vector3 orig, dest;
+    mPlayer->setCameraDistance();
+    if (!mPlayer->getPosition(orig, dest)) {
+        orig.z += mPlayer->getHeight() * mMwRoot->getScale().z;
+
+        btVector3 btOrig(orig.x, orig.y, orig.z);
+        btVector3 btDest(dest.x, dest.y, dest.z);
+        std::pair<std::string, float> test =
+            mPhysicsEngine->rayTest(btOrig, btDest);
+        if (!test.first.empty()) {
+            mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false);
+        }
+    }
+    mPlayer->update(duration);
 
     mActors.update (duration);
     mObjects.update (duration);
@@ -339,7 +354,6 @@ void RenderingManager::update (float duration){
         );
         mWater->update(duration);
     }
-    mPlayer->update(duration);
 }
 
 void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){