diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp
index db34e04117..840bb3bd61 100644
--- a/apps/openmw/mwphysics/physicssystem.cpp
+++ b/apps/openmw/mwphysics/physicssystem.cpp
@@ -396,16 +396,16 @@ namespace MWPhysics
                 if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope
                         && tracer.mHitObject->getBroadphaseHandle()->m_collisionFilterGroup != CollisionType_Actor)
                 {
-                    /*
                     const btCollisionObject* standingOn = tracer.mHitObject;
-
+                    /*
                     if (const OEngine::Physic::RigidBody* body = dynamic_cast<const OEngine::Physic::RigidBody*>(standingOn))
                     {
                         standingCollisionTracker[ptr.getRefData().getHandle()] = body->mName;
                     }
+                    */
+
                     if (standingOn->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Water)
                         physicActor->setWalkingOnWater(true);
-                    */
                     if (!isFlying)
                         newPosition.z() = tracer.mEndPos.z() + 1.0f;
 
@@ -698,23 +698,21 @@ namespace MWPhysics
         */
     }
 
-    std::pair<bool, Ogre::Vector3>
-    PhysicsSystem::castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len)
+    std::pair<bool, osg::Vec3f> PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to)
     {
-        return std::make_pair(false, Ogre::Vector3());
-        /*
-        Ogre::Ray ray = Ogre::Ray(orig, dir);
-        Ogre::Vector3 to = ray.getPoint(len);
+        btVector3 btFrom = toBullet(from);
+        btVector3 btTo = toBullet(to);
 
-        btVector3 btFrom = btVector3(orig.x, orig.y, orig.z);
-        btVector3 btTo = btVector3(to.x, to.y, to.z);
+        btCollisionWorld::ClosestRayResultCallback resultCallback(btFrom, btTo);
+        resultCallback.m_collisionFilterGroup = 0xff;
+        resultCallback.m_collisionFilterMask = CollisionType_World | CollisionType_HeightMap;
 
-        std::pair<std::string, float> test = mEngine->rayTest(btFrom, btTo);
-        if (test.second == -1) {
-            return std::make_pair(false, Ogre::Vector3());
+        mDynamicsWorld->rayTest(btFrom, btTo, resultCallback);
+        if (resultCallback.hasHit())
+        {
+            return std::make_pair(true, toOsg(resultCallback.m_hitPointWorld));
         }
-        return std::make_pair(true, ray.getPoint(len * test.second));
-        */
+        return std::make_pair(false, osg::Vec3f());
     }
 
     std::vector<std::string> PhysicsSystem::getCollisions(const MWWorld::Ptr &ptr, int collisionGroup, int collisionMask)
diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp
index 91e166bef4..5f89b1b435 100644
--- a/apps/openmw/mwphysics/physicssystem.hpp
+++ b/apps/openmw/mwphysics/physicssystem.hpp
@@ -86,8 +86,8 @@ namespace MWPhysics
             // cast ray, return true if it hit something.
             bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to,bool ignoreHeightMap = false);
 
-            std::pair<bool, Ogre::Vector3>
-            castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);
+            /// @return <bool hit, world hit position>
+            std::pair<bool, osg::Vec3f> castRay(const osg::Vec3f &from, const osg::Vec3f &to);
 
             /// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will
             /// be overwritten. Valid until the next call to applyQueuedMovement.
diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp
index 110ed61beb..c81a3f71b9 100644
--- a/apps/openmw/mwworld/worldimp.cpp
+++ b/apps/openmw/mwworld/worldimp.cpp
@@ -10,6 +10,8 @@
 #include <OgreSceneNode.h>
 
 #include <osg/Group>
+#include <osg/ComputeBoundsVisitor>
+#include <osg/PositionAttitudeTransform>
 
 #include <components/misc/rng.hpp>
 
@@ -1888,29 +1890,6 @@ namespace MWWorld
 
     Ptr World::copyObjectToCell(const Ptr &object, CellStore* cell, ESM::Position pos, bool adjustPos)
     {
-#if 0
-        if (!object.getClass().isActor() && adjustPos)
-        {
-            // Adjust position so the location we wanted ends up in the middle of the object bounding box
-            Ogre::Vector3 min, max;
-            if (mPhysics->getObjectAABB(object, min, max)) {
-                Ogre::Quaternion xr(Ogre::Radian(-pos.rot[0]), Ogre::Vector3::UNIT_X);
-                Ogre::Quaternion yr(Ogre::Radian(-pos.rot[1]), Ogre::Vector3::UNIT_Y);
-                Ogre::Quaternion zr(Ogre::Radian(-pos.rot[2]), Ogre::Vector3::UNIT_Z);
-
-                Ogre::Vector3 adjust (
-                             (min.x + max.x) / 2,
-                            (min.y + max.y) / 2,
-                            min.z
-                            );
-                adjust = (xr*yr*zr) * adjust;
-                pos.pos[0] -= adjust.x;
-                pos.pos[1] -= adjust.y;
-                pos.pos[2] -= adjust.z;
-            }
-        }
-#endif
-
         if (cell->isExterior())
         {
             int cellX, cellY;
@@ -1941,6 +1920,28 @@ namespace MWWorld
             addContainerScripts(dropped, cell);
         }
 
+        if (!object.getClass().isActor() && adjustPos && dropped.getRefData().getBaseNode())
+        {
+            // Adjust position so the location we wanted ends up in the middle of the object bounding box
+            osg::ComputeBoundsVisitor computeBounds;
+            dropped.getRefData().getBaseNode()->accept(computeBounds);
+            osg::BoundingBox bounds = computeBounds.getBoundingBox();
+            if (bounds.valid())
+            {
+                bounds.set(bounds._min - pos.asVec3(), bounds._max - pos.asVec3());
+
+                osg::Vec3f adjust (
+                            (bounds.xMin() + bounds.xMax()) / 2,
+                           (bounds.yMin() + bounds.yMax()) / 2,
+                           bounds.zMin()
+                           );
+                pos.pos[0] -= adjust.x();
+                pos.pos[1] -= adjust.y();
+                pos.pos[2] -= adjust.z();
+                moveObject(dropped, pos.pos[0], pos.pos[1], pos.pos[2]);
+            }
+        }
+
         return dropped;
     }
 
@@ -1954,17 +1955,15 @@ namespace MWWorld
         pos.rot[0] = 0;
         pos.rot[1] = 0;
 
-        Ogre::Vector3 orig =
-            Ogre::Vector3(pos.pos);
-        orig.z += 20;
-        //Ogre::Vector3 dir = Ogre::Vector3(0, 0, -1);
+        osg::Vec3f orig = pos.asVec3();
+        orig.z() += 20;
+        osg::Vec3f dir (0, 0, -1);
 
-        //float len = 100.0;
+        float len = 100.0;
 
-        std::pair<bool, Ogre::Vector3> hit;// =
-            //mPhysics->castRay(orig, dir, len);
+        std::pair<bool, osg::Vec3f> hit = mPhysics->castRay(orig, dir*len);
         if (hit.first)
-            pos.pos[2] = hit.second.z;
+            pos.pos[2] = hit.second.z();
 
         // copy the object and set its count
         int origCount = object.getRefData().getCount();
@@ -2069,14 +2068,12 @@ namespace MWWorld
     // TODO: There might be better places to update PhysicActor::mOnGround.
     bool World::isOnGround(const MWWorld::Ptr &ptr) const
     {
-        return true;
-        /*
-        //RefData &refdata = ptr.getRefData();
-        OEngine::Physic::PhysicActor *physactor = 0;//mPhysEngine->getCharacter(refdata.getHandle());
+        MWPhysics::Actor* physactor = mPhysics->getActor(ptr);
 
         if(!physactor)
             return false;
-
+        return physactor->getOnGround();
+        /*
         if(physactor->getOnGround())
             return true;
         else