diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6c7b5757a..f347fb46eb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,7 +44,6 @@
     Bug #5367: Selecting a spell on an enchanted item per hotkey always plays the equip sound
     Bug #5369: Spawnpoint in the Grazelands doesn't produce oversized creatures
     Bug #5370: Opening an unlocked but trapped door uses the key
-    Bug #5379: Wandering NPCs falling through cantons
     Bug #5384: openmw-cs: deleting an instance requires reload of scene window to show in editor
     Bug #5387: Move/MoveWorld don't update the object's cell properly
     Bug #5391: Races Redone 1.2 bodies don't show on the inventory
diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp
index 716e548e1d..c54b1c3691 100644
--- a/apps/openmw/mwclass/activator.cpp
+++ b/apps/openmw/mwclass/activator.cpp
@@ -38,10 +38,10 @@ namespace MWClass
         }
     }
 
-    void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const
+    void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
     {
         if(!model.empty())
-            physics.addObject(ptr, model, rotation);
+            physics.addObject(ptr, model);
     }
 
     std::string Activator::getModel(const MWWorld::ConstPtr &ptr) const
diff --git a/apps/openmw/mwclass/activator.hpp b/apps/openmw/mwclass/activator.hpp
index c7b65ef679..10ace6f74d 100644
--- a/apps/openmw/mwclass/activator.hpp
+++ b/apps/openmw/mwclass/activator.hpp
@@ -17,7 +17,7 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
-            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const override;
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
 
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp
index 1789f1b19a..33aeb26bb0 100644
--- a/apps/openmw/mwclass/actor.cpp
+++ b/apps/openmw/mwclass/actor.cpp
@@ -17,12 +17,16 @@
 
 namespace MWClass
 {
+    Actor::Actor() {}
+
+    Actor::~Actor() {}
+
     void Actor::adjustPosition(const MWWorld::Ptr& ptr, bool force) const
     {
         MWBase::Environment::get().getWorld()->adjustPosition(ptr, force);
     }
 
-    void Actor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const
+    void Actor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
     {
         if (!model.empty())
         {
diff --git a/apps/openmw/mwclass/actor.hpp b/apps/openmw/mwclass/actor.hpp
index 98998b4eb2..3d509b2768 100644
--- a/apps/openmw/mwclass/actor.hpp
+++ b/apps/openmw/mwclass/actor.hpp
@@ -15,16 +15,16 @@ namespace MWClass
     {
     protected:
 
-        Actor() = default;
+        Actor();
 
     public:
-         ~Actor() override = default;
+        virtual ~Actor();
 
         void adjustPosition(const MWWorld::Ptr& ptr, bool force) const override;
         ///< Adjust position to stand on ground. Must be called post model load
         /// @param force do this even if the ptr is flying
 
-        void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const override;
+        void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
 
         bool useAnim() const override;
 
@@ -46,8 +46,8 @@ namespace MWClass
         float getCurrentSpeed(const MWWorld::Ptr& ptr) const override;
         
         // not implemented
-        Actor(const Actor&) = delete;
-        Actor& operator= (const Actor&) = delete;
+        Actor(const Actor&);
+        Actor& operator= (const Actor&);
     };
 }
 
diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp
index e09e4804ce..518695fabf 100644
--- a/apps/openmw/mwclass/apparatus.cpp
+++ b/apps/openmw/mwclass/apparatus.cpp
@@ -26,6 +26,11 @@ namespace MWClass
         }
     }
 
+    void Apparatus::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Apparatus::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Apparatus> *ref = ptr.get<ESM::Apparatus>();
diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp
index 828abef25e..8087c57ba3 100644
--- a/apps/openmw/mwclass/apparatus.hpp
+++ b/apps/openmw/mwclass/apparatus.hpp
@@ -17,6 +17,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp
index 817adbc1f5..3f9bfb859f 100644
--- a/apps/openmw/mwclass/armor.cpp
+++ b/apps/openmw/mwclass/armor.cpp
@@ -34,6 +34,11 @@ namespace MWClass
         }
     }
 
+    void Armor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Armor::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Armor> *ref = ptr.get<ESM::Armor>();
diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp
index f64f138a29..4f04e0824b 100644
--- a/apps/openmw/mwclass/armor.hpp
+++ b/apps/openmw/mwclass/armor.hpp
@@ -16,6 +16,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/bodypart.cpp b/apps/openmw/mwclass/bodypart.cpp
index 7fe798e27d..0315d3ddb0 100644
--- a/apps/openmw/mwclass/bodypart.cpp
+++ b/apps/openmw/mwclass/bodypart.cpp
@@ -22,6 +22,10 @@ namespace MWClass
         }
     }
 
+    void BodyPart::insertObject(const MWWorld::Ptr &ptr, const std::string &model, MWPhysics::PhysicsSystem &physics) const
+    {
+    }
+
     std::string BodyPart::getName(const MWWorld::ConstPtr &ptr) const
     {
         return std::string();
diff --git a/apps/openmw/mwclass/bodypart.hpp b/apps/openmw/mwclass/bodypart.hpp
index 0e372b884a..13d9141386 100644
--- a/apps/openmw/mwclass/bodypart.hpp
+++ b/apps/openmw/mwclass/bodypart.hpp
@@ -15,6 +15,8 @@ namespace MWClass
         void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
         ///< Add reference into a cell for rendering
 
+        void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
         std::string getName (const MWWorld::ConstPtr& ptr) const override;
         ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp
index 51b9e39d7a..4ea71e3ac2 100644
--- a/apps/openmw/mwclass/book.cpp
+++ b/apps/openmw/mwclass/book.cpp
@@ -31,6 +31,11 @@ namespace MWClass
         }
     }
 
+    void Book::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Book::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Book> *ref = ptr.get<ESM::Book>();
diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp
index f3d34c5168..c58e68ad87 100644
--- a/apps/openmw/mwclass/book.hpp
+++ b/apps/openmw/mwclass/book.hpp
@@ -14,6 +14,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp
index 400cd97e41..6d7960aac2 100644
--- a/apps/openmw/mwclass/clothing.cpp
+++ b/apps/openmw/mwclass/clothing.cpp
@@ -29,6 +29,11 @@ namespace MWClass
         }
     }
 
+    void Clothing::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Clothing::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Clothing> *ref = ptr.get<ESM::Clothing>();
diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp
index 3d5c162aa4..a87e0cbe00 100644
--- a/apps/openmw/mwclass/clothing.hpp
+++ b/apps/openmw/mwclass/clothing.hpp
@@ -14,6 +14,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp
index 3023466f08..28305c394e 100644
--- a/apps/openmw/mwclass/container.cpp
+++ b/apps/openmw/mwclass/container.cpp
@@ -111,10 +111,10 @@ namespace MWClass
         }
     }
 
-    void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const
+    void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
     {
         if(!model.empty())
-            physics.addObject(ptr, model, rotation);
+            physics.addObject(ptr, model);
     }
 
     std::string Container::getModel(const MWWorld::ConstPtr &ptr) const
diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp
index 74d9ac0da2..2dc0c06cae 100644
--- a/apps/openmw/mwclass/container.hpp
+++ b/apps/openmw/mwclass/container.hpp
@@ -44,7 +44,7 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
-            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const override;
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
 
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp
index 983953c20d..ba51d9c2bc 100644
--- a/apps/openmw/mwclass/door.cpp
+++ b/apps/openmw/mwclass/door.cpp
@@ -62,10 +62,10 @@ namespace MWClass
         }
     }
 
-    void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const
+    void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
     {
         if(!model.empty())
-            physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_Door);
+            physics.addObject(ptr, model, MWPhysics::CollisionType_Door);
 
         // Resume the door's opening/closing animation if it wasn't finished
         if (ptr.getRefData().getCustomData())
diff --git a/apps/openmw/mwclass/door.hpp b/apps/openmw/mwclass/door.hpp
index 6d40a840b1..6c2fa26b80 100644
--- a/apps/openmw/mwclass/door.hpp
+++ b/apps/openmw/mwclass/door.hpp
@@ -18,7 +18,7 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
-            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const override;
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
 
             bool isDoor() const override;
 
diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp
index 20f9576dff..a007ad115f 100644
--- a/apps/openmw/mwclass/ingredient.cpp
+++ b/apps/openmw/mwclass/ingredient.cpp
@@ -28,6 +28,11 @@ namespace MWClass
         }
     }
 
+    void Ingredient::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Ingredient::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Ingredient> *ref = ptr.get<ESM::Ingredient>();
diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp
index 2aa831f868..5219cf39ce 100644
--- a/apps/openmw/mwclass/ingredient.hpp
+++ b/apps/openmw/mwclass/ingredient.hpp
@@ -14,6 +14,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp
index d4d196bc4b..3bdf10f475 100644
--- a/apps/openmw/mwclass/light.cpp
+++ b/apps/openmw/mwclass/light.cpp
@@ -33,7 +33,7 @@ namespace MWClass
         renderingInterface.getObjects().insertModel(ptr, model, true, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault));
     }
 
-    void Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const
+    void Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
     {
         MWWorld::LiveCellRef<ESM::Light> *ref =
             ptr.get<ESM::Light>();
@@ -41,7 +41,7 @@ namespace MWClass
 
         // TODO: add option somewhere to enable collision for placeable objects
         if (!model.empty() && (ref->mBase->mData.mFlags & ESM::Light::Carry) == 0)
-            physics.addObject(ptr, model, rotation);
+            physics.addObject(ptr, model);
 
         if (!ref->mBase->mSound.empty() && !(ref->mBase->mData.mFlags & ESM::Light::OffDefault))
             MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0,
diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp
index 1b1794d4a7..e37dddc250 100644
--- a/apps/openmw/mwclass/light.hpp
+++ b/apps/openmw/mwclass/light.hpp
@@ -14,7 +14,7 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
-            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const override;
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
 
             bool useAnim() const override;
 
diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp
index 985b087711..9b8abc8f23 100644
--- a/apps/openmw/mwclass/lockpick.cpp
+++ b/apps/openmw/mwclass/lockpick.cpp
@@ -28,6 +28,11 @@ namespace MWClass
         }
     }
 
+    void Lockpick::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Lockpick::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Lockpick> *ref = ptr.get<ESM::Lockpick>();
diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp
index d4b265e397..fabae33435 100644
--- a/apps/openmw/mwclass/lockpick.hpp
+++ b/apps/openmw/mwclass/lockpick.hpp
@@ -14,6 +14,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp
index facab9d51c..8d3cda6fe5 100644
--- a/apps/openmw/mwclass/misc.cpp
+++ b/apps/openmw/mwclass/misc.cpp
@@ -37,6 +37,11 @@ namespace MWClass
         }
     }
 
+    void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Miscellaneous::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = ptr.get<ESM::Miscellaneous>();
diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp
index 18788c7ed8..9bff85ca56 100644
--- a/apps/openmw/mwclass/misc.hpp
+++ b/apps/openmw/mwclass/misc.hpp
@@ -14,6 +14,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp
index 56d9dff279..4af97e6345 100644
--- a/apps/openmw/mwclass/potion.cpp
+++ b/apps/openmw/mwclass/potion.cpp
@@ -30,6 +30,11 @@ namespace MWClass
         }
     }
 
+    void Potion::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Potion::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Potion> *ref = ptr.get<ESM::Potion>();
diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp
index 75b962164b..75d923f0ba 100644
--- a/apps/openmw/mwclass/potion.hpp
+++ b/apps/openmw/mwclass/potion.hpp
@@ -14,6 +14,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp
index 51273337a6..dba4e8c063 100644
--- a/apps/openmw/mwclass/probe.cpp
+++ b/apps/openmw/mwclass/probe.cpp
@@ -28,6 +28,11 @@ namespace MWClass
         }
     }
 
+    void Probe::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Probe::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Probe> *ref = ptr.get<ESM::Probe>();
diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp
index ef9273a379..a0a41dcfb6 100644
--- a/apps/openmw/mwclass/probe.hpp
+++ b/apps/openmw/mwclass/probe.hpp
@@ -14,6 +14,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp
index f1b88e422b..8907c8212e 100644
--- a/apps/openmw/mwclass/repair.cpp
+++ b/apps/openmw/mwclass/repair.cpp
@@ -25,6 +25,11 @@ namespace MWClass
         }
     }
 
+    void Repair::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Repair::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Repair> *ref = ptr.get<ESM::Repair>();
diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp
index c403449e18..b9791e9cf4 100644
--- a/apps/openmw/mwclass/repair.hpp
+++ b/apps/openmw/mwclass/repair.hpp
@@ -14,6 +14,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp
index 28156c97f6..5551b3d731 100644
--- a/apps/openmw/mwclass/static.cpp
+++ b/apps/openmw/mwclass/static.cpp
@@ -23,10 +23,10 @@ namespace MWClass
         }
     }
 
-    void Static::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const
+    void Static::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
     {
         if(!model.empty())
-            physics.addObject(ptr, model, rotation);
+            physics.addObject(ptr, model);
     }
 
     std::string Static::getModel(const MWWorld::ConstPtr &ptr) const
@@ -63,9 +63,4 @@ namespace MWClass
 
         return MWWorld::Ptr(cell.insert(ref), &cell);
     }
-
-    bool Static::isStatic() const
-    {
-        return true;
-    }
 }
diff --git a/apps/openmw/mwclass/static.hpp b/apps/openmw/mwclass/static.hpp
index d0f4913f0f..6bc783dad0 100644
--- a/apps/openmw/mwclass/static.hpp
+++ b/apps/openmw/mwclass/static.hpp
@@ -14,7 +14,7 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
-            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const override;
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
 
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
@@ -25,8 +25,6 @@ namespace MWClass
             static void registerSelf();
 
             std::string getModel(const MWWorld::ConstPtr &ptr) const override;
-
-            bool isStatic() const override;
     };
 }
 
diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp
index 6246c8fb09..0d6a27cf60 100644
--- a/apps/openmw/mwclass/weapon.cpp
+++ b/apps/openmw/mwclass/weapon.cpp
@@ -34,6 +34,11 @@ namespace MWClass
         }
     }
 
+    void Weapon::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
+    {
+        // TODO: add option somewhere to enable collision for placeable objects
+    }
+
     std::string Weapon::getModel(const MWWorld::ConstPtr &ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Weapon> *ref = ptr.get<ESM::Weapon>();
diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp
index db17e6b70f..f1824b7d14 100644
--- a/apps/openmw/mwclass/weapon.hpp
+++ b/apps/openmw/mwclass/weapon.hpp
@@ -15,6 +15,8 @@ namespace MWClass
             void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override;
             ///< Add reference into a cell for rendering
 
+            void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override;
+
             std::string getName (const MWWorld::ConstPtr& ptr) const override;
             ///< \return name or ID; can return an empty string.
 
diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp
index 06600fd6ac..3b52ee934f 100644
--- a/apps/openmw/mwphysics/actor.cpp
+++ b/apps/openmw/mwphysics/actor.cpp
@@ -67,7 +67,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic
     updateScale();
 
     if(!mRotationallyInvariant)
-        setRotation(mPtr.getRefData().getBaseNode()->getAttitude());
+        updateRotation();
 
     updatePosition();
     addCollisionMask(getCollisionMask());
@@ -197,10 +197,10 @@ osg::Vec3f Actor::getPreviousPosition() const
     return mPreviousPosition;
 }
 
-void Actor::setRotation(osg::Quat quat)
+void Actor::updateRotation ()
 {
     std::scoped_lock lock(mPositionMutex);
-    mRotation = quat;
+    mRotation = mPtr.getRefData().getBaseNode()->getAttitude();
 }
 
 bool Actor::isRotationallyInvariant() const
diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp
index 4039f44811..9d129f2ba6 100644
--- a/apps/openmw/mwphysics/actor.hpp
+++ b/apps/openmw/mwphysics/actor.hpp
@@ -49,7 +49,7 @@ namespace MWPhysics
         void enableCollisionBody(bool collision);
 
         void updateScale();
-        void setRotation(osg::Quat quat);
+        void updateRotation();
 
         /**
          * Return true if the collision shape looks the same no matter how its Z rotated.
diff --git a/apps/openmw/mwphysics/object.cpp b/apps/openmw/mwphysics/object.cpp
index 6d3954088a..e3615989dd 100644
--- a/apps/openmw/mwphysics/object.cpp
+++ b/apps/openmw/mwphysics/object.cpp
@@ -14,7 +14,7 @@
 
 namespace MWPhysics
 {
-    Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance, osg::Quat rotation, int collisionType, PhysicsTaskScheduler* scheduler)
+    Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance, int collisionType, PhysicsTaskScheduler* scheduler)
         : mShapeInstance(shapeInstance)
         , mSolid(true)
         , mTaskScheduler(scheduler)
@@ -27,7 +27,7 @@ namespace MWPhysics
         mCollisionObject->setUserPointer(this);
 
         setScale(ptr.getCellRef().getScale());
-        setRotation(rotation);
+        setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude()));
         setOrigin(Misc::Convert::toBullet(ptr.getRefData().getPosition().asVec3()));
         commitPositionChange();
 
@@ -51,10 +51,10 @@ namespace MWPhysics
         mScaleUpdatePending = true;
     }
 
-    void Object::setRotation(osg::Quat quat)
+    void Object::setRotation(const btQuaternion& quat)
     {
         std::unique_lock<std::mutex> lock(mPositionMutex);
-        mLocalTransform.setRotation(Misc::Convert::toBullet(quat));
+        mLocalTransform.setRotation(quat);
         mTransformUpdatePending = true;
     }
 
diff --git a/apps/openmw/mwphysics/object.hpp b/apps/openmw/mwphysics/object.hpp
index c2273831e5..cae8771809 100644
--- a/apps/openmw/mwphysics/object.hpp
+++ b/apps/openmw/mwphysics/object.hpp
@@ -26,12 +26,12 @@ namespace MWPhysics
     class Object final : public PtrHolder
     {
     public:
-        Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance, osg::Quat rotation, int collisionType, PhysicsTaskScheduler* scheduler);
+        Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance, int collisionType, PhysicsTaskScheduler* scheduler);
         ~Object() override;
 
         const Resource::BulletShapeInstance* getShapeInstance() const;
         void setScale(float scale);
-        void setRotation(osg::Quat quat);
+        void setRotation(const btQuaternion& quat);
         void setOrigin(const btVector3& vec);
         void commitPositionChange();
         btCollisionObject* getCollisionObject();
diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp
index 5a9a0be832..ed0e0c915d 100644
--- a/apps/openmw/mwphysics/physicssystem.cpp
+++ b/apps/openmw/mwphysics/physicssystem.cpp
@@ -456,20 +456,20 @@ namespace MWPhysics
         return heightField->second.get();
     }
 
-    void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType)
+    void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, int collisionType)
     {
         osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance = mShapeManager->getInstance(mesh);
         if (!shapeInstance || !shapeInstance->getCollisionShape())
             return;
 
-        auto obj = std::make_shared<Object>(ptr, shapeInstance, rotation, collisionType, mTaskScheduler.get());
+        auto obj = std::make_shared<Object>(ptr, shapeInstance, collisionType, mTaskScheduler.get());
         mObjects.emplace(ptr, obj);
 
         if (obj->isAnimated())
             mAnimatedObjects.insert(obj.get());
     }
 
-    void PhysicsSystem::remove(const MWWorld::Ptr &ptr, bool keepObject)
+    void PhysicsSystem::remove(const MWWorld::Ptr &ptr)
     {
         ObjectMap::iterator found = mObjects.find(ptr);
         if (found != mObjects.end())
@@ -479,8 +479,7 @@ namespace MWPhysics
 
             mAnimatedObjects.erase(found->second.get());
 
-            if (!keepObject)
-                mObjects.erase(found);
+            mObjects.erase(found);
         }
 
         ActorMap::iterator foundActor = mActors.find(ptr);
@@ -622,12 +621,12 @@ namespace MWPhysics
         mTaskScheduler->updateSingleAabb(foundProjectile->second);
     }
 
-    void PhysicsSystem::updateRotation(const MWWorld::Ptr &ptr, osg::Quat rotate)
+    void PhysicsSystem::updateRotation(const MWWorld::Ptr &ptr)
     {
         ObjectMap::iterator found = mObjects.find(ptr);
         if (found != mObjects.end())
         {
-            found->second->setRotation(rotate);
+            found->second->setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude()));
             mTaskScheduler->updateSingleAabb(found->second);
             return;
         }
@@ -636,7 +635,7 @@ namespace MWPhysics
         {
             if (!foundActor->second->isRotationallyInvariant())
             {
-                foundActor->second->setRotation(rotate);
+                foundActor->second->updateRotation();
                 mTaskScheduler->updateSingleAabb(foundActor->second);
             }
             return;
diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp
index 715a6cd1a2..6f901067a2 100644
--- a/apps/openmw/mwphysics/physicssystem.hpp
+++ b/apps/openmw/mwphysics/physicssystem.hpp
@@ -121,7 +121,7 @@ namespace MWPhysics
             void setWaterHeight(float height);
             void disableWater();
 
-            void addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType = CollisionType_World);
+            void addObject (const MWWorld::Ptr& ptr, const std::string& mesh, int collisionType = CollisionType_World);
             void addActor (const MWWorld::Ptr& ptr, const std::string& mesh);
 
             int addProjectile(const MWWorld::Ptr& caster, const osg::Vec3f& position, float radius, bool canTraverseWater);
@@ -138,10 +138,10 @@ namespace MWPhysics
             Projectile* getProjectile(int projectileId) const;
 
             // Object or Actor
-            void remove (const MWWorld::Ptr& ptr, bool keepObject = false);
+            void remove (const MWWorld::Ptr& ptr);
 
             void updateScale (const MWWorld::Ptr& ptr);
-            void updateRotation (const MWWorld::Ptr& ptr, osg::Quat rotate);
+            void updateRotation (const MWWorld::Ptr& ptr);
             void updatePosition (const MWWorld::Ptr& ptr);
 
             void addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject);
diff --git a/apps/openmw/mwworld/cellvisitors.hpp b/apps/openmw/mwworld/cellvisitors.hpp
index 5985d06fb6..e68b383b77 100644
--- a/apps/openmw/mwworld/cellvisitors.hpp
+++ b/apps/openmw/mwworld/cellvisitors.hpp
@@ -18,23 +18,12 @@ namespace MWWorld
             if (ptr.getRefData().getBaseNode())
             {
                 ptr.getRefData().setBaseNode(nullptr);
+                mObjects.push_back (ptr);
             }
-            mObjects.push_back (ptr);
 
             return true;
         }
     };
-
-    struct ListObjectsVisitor
-    {
-        std::vector<MWWorld::Ptr> mObjects;
-
-        bool operator() (MWWorld::Ptr ptr)
-        {
-            mObjects.push_back (ptr);
-            return true;
-        }
-    };
 }
 
 #endif
diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp
index becf912eaa..950c8a6d49 100644
--- a/apps/openmw/mwworld/class.cpp
+++ b/apps/openmw/mwworld/class.cpp
@@ -25,12 +25,16 @@ namespace MWWorld
 {
     std::map<std::string, std::shared_ptr<Class> > Class::sClasses;
 
+    Class::Class() {}
+
+    Class::~Class() {}
+
     void Class::insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const
     {
 
     }
 
-    void Class::insertObject(const Ptr& ptr, const std::string& mesh, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const
+    void Class::insertObject(const Ptr& ptr, const std::string& mesh, MWPhysics::PhysicsSystem& physics) const
     {
 
     }
diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp
index 592552d47f..1b3d4029e4 100644
--- a/apps/openmw/mwworld/class.hpp
+++ b/apps/openmw/mwworld/class.hpp
@@ -6,7 +6,6 @@
 #include <string>
 #include <vector>
 
-#include <osg/Quat>
 #include <osg/Vec4f>
 
 #include "ptr.hpp"
@@ -58,9 +57,13 @@ namespace MWWorld
 
             std::string mTypeName;
 
+            // not implemented
+            Class (const Class&);
+            Class& operator= (const Class&);
+
         protected:
 
-            Class() = default;
+            Class();
 
             std::shared_ptr<Action> defaultItemActivate(const Ptr &ptr, const Ptr &actor) const;
             ///< Generate default action for activating inventory items
@@ -69,16 +72,14 @@ namespace MWWorld
 
         public:
 
-            virtual ~Class() = default;
-            Class (const Class&) = delete;
-            Class& operator= (const Class&) = delete;
+            virtual ~Class();
 
             const std::string& getTypeName() const {
                 return mTypeName;
             }
 
             virtual void insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const;
-            virtual void insertObject(const Ptr& ptr, const std::string& mesh, osg::Quat rotation, MWPhysics::PhysicsSystem& physics) const;
+            virtual void insertObject(const Ptr& ptr, const std::string& mesh, MWPhysics::PhysicsSystem& physics) const;
             ///< Add reference into a cell for rendering (default implementation: don't render anything).
 
             virtual std::string getName (const ConstPtr& ptr) const = 0;
@@ -318,10 +319,6 @@ namespace MWWorld
                 return false;
             }
 
-            virtual bool isStatic() const {
-                return false;
-            }
-
             virtual bool isBipedal(const MWWorld::ConstPtr& ptr) const;
             virtual bool canFly(const MWWorld::ConstPtr& ptr) const;
             virtual bool canSwim(const MWWorld::ConstPtr& ptr) const;
diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp
index 2abedcd788..427ee3aa8b 100644
--- a/apps/openmw/mwworld/scene.cpp
+++ b/apps/openmw/mwworld/scene.cpp
@@ -75,20 +75,18 @@ namespace
             * osg::Quat(xr, osg::Vec3(-1, 0, 0));
     }
 
-    osg::Quat makeNodeRotation(const MWWorld::Ptr& ptr, RotationOrder order)
+    void setNodeRotation(const MWWorld::Ptr& ptr, MWRender::RenderingManager& rendering, RotationOrder order)
     {
-        const auto pos = ptr.getRefData().getPosition();
+        if (!ptr.getRefData().getBaseNode())
+            return;
 
-        const auto rot = ptr.getClass().isActor() ? makeActorOsgQuat(pos)
-            : (order == RotationOrder::inverse ? makeInversedOrderObjectOsgQuat(pos) : makeObjectOsgQuat(pos));
-
-        return rot;
-    }
-
-    void setNodeRotation(const MWWorld::Ptr& ptr, MWRender::RenderingManager& rendering, osg::Quat rotation)
-    {
-        if (ptr.getRefData().getBaseNode())
-            rendering.rotateObject(ptr, rotation);
+        rendering.rotateObject(ptr,
+            ptr.getClass().isActor()
+            ? makeActorOsgQuat(ptr.getRefData().getPosition())
+            : (order == RotationOrder::inverse
+                ? makeInversedOrderObjectOsgQuat(ptr.getRefData().getPosition())
+                : makeObjectOsgQuat(ptr.getRefData().getPosition()))
+        );
     }
 
     std::string getModel(const MWWorld::Ptr &ptr, const VFS::Manager *vfs)
@@ -105,7 +103,7 @@ namespace
     }
 
     void addObject(const MWWorld::Ptr& ptr, MWPhysics::PhysicsSystem& physics,
-                   MWRender::RenderingManager& rendering, std::set<ESM::RefNum>& pagedRefs, bool onlyPhysics)
+                   MWRender::RenderingManager& rendering, std::set<ESM::RefNum>& pagedRefs)
     {
         if (ptr.getRefData().getBaseNode() || physics.getActor(ptr))
         {
@@ -113,31 +111,26 @@ namespace
             return;
         }
 
+        bool useAnim = ptr.getClass().useAnim();
         std::string model = getModel(ptr, rendering.getResourceSystem()->getVFS());
-        const auto rotation = makeNodeRotation(ptr, RotationOrder::direct);
-        if (!onlyPhysics)
-        {
-            bool useAnim = ptr.getClass().useAnim();
 
-            const ESM::RefNum& refnum = ptr.getCellRef().getRefNum();
-            if (!refnum.hasContentFile() || pagedRefs.find(refnum) == pagedRefs.end())
-                ptr.getClass().insertObjectRendering(ptr, model, rendering);
-            else
-                ptr.getRefData().setBaseNode(new SceneUtil::PositionAttitudeTransform); // FIXME remove this when physics code is fixed not to depend on basenode
+        const ESM::RefNum& refnum = ptr.getCellRef().getRefNum();
+        if (!refnum.hasContentFile() || pagedRefs.find(refnum) == pagedRefs.end())
+            ptr.getClass().insertObjectRendering(ptr, model, rendering);
+        else
+            ptr.getRefData().setBaseNode(new SceneUtil::PositionAttitudeTransform); // FIXME remove this when physics code is fixed not to depend on basenode
+        setNodeRotation(ptr, rendering, RotationOrder::direct);
 
-            setNodeRotation(ptr, rendering, rotation);
+        ptr.getClass().insertObject (ptr, model, physics);
 
-            if (useAnim)
-                MWBase::Environment::get().getMechanicsManager()->add(ptr);
+        if (useAnim)
+            MWBase::Environment::get().getMechanicsManager()->add(ptr);
 
-            if (ptr.getClass().isActor())
-                rendering.addWaterRippleEmitter(ptr);
+        if (ptr.getClass().isActor())
+            rendering.addWaterRippleEmitter(ptr);
 
-            // Restore effect particles
-            MWBase::Environment::get().getWorld()->applyLoopingParticles(ptr);
-        }
-        if (!physics.getObject(ptr))
-            ptr.getClass().insertObject (ptr, model, rotation, physics);
+        // Restore effect particles
+        MWBase::Environment::get().getWorld()->applyLoopingParticles(ptr);
     }
 
     void addObject(const MWWorld::Ptr& ptr, const MWPhysics::PhysicsSystem& physics, DetourNavigator::Navigator& navigator)
@@ -208,12 +201,11 @@ namespace
     {
         MWWorld::CellStore& mCell;
         Loading::Listener& mLoadingListener;
-        bool mOnlyStatics;
         bool mTest;
 
         std::vector<MWWorld::Ptr> mToInsert;
 
-        InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener, bool onlyStatics, bool test);
+        InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener, bool test);
 
         bool operator() (const MWWorld::Ptr& ptr);
 
@@ -221,8 +213,8 @@ namespace
         void insert(AddObject&& addObject);
     };
 
-    InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener, bool onlyStatics, bool test)
-    : mCell (cell), mLoadingListener (loadingListener), mOnlyStatics(onlyStatics), mTest(test)
+    InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener, bool test)
+    : mCell (cell), mLoadingListener (loadingListener), mTest(test)
     {}
 
     bool InsertVisitor::operator() (const MWWorld::Ptr& ptr)
@@ -238,7 +230,7 @@ namespace
     {
         for (MWWorld::Ptr& ptr : mToInsert)
         {
-            if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled() && ((mOnlyStatics && ptr.getClass().isStatic()) || !mOnlyStatics))
+            if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled())
             {
                 try
                 {
@@ -271,16 +263,6 @@ namespace
         return std::abs(cellPosition.first) + std::abs(cellPosition.second);
     }
 
-    bool isCellInCollection(int x, int y, MWWorld::Scene::CellStoreCollection& collection)
-    {
-        for (auto *cell : collection)
-        {
-            assert(cell->getCell()->isExterior());
-            if (x == cell->getCell()->getGridX() && y == cell->getCell()->getGridY())
-                return true;
-        }
-        return false;
-    }
 }
 
 
@@ -294,7 +276,7 @@ namespace MWWorld
         {
             if (!ptr.getRefData().getBaseNode()) return;
             ptr.getClass().insertObjectRendering(ptr, getModel(ptr, mRendering.getResourceSystem()->getVFS()), mRendering);
-            setNodeRotation(ptr, mRendering, makeNodeRotation(ptr, RotationOrder::direct));
+            setNodeRotation(ptr, mRendering, RotationOrder::direct);
             reloadTerrain();
         }
     }
@@ -310,9 +292,8 @@ namespace MWWorld
 
     void Scene::updateObjectRotation(const Ptr &ptr, RotationOrder order)
     {
-        const auto rot = makeNodeRotation(ptr, order);
-        setNodeRotation(ptr, mRendering, rot);
-        mPhysics->updateRotation(ptr, rot);
+        setNodeRotation(ptr, mRendering, order);
+        mPhysics->updateRotation(ptr);
     }
 
     void Scene::updateObjectScale(const Ptr &ptr)
@@ -332,41 +313,15 @@ namespace MWWorld
         mRendering.update (duration, paused);
     }
 
-    void Scene::unloadInactiveCell (CellStore* cell, bool test)
+    void Scene::unloadCell (CellStoreCollection::iterator iter, bool test)
     {
-        assert(mActiveCells.find(cell) == mActiveCells.end());
-        assert(mInactiveCells.find(cell) != mInactiveCells.end());
         if (!test)
-            Log(Debug::Info) << "Unloading cell " << cell->getCell()->getDescription();
-
-        ListObjectsVisitor visitor;
-
-        cell->forEach(visitor);
-        for (const auto& ptr : visitor.mObjects)
-            mPhysics->remove(ptr);
-
-        if (cell->getCell()->isExterior())
-        {
-            const auto cellX = cell->getCell()->getGridX();
-            const auto cellY = cell->getCell()->getGridY();
-            mPhysics->removeHeightField(cellX, cellY);
-        }
-
-        mInactiveCells.erase(cell);
-    }
-
-    void Scene::deactivateCell(CellStore* cell, bool test)
-    {
-        assert(mInactiveCells.find(cell) != mInactiveCells.end());
-        if (mActiveCells.find(cell) == mActiveCells.end())
-            return;
-        if (!test)
-            Log(Debug::Info) << "Deactivate cell " << cell->getCell()->getDescription();
+            Log(Debug::Info) << "Unloading cell " << (*iter)->getCell()->getDescription();
 
         const auto navigator = MWBase::Environment::get().getWorld()->getNavigator();
         ListAndResetObjectsVisitor visitor;
 
-        cell->forEach(visitor);
+        (*iter)->forEach(visitor);
         const auto world = MWBase::Environment::get().getWorld();
         for (const auto& ptr : visitor.mObjects)
         {
@@ -377,157 +332,140 @@ namespace MWWorld
                 navigator->removeAgent(world->getPathfindingHalfExtents(ptr));
                 mRendering.removeActorPath(ptr);
             }
-            mPhysics->remove(ptr, ptr.getClass().isStatic());
+            mPhysics->remove(ptr);
         }
 
-        const auto cellX = cell->getCell()->getGridX();
-        const auto cellY = cell->getCell()->getGridY();
+        const auto cellX = (*iter)->getCell()->getGridX();
+        const auto cellY = (*iter)->getCell()->getGridY();
 
-        if (cell->getCell()->isExterior())
+        if ((*iter)->getCell()->isExterior())
         {
             if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
                 navigator->removeObject(DetourNavigator::ObjectId(heightField));
+            mPhysics->removeHeightField(cellX, cellY);
         }
 
-        if (cell->getCell()->hasWater())
+        if ((*iter)->getCell()->hasWater())
             navigator->removeWater(osg::Vec2i(cellX, cellY));
 
-        if (const auto pathgrid = world->getStore().get<ESM::Pathgrid>().search(*cell->getCell()))
+        if (const auto pathgrid = world->getStore().get<ESM::Pathgrid>().search(*(*iter)->getCell()))
             navigator->removePathgrid(*pathgrid);
 
         const auto player = world->getPlayerPtr();
         navigator->update(player.getRefData().getPosition().asVec3());
 
-        MWBase::Environment::get().getMechanicsManager()->drop (cell);
+        MWBase::Environment::get().getMechanicsManager()->drop (*iter);
 
-        mRendering.removeCell(cell);
-        MWBase::Environment::get().getWindowManager()->removeCell(cell);
+        mRendering.removeCell(*iter);
+        MWBase::Environment::get().getWindowManager()->removeCell(*iter);
 
-        MWBase::Environment::get().getWorld()->getLocalScripts().clearCell (cell);
+        MWBase::Environment::get().getWorld()->getLocalScripts().clearCell (*iter);
 
-        MWBase::Environment::get().getSoundManager()->stopSound (cell);
-        mActiveCells.erase(cell);
+        MWBase::Environment::get().getSoundManager()->stopSound (*iter);
+        mActiveCells.erase(*iter);
     }
 
-    void Scene::activateCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn, bool test)
+    void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn, bool test)
     {
-        assert(mActiveCells.find(cell) == mActiveCells.end());
-        assert(mInactiveCells.find(cell) != mInactiveCells.end());
-        mActiveCells.insert(cell);
+        std::pair<CellStoreCollection::iterator, bool> result = mActiveCells.insert(cell);
 
-        if (test)
-            Log(Debug::Info) << "Testing cell " << cell->getCell()->getDescription();
-        else
-            Log(Debug::Info) << "Loading cell " << cell->getCell()->getDescription();
-
-        const auto world = MWBase::Environment::get().getWorld();
-        const auto navigator = world->getNavigator();
-
-        const int cellX = cell->getCell()->getGridX();
-        const int cellY = cell->getCell()->getGridY();
-
-        if (!test && cell->getCell()->isExterior())
+        if(result.second)
         {
-            if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
-                navigator->addObject(DetourNavigator::ObjectId(heightField), *heightField->getShape(),
-                        heightField->getCollisionObject()->getWorldTransform());
-        }
+            if (test)
+                Log(Debug::Info) << "Testing cell " << cell->getCell()->getDescription();
+            else
+                Log(Debug::Info) << "Loading cell " << cell->getCell()->getDescription();
 
-        if (const auto pathgrid = world->getStore().get<ESM::Pathgrid>().search(*cell->getCell()))
-            navigator->addPathgrid(*cell->getCell(), *pathgrid);
+            float verts = ESM::Land::LAND_SIZE;
+            float worldsize = ESM::Land::REAL_SIZE;
 
-        // register local scripts
-        // do this before insertCell, to make sure we don't add scripts from levelled creature spawning twice
-        MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell);
+            const auto world = MWBase::Environment::get().getWorld();
+            const auto navigator = world->getNavigator();
 
-        if (respawn)
-            cell->respawn();
+            const int cellX = cell->getCell()->getGridX();
+            const int cellY = cell->getCell()->getGridY();
 
-        insertCell (*cell, loadingListener, false, test);
-
-        mRendering.addCell(cell);
-        if (!test)
-        {
-            MWBase::Environment::get().getWindowManager()->addCell(cell);
-            bool waterEnabled = cell->getCell()->hasWater() || cell->isExterior();
-            float waterLevel = cell->getWaterLevel();
-            mRendering.setWaterEnabled(waterEnabled);
-            if (waterEnabled)
+            // Load terrain physics first...
+            if (!test && cell->getCell()->isExterior())
             {
-                mPhysics->enableWater(waterLevel);
-                mRendering.setWaterHeight(waterLevel);
-
-                if (cell->getCell()->isExterior())
+                osg::ref_ptr<const ESMTerrain::LandObject> land = mRendering.getLandManager()->getLand(cellX, cellY);
+                const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr;
+                if (data)
                 {
-                    if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
-                        navigator->addWater(osg::Vec2i(cellX, cellY), ESM::Land::REAL_SIZE,
-                                cell->getWaterLevel(), heightField->getCollisionObject()->getWorldTransform());
+                    mPhysics->addHeightField (data->mHeights, cellX, cellY, worldsize / (verts-1), verts, data->mMinHeight, data->mMaxHeight, land.get());
                 }
                 else
                 {
-                    navigator->addWater(osg::Vec2i(cellX, cellY), std::numeric_limits<int>::max(),
+                    static std::vector<float> defaultHeight;
+                    defaultHeight.resize(verts*verts, ESM::Land::DEFAULT_HEIGHT);
+                    mPhysics->addHeightField (&defaultHeight[0], cell->getCell()->getGridX(), cell->getCell()->getGridY(), worldsize / (verts-1), verts, ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT, land.get());
+                }
+
+                if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
+                    navigator->addObject(DetourNavigator::ObjectId(heightField), *heightField->getShape(),
+                            heightField->getCollisionObject()->getWorldTransform());
+            }
+
+            if (const auto pathgrid = world->getStore().get<ESM::Pathgrid>().search(*cell->getCell()))
+                navigator->addPathgrid(*cell->getCell(), *pathgrid);
+
+            // register local scripts
+            // do this before insertCell, to make sure we don't add scripts from levelled creature spawning twice
+            MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell);
+
+            if (respawn)
+                cell->respawn();
+
+            // ... then references. This is important for adjustPosition to work correctly.
+            insertCell (*cell, loadingListener, test);
+
+            mRendering.addCell(cell);
+            if (!test)
+            {
+                MWBase::Environment::get().getWindowManager()->addCell(cell);
+                bool waterEnabled = cell->getCell()->hasWater() || cell->isExterior();
+                float waterLevel = cell->getWaterLevel();
+                mRendering.setWaterEnabled(waterEnabled);
+                if (waterEnabled)
+                {
+                    mPhysics->enableWater(waterLevel);
+                    mRendering.setWaterHeight(waterLevel);
+
+                    if (cell->getCell()->isExterior())
+                    {
+                        if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
+                            navigator->addWater(osg::Vec2i(cellX, cellY), ESM::Land::REAL_SIZE,
+                                cell->getWaterLevel(), heightField->getCollisionObject()->getWorldTransform());
+                    }
+                    else
+                    {
+                        navigator->addWater(osg::Vec2i(cellX, cellY), std::numeric_limits<int>::max(),
                             cell->getWaterLevel(), btTransform::getIdentity());
+                    }
+                }
+                else
+                    mPhysics->disableWater();
+
+                const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr();
+                navigator->update(player.getRefData().getPosition().asVec3());
+
+                if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx))
+                {
+
+                    mRendering.configureAmbient(cell->getCell());
                 }
             }
-            else
-                mPhysics->disableWater();
-
-            const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr();
-            navigator->update(player.getRefData().getPosition().asVec3());
-
-            if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx))
-                mRendering.configureAmbient(cell->getCell());
         }
 
         mPreloader->notifyLoaded(cell);
     }
 
-    void Scene::loadInactiveCell (CellStore *cell, Loading::Listener* loadingListener, bool test)
-    {
-        assert(mActiveCells.find(cell) == mActiveCells.end());
-        assert(mInactiveCells.find(cell) == mInactiveCells.end());
-        mInactiveCells.insert(cell);
-
-        if (test)
-            Log(Debug::Info) << "Testing inactive cell " << cell->getCell()->getDescription();
-        else
-            Log(Debug::Info) << "Loading inactive cell " << cell->getCell()->getDescription();
-
-        if (!test && cell->getCell()->isExterior())
-        {
-            float verts = ESM::Land::LAND_SIZE;
-            float worldsize = ESM::Land::REAL_SIZE;
-
-            const int cellX = cell->getCell()->getGridX();
-            const int cellY = cell->getCell()->getGridY();
-
-            osg::ref_ptr<const ESMTerrain::LandObject> land = mRendering.getLandManager()->getLand(cellX, cellY);
-            const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr;
-            if (data)
-            {
-                mPhysics->addHeightField (data->mHeights, cellX, cellY, worldsize / (verts-1), verts, data->mMinHeight, data->mMaxHeight, land.get());
-            }
-            else
-            {
-                static std::vector<float> defaultHeight;
-                defaultHeight.resize(verts*verts, ESM::Land::DEFAULT_HEIGHT);
-                mPhysics->addHeightField (&defaultHeight[0], cell->getCell()->getGridX(), cell->getCell()->getGridY(), worldsize / (verts-1), verts, ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT, land.get());
-            }
-        }
-
-        insertCell (*cell, loadingListener, true, test);
-    }
-
     void Scene::clear()
     {
-        for (auto iter = mInactiveCells.begin(); iter!=mInactiveCells.end(); )
-        {
-            auto* cell = *iter++;
-            deactivateCell(cell);
-            unloadInactiveCell (cell);
-        }
+        CellStoreCollection::iterator active = mActiveCells.begin();
+        while (active!=mActiveCells.end())
+            unloadCell (active++);
         assert(mActiveCells.empty());
-        assert(mInactiveCells.empty());
         mCurrentCell = nullptr;
 
         mPreloader->clear();
@@ -570,24 +508,20 @@ namespace MWWorld
 
     void Scene::changeCellGrid (const osg::Vec3f &pos, int playerCellX, int playerCellY, bool changeEvent)
     {
-        for (auto iter = mInactiveCells.begin(); iter != mInactiveCells.end(); )
+        CellStoreCollection::iterator active = mActiveCells.begin();
+        while (active!=mActiveCells.end())
         {
-            auto* cell = *iter++;
-            if (cell->getCell()->isExterior())
+            if ((*active)->getCell()->isExterior())
             {
-                const auto dx = std::abs(playerCellX - cell->getCell()->getGridX());
-                const auto dy = std::abs(playerCellY - cell->getCell()->getGridY());
-                if (dx > mHalfGridSize || dy > mHalfGridSize)
-                    deactivateCell(cell);
-
-                if (dx > mHalfGridSize+1 || dy > mHalfGridSize+1)
-                    unloadInactiveCell(cell);
-            }
-            else
-            {
-                deactivateCell(cell);
-                unloadInactiveCell(cell);
+                if (std::abs (playerCellX-(*active)->getCell()->getGridX())<=mHalfGridSize &&
+                    std::abs (playerCellY-(*active)->getCell()->getGridY())<=mHalfGridSize)
+                {
+                    // keep cells within the new grid
+                    ++active;
+                    continue;
+                }
             }
+            unloadCell (active++);
         }
 
         mCurrentGridCenter = osg::Vec2i(playerCellX, playerCellY);
@@ -599,24 +533,32 @@ namespace MWWorld
         mRendering.getPagedRefnums(newGrid, mPagedRefs);
 
         std::size_t refsToLoad = 0;
-        const auto cellsToLoad = [&playerCellX,&playerCellY,&refsToLoad](CellStoreCollection& collection, int range) -> std::vector<std::pair<int,int>>
+        std::vector<std::pair<int, int>> cellsPositionsToLoad;
+        // get the number of refs to load
+        for (int x = playerCellX - mHalfGridSize; x <= playerCellX + mHalfGridSize; ++x)
         {
-            std::vector<std::pair<int, int>> cellsPositionsToLoad;
-            for (int x = playerCellX - range; x <= playerCellX + range; ++x)
+            for (int y = playerCellY - mHalfGridSize; y <= playerCellY + mHalfGridSize; ++y)
             {
-                for (int y = playerCellY - range; y <= playerCellY + range; ++y)
+                CellStoreCollection::iterator iter = mActiveCells.begin();
+
+                while (iter!=mActiveCells.end())
                 {
-                    if (!isCellInCollection(x, y, collection))
-                    {
-                        refsToLoad += MWBase::Environment::get().getWorld()->getExterior(x, y)->count();
-                        cellsPositionsToLoad.emplace_back(x, y);
-                    }
+                    assert ((*iter)->getCell()->isExterior());
+
+                    if (x==(*iter)->getCell()->getGridX() &&
+                        y==(*iter)->getCell()->getGridY())
+                        break;
+
+                    ++iter;
+                }
+
+                if (iter==mActiveCells.end())
+                {
+                    refsToLoad += MWBase::Environment::get().getWorld()->getExterior(x, y)->count();
+                    cellsPositionsToLoad.emplace_back(x, y);
                 }
             }
-            return cellsPositionsToLoad;
-        };
-        auto cellsPositionsToLoad = cellsToLoad(mActiveCells,mHalfGridSize);
-        auto cellsPositionsToLoadInactive = cellsToLoad(mInactiveCells,mHalfGridSize+1);
+        }
 
         Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
         Loading::ScopedLoad load(loadingListener);
@@ -640,26 +582,30 @@ namespace MWWorld
                 return getCellPositionPriority(lhs) < getCellPositionPriority(rhs);
             });
 
-        std::sort(cellsPositionsToLoadInactive.begin(), cellsPositionsToLoadInactive.end(),
-            [&] (const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) {
-                return getCellPositionPriority(lhs) < getCellPositionPriority(rhs);
-            });
-
         // Load cells
-        for (const auto& [x,y] : cellsPositionsToLoadInactive)
+        for (const auto& cellPosition : cellsPositionsToLoad)
         {
-            if (!isCellInCollection(x, y, mInactiveCells))
+            const auto x = cellPosition.first;
+            const auto y = cellPosition.second;
+
+            CellStoreCollection::iterator iter = mActiveCells.begin();
+
+            while (iter != mActiveCells.end())
             {
-                CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y);
-                loadInactiveCell (cell, loadingListener);
+                assert ((*iter)->getCell()->isExterior());
+
+                if (x == (*iter)->getCell()->getGridX() &&
+                    y == (*iter)->getCell()->getGridY())
+                    break;
+
+                ++iter;
             }
-        }
-        for (const auto& [x,y] : cellsPositionsToLoad)
-        {
-            if (!isCellInCollection(x, y, mActiveCells))
+
+            if (iter == mActiveCells.end())
             {
                 CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y);
-                activateCell (cell, loadingListener, changeEvent);
+
+                loadCell (cell, loadingListener, changeEvent);
             }
         }
 
@@ -692,8 +638,7 @@ namespace MWWorld
             CellStoreCollection::iterator iter = mActiveCells.begin();
 
             CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(it->mData.mX, it->mData.mY);
-            loadInactiveCell (cell, loadingListener, true);
-            activateCell (cell, loadingListener, false, true);
+            loadCell (cell, loadingListener, false, true);
 
             iter = mActiveCells.begin();
             while (iter != mActiveCells.end())
@@ -701,8 +646,7 @@ namespace MWWorld
                 if (it->isExterior() && it->mData.mX == (*iter)->getCell()->getGridX() &&
                     it->mData.mY == (*iter)->getCell()->getGridY())
                 {
-                    deactivateCell(*iter, true);
-                    unloadInactiveCell (*iter, true);
+                    unloadCell(iter, true);
                     break;
                 }
 
@@ -740,8 +684,7 @@ namespace MWWorld
             loadingListener->setLabel("Testing interior cells ("+std::to_string(i)+"/"+std::to_string(cells.getIntSize())+")...");
 
             CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(it->mName);
-            loadInactiveCell (cell, loadingListener, true);
-            activateCell (cell, loadingListener, false, true);
+            loadCell (cell, loadingListener, false, true);
 
             CellStoreCollection::iterator iter = mActiveCells.begin();
             while (iter != mActiveCells.end())
@@ -750,8 +693,7 @@ namespace MWWorld
 
                 if (it->mName == (*iter)->getCell()->mName)
                 {
-                    deactivateCell(*iter, true);
-                    unloadInactiveCell (*iter, true);
+                    unloadCell(iter, true);
                     break;
                 }
 
@@ -874,21 +816,15 @@ namespace MWWorld
         Log(Debug::Info) << "Changing to interior";
 
         // unload
-        for (auto iter = mInactiveCells.begin(); iter!=mInactiveCells.end(); )
-        {
-            auto* cell = *iter++;
-            deactivateCell(cell);
-            unloadInactiveCell(cell);
-        }
-        assert(mActiveCells.empty());
-        assert(mInactiveCells.empty());
+        CellStoreCollection::iterator active = mActiveCells.begin();
+        while (active!=mActiveCells.end())
+            unloadCell (active++);
 
         loadingListener->setProgressRange(cell->count());
 
         // Load cell.
         mPagedRefs.clear();
-        loadInactiveCell (cell, loadingListener);
-        activateCell (cell, loadingListener, changeEvent);
+        loadCell (cell, loadingListener, changeEvent);
 
         changePlayerCell(cell, position, adjustPlayerPos);
 
@@ -936,26 +872,23 @@ namespace MWWorld
         mCellChanged = false;
     }
 
-    void Scene::insertCell (CellStore &cell, Loading::Listener* loadingListener, bool onlyStatics, bool test)
+    void Scene::insertCell (CellStore &cell, Loading::Listener* loadingListener, bool test)
     {
-        InsertVisitor insertVisitor (cell, *loadingListener, onlyStatics, test);
+        InsertVisitor insertVisitor (cell, *loadingListener, test);
         cell.forEach (insertVisitor);
-        insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mRendering, mPagedRefs, onlyStatics); });
-        if (!onlyStatics)
-        {
-            insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mNavigator); });
+        insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mRendering, mPagedRefs); });
+        insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mNavigator); });
 
-            // do adjustPosition (snapping actors to ground) after objects are loaded, so we don't depend on the loading order
-            PositionVisitor posVisitor;
-            cell.forEach (posVisitor);
-        }
+        // do adjustPosition (snapping actors to ground) after objects are loaded, so we don't depend on the loading order
+        PositionVisitor posVisitor;
+        cell.forEach (posVisitor);
     }
 
     void Scene::addObjectToScene (const Ptr& ptr)
     {
         try
         {
-            addObject(ptr, *mPhysics, mRendering, mPagedRefs, false);
+            addObject(ptr, *mPhysics, mRendering, mPagedRefs);
             addObject(ptr, *mPhysics, mNavigator);
             MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale());
             const auto navigator = MWBase::Environment::get().getWorld()->getNavigator();
diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp
index 33c7b78d09..a70d3ccdd5 100644
--- a/apps/openmw/mwworld/scene.hpp
+++ b/apps/openmw/mwworld/scene.hpp
@@ -65,13 +65,13 @@ namespace MWWorld
     class Scene
     {
         public:
-            using CellStoreCollection = std::set<CellStore *>;
+
+            typedef std::set<CellStore *> CellStoreCollection;
 
         private:
 
             CellStore* mCurrentCell; // the cell the player is in
             CellStoreCollection mActiveCells;
-            CellStoreCollection mInactiveCells;
             bool mCellChanged;
             MWPhysics::PhysicsSystem *mPhysics;
             MWRender::RenderingManager& mRendering;
@@ -92,7 +92,7 @@ namespace MWWorld
 
             std::set<ESM::RefNum> mPagedRefs;
 
-            void insertCell (CellStore &cell, Loading::Listener* loadingListener, bool onlyStatics, bool test = false);
+            void insertCell (CellStore &cell, Loading::Listener* loadingListener, bool test = false);
             osg::Vec2i mCurrentGridCenter;
 
             // Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center
@@ -108,11 +108,6 @@ namespace MWWorld
             osg::Vec4i gridCenterToBounds(const osg::Vec2i &centerCell) const;
             osg::Vec2i getNewGridCenter(const osg::Vec3f &pos, const osg::Vec2i *currentGridCenter = nullptr) const;
 
-            void unloadInactiveCell (CellStore* cell, bool test = false);
-            void deactivateCell (CellStore* cell, bool test = false);
-            void activateCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn, bool test = false);
-            void loadInactiveCell (CellStore *cell, Loading::Listener* loadingListener, bool test = false);
-
         public:
 
             Scene (MWRender::RenderingManager& rendering, MWPhysics::PhysicsSystem *physics,
@@ -124,6 +119,10 @@ namespace MWWorld
             void preloadTerrain(const osg::Vec3f& pos, bool sync=false);
             void reloadTerrain();
 
+            void unloadCell (CellStoreCollection::iterator iter, bool test = false);
+
+            void loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn, bool test = false);
+
             void playerMoved (const osg::Vec3f& pos);
 
             void changePlayerCell (CellStore* newCell, const ESM::Position& position, bool adjustPlayerPos);
diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp
index ef00315cbb..442672d2bf 100644
--- a/apps/openmw/mwworld/worldimp.cpp
+++ b/apps/openmw/mwworld/worldimp.cpp
@@ -1420,7 +1420,7 @@ namespace MWWorld
             mWorldScene->removeFromPagedRefs(ptr);
 
             mRendering->rotateObject(ptr, rotate);
-            mPhysics->updateRotation(ptr, rotate);
+            mPhysics->updateRotation(ptr);
 
             if (const auto object = mPhysics->getObject(ptr))
                 updateNavigatorObject(object);