From 18a139cd66dada5a42b93a7f26bb46c7929fa744 Mon Sep 17 00:00:00 2001
From: Jason Hooks <jhooks1@mix.wvu.edu>
Date: Sat, 24 Mar 2012 22:03:08 -0400
Subject: [PATCH 01/20] adding up and down move buttons

---
 apps/openmw/mwclass/npc.cpp           |   5 +-
 apps/openmw/mwinput/inputmanager.cpp  |  16 +
 apps/openmw/mwmechanics/movement.hpp  |   3 +-
 apps/openmw/mwrender/objects.cpp      |   2 +
 apps/openmw/mwworld/physicssystem.cpp |  15 +-
 apps/openmw/mwworld/player.cpp        |   9 +
 apps/openmw/mwworld/player.hpp        |   1 +
 apps/openmw/physicssystem.cpp         | 225 +++++++
 libs/openengine/bullet/physic.cpp     |   4 +-
 libs/openengine/bullet/pmove.cpp      |  27 +-
 libs/openengine/bullet/pmove.h        |   4 +-
 libs/openengine/bullet/trace.cpp      |   4 +-
 libs/openengine/bullet/weather.cpp    | 811 ++++++++++++++++++++++++++
 libs/openengine/bullet/weather.hpp    | 272 +++++++++
 14 files changed, 1374 insertions(+), 24 deletions(-)
 create mode 100644 apps/openmw/physicssystem.cpp
 create mode 100644 libs/openengine/bullet/weather.cpp
 create mode 100644 libs/openengine/bullet/weather.hpp

diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp
index 83a94d27d..522fce3a3 100644
--- a/apps/openmw/mwclass/npc.cpp
+++ b/apps/openmw/mwclass/npc.cpp
@@ -269,8 +269,9 @@ namespace MWClass
     {
         Ogre::Vector3 vector (0, 0, 0);
 
-        vector.x = - getMovementSettings (ptr).mLeftRight * 200;
-        vector.y = getMovementSettings (ptr).mForwardBackward * 200;
+        vector.x = - getMovementSettings (ptr).mLeftRight * 127;
+        vector.y = getMovementSettings (ptr).mForwardBackward * 127;
+		vector.z = getMovementSettings(ptr).mUpDown * 127;
 
         if (getStance (ptr, Run, false))
             vector *= 2;
diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp
index 88534ddda..074f8a906 100644
--- a/apps/openmw/mwinput/inputmanager.cpp
+++ b/apps/openmw/mwinput/inputmanager.cpp
@@ -60,6 +60,7 @@ namespace MWInput
       A_CycleWeaponRight,
       A_ToggleSneak,    //Toggles Sneak, add Push-Sneak later
       A_ToggleWalk, //Toggle Walking/Running
+	  A_Crouch,
 
       A_QuickSave,
       A_QuickLoad,
@@ -259,6 +260,9 @@ namespace MWInput
       poller.bind(A_MoveRight, KC_D);
       poller.bind(A_MoveForward, KC_W);
       poller.bind(A_MoveBackward, KC_S);
+	  
+	  poller.bind(A_Jump, KC_E);
+	  poller.bind(A_Crouch, KC_LCONTROL);
     }
 
     //NOTE: Used to check for movement keys
@@ -306,6 +310,18 @@ namespace MWInput
         else
             player.setForwardBackward (0);
 
+		if (poller.isDown(A_Jump))
+        {
+            
+            player.setUpDown (1);
+        }
+        else if (poller.isDown(A_Crouch))
+        {
+            player.setUpDown (-1);
+        }
+        else
+            player.setUpDown (0);
+
         return true;
     }
 
diff --git a/apps/openmw/mwmechanics/movement.hpp b/apps/openmw/mwmechanics/movement.hpp
index a555ac010..11eb83151 100644
--- a/apps/openmw/mwmechanics/movement.hpp
+++ b/apps/openmw/mwmechanics/movement.hpp
@@ -8,8 +8,9 @@ namespace MWMechanics
     {
         signed char mLeftRight; // 1: wants to move left, -1: wants to move right
         signed char mForwardBackward; // 1:wants to move forward, -1: wants to move backward
+		signed char mUpDown;
 
-        Movement() : mLeftRight (0), mForwardBackward (0) {}
+        Movement() : mLeftRight (0), mForwardBackward (0), mUpDown(0) {}
     };
 }
 
diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp
index 717064ada..0d19a3013 100644
--- a/apps/openmw/mwrender/objects.cpp
+++ b/apps/openmw/mwrender/objects.cpp
@@ -56,8 +56,10 @@ void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
 
     Ogre::SceneNode* insert = cellnode->createChildSceneNode();
     const float *f = ptr.getRefData().getPosition().pos;
+
     insert->setPosition(f[0], f[1], f[2]);
     insert->setScale(ptr.getCellRef().scale, ptr.getCellRef().scale, ptr.getCellRef().scale);
+	
 
     // Convert MW rotation to a quaternion:
     f = ptr.getCellRef().pos.rot;
diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp
index 11a43c7d3..d54f4696a 100644
--- a/apps/openmw/mwworld/physicssystem.cpp
+++ b/apps/openmw/mwworld/physicssystem.cpp
@@ -103,7 +103,7 @@ namespace MWWorld
 				
 				playerphysics->ps.viewangles.x = 0;
 				playerphysics->ps.viewangles.z = 0;
-				playerphysics->ps.viewangles.y = both.getYaw().valueDegrees() *-1 + 90;
+			playerphysics->ps.viewangles.y = both.getYaw().valueDegrees() *-1 + 90;
 				//playerphysics->ps.viewangles.z = both.getPitch().valueDegrees();
 				
 			
@@ -113,6 +113,7 @@ namespace MWWorld
                 Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
 				pm_ref.rightmove = -dir1.x;
 				pm_ref.forwardmove = dir1.z;
+				pm_ref.upmove = dir1.y;
 				
 				
 				
@@ -127,6 +128,7 @@ namespace MWWorld
                 Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
 				pm_ref.rightmove = -dir1.x;
 				pm_ref.forwardmove = dir1.z;
+				pm_ref.upmove = dir.y;
 				
                 dir = 0.025*(quat*dir1);
             }
@@ -135,7 +137,7 @@ namespace MWWorld
             //set the walk direction
             act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
         }
-        //mEngine->stepSimulation(duration);
+        mEngine->stepSimulation(duration);
 		Pmove(playerphysics);
         std::vector< std::pair<std::string, Ogre::Vector3> > response;
         for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
@@ -147,7 +149,7 @@ namespace MWWorld
 				
 				coord = playerphysics->ps.origin;
 				//std::cout << "Coord" << coord << "\n";
-				coord = Ogre::Vector3(coord.x, coord.z, coord.y);   //x, z, -y
+				//coord = Ogre::Vector3(coord.x, coord.z, coord.y);   //x, z, -y
 				
 			}
             response.push_back(std::pair<std::string, Ogre::Vector3>(it->first, coord));
@@ -218,6 +220,10 @@ namespace MWWorld
 
     bool PhysicsSystem::toggleCollisionMode()
     {
+		if(playerphysics->ps.move_type==PM_NOCLIP)
+			playerphysics->ps.move_type=PM_NORMAL;
+		else
+			playerphysics->ps.move_type=PM_NOCLIP;
         for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
         {
             if (it->first=="player")
@@ -248,7 +254,10 @@ namespace MWWorld
     }
 
      void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){
+		 
            Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
+		   Ogre::Vector3 objPos = node->getPosition();
+
          addObject (node->getName(), model, node->getOrientation(),
             node->getScale().x, node->getPosition());
      }
diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp
index 5bfb82138..884a72c3a 100644
--- a/apps/openmw/mwworld/player.cpp
+++ b/apps/openmw/mwworld/player.cpp
@@ -80,6 +80,14 @@ namespace MWWorld
 
         MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
     }
+	void Player::setUpDown(int value)
+	{
+		MWWorld::Ptr ptr = getPlayer();
+
+        
+
+        MWWorld::Class::get (ptr).getMovementSettings (ptr).mUpDown = value;
+	}
 
     void Player::toggleRunning()
     {
@@ -89,4 +97,5 @@ namespace MWWorld
 
         MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Run, !running);
     }
+	
 }
diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp
index 01c71da43..da74fe6de 100644
--- a/apps/openmw/mwworld/player.hpp
+++ b/apps/openmw/mwworld/player.hpp
@@ -111,6 +111,7 @@ namespace MWWorld
         void setLeftRight (int value);
 
         void setForwardBackward (int value);
+		void setUpDown(int value);
 
         void toggleRunning();
     };
diff --git a/apps/openmw/physicssystem.cpp b/apps/openmw/physicssystem.cpp
new file mode 100644
index 000000000..a07358f8e
--- /dev/null
+++ b/apps/openmw/physicssystem.cpp
@@ -0,0 +1,225 @@
+#include <stdexcept>
+
+#include "physicssystem.hpp"
+#include "../mwworld/ptr.hpp"
+#include "../mwworld/world.hpp" // FIXME
+#include <components/nifbullet/bullet_nif_loader.hpp>
+
+#include "OgreRoot.h"
+#include "OgreRenderWindow.h"
+#include "OgreSceneManager.h"
+#include "OgreViewport.h"
+#include "OgreCamera.h"
+#include "OgreTextureManager.h"
+
+
+using namespace Ogre;
+namespace MWWorld
+{
+
+    PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
+        mRender(_rend), mEngine(0), mFreeFly (true)
+    {
+        // Create physics. shapeLoader is deleted by the physic engine
+        NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
+        mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
+    }
+
+    PhysicsSystem::~PhysicsSystem()
+    {
+        delete mEngine;
+    
+    }
+    OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine()
+    {
+        return mEngine;
+    }
+    
+	std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
+	{
+		std::string handle = "";
+
+        //get a ray pointing to the center of the viewport
+        Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
+        mRender.getViewport()->getWidth()/2,
+        mRender.getViewport()->getHeight()/2);
+        //let's avoid the capsule shape of the player.
+        centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection());
+        btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y);
+        btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y);
+
+        return mEngine->rayTest(from,to);
+    }
+    
+    bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to)
+    {
+        btVector3 _from, _to;
+        _from = btVector3(from.x, from.y, from.z);
+        _to = btVector3(to.x, to.y, to.z);
+        
+        std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
+        
+        return !(result.first == "");
+    }
+
+
+    std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysics (float duration,
+        const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
+    {
+        //set the DebugRenderingMode. To disable it,set it to 0
+        //eng->setDebugRenderingMode(1);
+
+        //set the walkdirection to 0 (no movement) for every actor)
+        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
+        {
+            OEngine::Physic::PhysicActor* act = it->second;
+            act->setWalkDirection(btVector3(0,0,0));
+        }
+
+        for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
+            iter!=actors.end(); ++iter)
+        {
+            OEngine::Physic::PhysicActor* act = mEngine->getCharacter(iter->first);
+
+            //dirty stuff to get the camera orientation. Must be changed!
+
+            Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first);
+            Ogre::Vector3 dir;
+            Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
+            Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
+            if(mFreeFly)
+            {
+                Ogre::Quaternion yawQuat = yawNode->getOrientation();
+                Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
+                Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
+                dir = 0.07*(yawQuat*pitchQuat*dir1);
+            }
+            else
+            {
+                Ogre::Quaternion quat = yawNode->getOrientation();
+                Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
+                dir = 0.025*(quat*dir1);
+            }
+
+            //set the walk direction
+            act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
+        }
+        mEngine->stepSimulation(duration);
+
+        std::vector< std::pair<std::string, Ogre::Vector3> > response;
+        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
+        {
+            btVector3 newPos = it->second->getPosition();
+            Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z());
+
+            response.push_back(std::pair<std::string, Ogre::Vector3>(it->first, coord));
+        }
+        return response;
+    }
+
+    void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh,
+        const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
+    {
+        OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale);
+        mEngine->addRigidBody(body);
+        btTransform tr;
+        tr.setOrigin(btVector3(position.x,position.y,position.z));
+		std::cout << "Position object:" << position << "\n";
+        tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w));
+        body->setWorldTransform(tr);
+    }
+
+    void PhysicsSystem::addActor (const std::string& handle, const std::string& mesh,
+        const Ogre::Vector3& position)
+    {
+        //TODO:optimize this. Searching the std::map isn't very efficient i think.
+        mEngine->addCharacter(handle);
+        OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle);
+        act->setPosition(btVector3(position.x,position.y,position.z));
+    }
+
+    void PhysicsSystem::removeObject (const std::string& handle)
+    {
+        //TODO:check if actor???
+        mEngine->removeCharacter(handle);
+        mEngine->removeRigidBody(handle);
+        mEngine->deleteRigidBody(handle);
+    }
+
+    void PhysicsSystem::moveObject (const std::string& handle, const Ogre::Vector3& position)
+    {
+        if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
+        {
+            // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
+            // start positions others than 0, 0, 0
+            btTransform tr = body->getWorldTransform();
+            tr.setOrigin(btVector3(position.x,position.y,position.z));
+            body->setWorldTransform(tr);
+        }
+        if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
+        {
+            // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
+            // start positions others than 0, 0, 0
+            act->setPosition(btVector3(position.x,position.y,position.z));
+        }
+    }
+
+    void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation)
+    {
+         if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
+        {
+            // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
+            // start positions others than 0, 0, 0
+            act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
+        }
+    }
+
+    void PhysicsSystem::scaleObject (const std::string& handle, float scale)
+    {
+
+    }
+
+    bool PhysicsSystem::toggleCollisionMode()
+    {
+        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
+        {
+            if (it->first=="player")
+            {
+                OEngine::Physic::PhysicActor* act = it->second;
+
+                bool cmode = act->getCollisionMode();
+                if(cmode)
+                {
+                    act->enableCollisions(false);
+                    act->setGravity(0.);
+                    act->setVerticalVelocity(0);
+                    mFreeFly = true;
+                    return false;
+                }
+                else
+                {
+                    mFreeFly = false;
+                    act->enableCollisions(true);
+                    act->setGravity(4.);
+                    act->setVerticalVelocity(0);
+                    return true;
+                }
+            }
+        }
+
+        throw std::logic_error ("can't find player");
+    }
+
+     void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){
+           Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
+         addObject (node->getName(), model, node->getOrientation(),
+            node->getScale().x, node->getPosition());
+     }
+
+     void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){
+           Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
+            // std::cout << "Adding node with name" << node->getName();
+         addActor (node->getName(), model, node->getPosition());
+     }
+
+}
diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp
index 07bad3053..911f6279b 100644
--- a/libs/openengine/bullet/physic.cpp
+++ b/libs/openengine/bullet/physic.cpp
@@ -156,10 +156,10 @@ namespace Physic
         solver = new btSequentialImpulseConstraintSolver;
 
         //TODO: memory leak?
-        btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache();
+        //btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache();
         //pairCache->setInternalGhostPairCallback( new btGhostPairCallback() );
 
-        broadphase = new btDbvtBroadphase(pairCache);
+        broadphase = new btDbvtBroadphase();
 
         // The world.
         dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 45fe84f4f..71c15fe45 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -786,7 +786,7 @@ static void PM_WaterMove( playerMove* const pm )
 		wishvel = pml.forward * scale * pm->cmd.forwardmove + pml.right * scale * pm->cmd.rightmove;
 
 		//wishvel[2] += scale * pm->cmd.upmove;
-		wishvel.y += pm->cmd.upmove * scale;
+		wishvel.z += pm->cmd.upmove * scale;
 	}
 
 	//VectorCopy (wishvel, wishdir);
@@ -1094,21 +1094,22 @@ void AngleVectors( const Ogre::Vector3& angles, Ogre::Vector3* const forward, Og
 	if (forward)
 	{
 		forward->x = cp * cy;
-		forward->z = cp * sy;
-		forward->y = -sp;
+		forward->y = cp * sy;
+		forward->z = -sp;
 	}
 	if (right)
 	{
 		right->x = (-1 * sr * sp * cy + -1 * cr * -sy);
-		right->z = (-1 * sr * sp * sy + -1 * cr * cy);
-		right->y = 0.0f;//-1 * sp * cp;
+		right->y = (-1 * sr * sp * sy + -1 * cr * cy);
+		right->z = 0.0f;//-1 * sp * cp;
 	}
 	if (up)
 	{
-		up->x = (cr * sp * cy + -sr * -sy);
-		up->z = (cr * sp * sy + -sr * cy);
-		up->y = cr * cp;
+		up->x =(cr * sp * cy + -sr * -sy);
+		up->y=(cr * sp * sy + -sr * cy);
+		up->z = cr * cp;
 	}
+	
 }
 
 void PM_GroundTraceMissed()
@@ -1356,7 +1357,7 @@ static void PM_CrashLand( void )
 
 static void PM_GroundTrace( void ) 
 {
-	std::cout << "Ground trace\n";
+	//std::cout << "Ground trace\n";
 	Ogre::Vector3		point;
 	traceResults		trace;
 
@@ -1578,9 +1579,12 @@ static void PM_NoclipMove( void )
 	
 	//for (i=0 ; i<3 ; i++)
 		//wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove;
+	std::cout << "Forward" << pml.forward << "\n";
+	std::cout << "Right" << pml.right << "\n";
+	std::cout << "Up" << pml.up << "\n";
 	wishvel = pml.forward * fmove + pml.right * smove;
 	//wishvel[2] += pm->cmd.upmove;
-	wishvel.y += pm->cmd.upmove;
+	wishvel.z += pm->cmd.upmove;
 
 	//VectorCopy (wishvel, wishdir);
 	wishdir = wishvel;
@@ -1720,7 +1724,6 @@ void PM_SetWaterLevel( playerMove* const pm )
 
 void PmoveSingle (playerMove* const pmove) 
 {
-	std::cout << "Pmove single\n";
 	//pm = pmove;
 
 	// Aedra doesn't support Q3-style VM traps D:	//while(1);
@@ -1944,7 +1947,7 @@ void PmoveSingle (playerMove* const pmove)
 	else 
 	{
 		// airborne
-		std::cout << "AIRMOVE\n";
+		//std::cout << "AIRMOVE\n";
 		PM_AirMove();
 		//bprintf("AirMove\n");
 	}
diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h
index e90cc3b35..5dfd18f6d 100644
--- a/libs/openengine/bullet/pmove.h
+++ b/libs/openengine/bullet/pmove.h
@@ -90,9 +90,9 @@ struct playerMove
 {
 	struct playerStruct
 	{
-		playerStruct() : gravity(50.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NORMAL), pm_time(0)
+		playerStruct() : gravity(50.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0)
 		{
-			origin = Ogre::Vector3(733.164f,1000.0f, 839.432f);
+			origin = Ogre::Vector3(733.164f,900.0f, 839.432f);
 			velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f);
 
 			viewangles = Ogre::Vector3(0.0f, 0.0f, 0.0f);
diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp
index 49e12064e..57d071f17 100644
--- a/libs/openengine/bullet/trace.cpp
+++ b/libs/openengine/bullet/trace.cpp
@@ -112,8 +112,8 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
 	float y2 = to.getOrigin().getY();
 	float z2 = to.getOrigin().getZ();
 	
-	std::cout << "BtFrom: " << x << "," << y << "," << z << "\n";
-	std::cout << "BtTo: " << x2 << "," << y2 << "," << z2 << "\n";
+	//std::cout << "BtFrom: " << x << "," << y << "," << z << "\n";
+	//std::cout << "BtTo: " << x2 << "," << y2 << "," << z2 << "\n";
 	//std::cout << "BtTo: " << to.getOrigin().getX() << "," << to.getOrigin().getY() << "," << to.getOrigin().getZ() << "\n";
 
 
diff --git a/libs/openengine/bullet/weather.cpp b/libs/openengine/bullet/weather.cpp
new file mode 100644
index 000000000..90afc4e78
--- /dev/null
+++ b/libs/openengine/bullet/weather.cpp
@@ -0,0 +1,811 @@
+#include "weather.hpp"
+#include "world.hpp"
+#include "player.hpp"
+
+#include "../mwrender/renderingmanager.hpp"
+#include "../mwsound/soundmanager.hpp"
+
+#include <ctime>
+#include <cstdlib>
+#include <iostream>
+
+#include <boost/algorithm/string.hpp>   
+
+using namespace Ogre;
+using namespace MWWorld;
+using namespace MWSound;
+
+#define lerp(x, y) (x * (1-factor) + y * factor)
+
+const std::string WeatherGlobals::mThunderSoundID0 = "Thunder0";
+const std::string WeatherGlobals::mThunderSoundID1 = "Thunder1";
+const std::string WeatherGlobals::mThunderSoundID2 = "Thunder2";
+const std::string WeatherGlobals::mThunderSoundID3 = "Thunder3";
+const float WeatherGlobals::mSunriseTime = 8;
+const float WeatherGlobals::mSunsetTime = 18;
+const float WeatherGlobals::mSunriseDuration = 2;
+const float WeatherGlobals::mSunsetDuration = 2;
+const float WeatherGlobals::mWeatherUpdateTime = 20.f;
+const float WeatherGlobals::mThunderFrequency = .4;
+const float WeatherGlobals::mThunderThreshold = 0.6;
+const float WeatherGlobals::mThunderSoundDelay = 0.25;
+
+WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) : 
+     mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
+     mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0)
+{
+    mRendering = rendering;
+    mEnvironment = env;
+    
+    #define clr(r,g,b) ColourValue(r/255.f, g/255.f, b/255.f)
+    
+    /// \todo read these from Morrowind.ini
+    Weather clear;
+    clear.mCloudTexture = "tx_sky_clear.dds";
+    clear.mCloudsMaximumPercent = 1.0;
+    clear.mTransitionDelta = 0.015;
+    clear.mSkySunriseColor = clr(118, 141, 164);
+    clear.mSkyDayColor = clr(95, 135, 203);
+    clear.mSkySunsetColor = clr(56, 89, 129);
+    clear.mSkyNightColor = clr(9, 10, 11);
+    clear.mFogSunriseColor = clr(255, 189, 157);
+    clear.mFogDayColor = clr(206, 227, 255);
+    clear.mFogSunsetColor = clr(255, 189, 157);
+    clear.mFogNightColor = clr(9, 10, 11);
+    clear.mAmbientSunriseColor = clr(47, 66, 96);
+    clear.mAmbientDayColor = clr(137, 140, 160);
+    clear.mAmbientSunsetColor = clr(68, 75, 96);
+    clear.mAmbientNightColor = clr(32, 35, 42);
+    clear.mSunSunriseColor = clr(242, 159, 99);
+    clear.mSunDayColor = clr(255, 252, 238);
+    clear.mSunSunsetColor = clr(255, 115, 79);
+    clear.mSunNightColor = clr(59, 97, 176);
+    clear.mSunDiscSunsetColor = clr(255, 189, 157);
+    clear.mLandFogDayDepth = 0.69;
+    clear.mLandFogNightDepth = 0.69;
+    clear.mWindSpeed = 0.1;
+    clear.mCloudSpeed = 1.25;
+    clear.mGlareView = 1.0;
+    mWeatherSettings["clear"] = clear;
+    
+    Weather cloudy;
+    cloudy.mCloudTexture = "tx_sky_cloudy.dds";
+    cloudy.mCloudsMaximumPercent = 1.0;
+    cloudy.mTransitionDelta = 0.015;
+    cloudy.mSkySunriseColor = clr(126, 158, 173);
+    cloudy.mSkyDayColor = clr(117, 160, 215);
+    cloudy.mSkySunsetColor = clr(111, 114, 159);
+    cloudy.mSkyNightColor = clr(9, 10, 11);
+    cloudy.mFogSunriseColor = clr(255, 207, 149);
+    cloudy.mFogDayColor = clr(245, 235, 224);
+    cloudy.mFogSunsetColor = clr(255, 155, 106);
+    cloudy.mFogNightColor = clr(9, 10, 11);
+    cloudy.mAmbientSunriseColor = clr(66, 74, 87);
+    cloudy.mAmbientDayColor = clr(137, 145, 160);
+    cloudy.mAmbientSunsetColor = clr(71, 80, 92);
+    cloudy.mAmbientNightColor = clr(32, 39, 54);
+    cloudy.mSunSunriseColor = clr(241, 177, 99);
+    cloudy.mSunDayColor = clr(255, 236, 221);
+    cloudy.mSunSunsetColor = clr(255, 89, 00);
+    cloudy.mSunNightColor = clr(77, 91, 124);
+    cloudy.mSunDiscSunsetColor = clr(255, 202, 179);
+    cloudy.mLandFogDayDepth = 0.72;
+    cloudy.mLandFogNightDepth = 0.72;
+    cloudy.mWindSpeed = 0.2;
+    cloudy.mCloudSpeed = 2;
+    cloudy.mGlareView = 1.0;
+    mWeatherSettings["cloudy"] = cloudy;
+    
+    Weather foggy;
+    foggy.mCloudTexture = "tx_sky_foggy.dds";
+    foggy.mCloudsMaximumPercent = 1.0;
+    foggy.mTransitionDelta = 0.015;
+    foggy.mSkySunriseColor = clr(197, 190, 180);
+    foggy.mSkyDayColor = clr(184, 211, 228);
+    foggy.mSkySunsetColor = clr(142, 159, 176);
+    foggy.mSkyNightColor = clr(18, 23, 28);
+    foggy.mFogSunriseColor = clr(173, 164, 148);
+    foggy.mFogDayColor = clr(150, 187, 209);
+    foggy.mFogSunsetColor = clr(113, 135, 157);
+    foggy.mFogNightColor = clr(19, 24, 29);
+    foggy.mAmbientSunriseColor = clr(48, 43, 37);
+    foggy.mAmbientDayColor = clr(92, 109, 120);
+    foggy.mAmbientSunsetColor = clr(28, 33, 39);
+    foggy.mAmbientNightColor = clr(28, 33, 39);
+    foggy.mSunSunriseColor = clr(177, 162, 137);
+    foggy.mSunDayColor = clr(111, 131, 151);
+    foggy.mSunSunsetColor = clr(125, 157, 189);
+    foggy.mSunNightColor = clr(81, 100, 119);
+    foggy.mSunDiscSunsetColor = clr(223, 223, 223);
+    foggy.mLandFogDayDepth = 1.0;
+    foggy.mLandFogNightDepth = 1.9;
+    foggy.mWindSpeed = 0;
+    foggy.mCloudSpeed = 1.25;
+    foggy.mGlareView = 0.25;
+    mWeatherSettings["foggy"] = foggy;
+    
+    Weather thunderstorm;
+    thunderstorm.mCloudTexture = "tx_sky_thunder.dds";
+    thunderstorm.mCloudsMaximumPercent = 0.66;
+    thunderstorm.mTransitionDelta = 0.03;
+    thunderstorm.mSkySunriseColor = clr(35, 36, 39);
+    thunderstorm.mSkyDayColor = clr(97, 104, 115);
+    thunderstorm.mSkySunsetColor = clr(35, 36, 39);
+    thunderstorm.mSkyNightColor = clr(19, 20, 22);
+    thunderstorm.mFogSunriseColor = clr(70, 74, 85);
+    thunderstorm.mFogDayColor = clr(97, 104, 115);
+    thunderstorm.mFogSunsetColor = clr(70, 74, 85);
+    thunderstorm.mFogNightColor = clr(19, 20, 22);
+    thunderstorm.mAmbientSunriseColor = clr(54, 54, 54);
+    thunderstorm.mAmbientDayColor = clr(90, 90, 90);
+    thunderstorm.mAmbientSunsetColor = clr(54, 54, 54);
+    thunderstorm.mAmbientNightColor = clr(49, 51, 54);
+    thunderstorm.mSunSunriseColor = clr(91, 99, 122);
+    thunderstorm.mSunDayColor = clr(138, 144, 155);
+    thunderstorm.mSunSunsetColor = clr(96, 101, 117);
+    thunderstorm.mSunNightColor = clr(55, 76, 110);
+    thunderstorm.mSunDiscSunsetColor = clr(128, 128, 128);
+    thunderstorm.mLandFogDayDepth = 1;
+    thunderstorm.mLandFogNightDepth = 1.15;
+    thunderstorm.mWindSpeed = 0.5;
+    thunderstorm.mCloudSpeed = 3;
+    thunderstorm.mGlareView = 0;
+    thunderstorm.mRainLoopSoundID = "rain heavy";
+    mWeatherSettings["thunderstorm"] = thunderstorm;
+    
+    Weather rain;
+    rain.mCloudTexture = "tx_sky_rainy.dds";
+    rain.mCloudsMaximumPercent = 0.66;
+    rain.mTransitionDelta = 0.015;
+    rain.mSkySunriseColor = clr(71, 74, 75);
+    rain.mSkyDayColor = clr(116, 120, 122);
+    rain.mSkySunsetColor = clr(73, 73, 73);
+    rain.mSkyNightColor = clr(24, 25, 26);
+    rain.mFogSunriseColor = clr(71, 74, 75);
+    rain.mFogDayColor = clr(116, 120, 122);
+    rain.mFogSunsetColor = clr(73, 73, 73);
+    rain.mFogNightColor = clr(24, 25, 26);
+    rain.mAmbientSunriseColor = clr(97, 90, 88);
+    rain.mAmbientDayColor = clr(105, 110, 113);
+    rain.mAmbientSunsetColor = clr(88, 97, 97);
+    rain.mAmbientNightColor = clr(50, 55, 67);
+    rain.mSunSunriseColor = clr(131, 122, 120);
+    rain.mSunDayColor = clr(149, 157, 170);
+    rain.mSunSunsetColor = clr(120, 126, 131);
+    rain.mSunNightColor = clr(50, 62, 101);
+    rain.mSunDiscSunsetColor = clr(128, 128, 128);
+    rain.mLandFogDayDepth = 0.8;
+    rain.mLandFogNightDepth = 0.8;
+    rain.mWindSpeed = 0.3;
+    rain.mCloudSpeed = 2;
+    rain.mGlareView = 0;
+    rain.mRainLoopSoundID = "rain";
+    mWeatherSettings["rain"] = rain;
+    
+    Weather overcast;
+    overcast.mCloudTexture = "tx_sky_overcast.dds";
+    overcast.mCloudsMaximumPercent = 1.0;
+    overcast.mTransitionDelta = 0.015;
+    overcast.mSkySunriseColor = clr(91, 99, 106);
+    overcast.mSkyDayColor = clr(143, 146, 149);
+    overcast.mSkySunsetColor = clr(108, 115, 121);
+    overcast.mSkyNightColor = clr(19, 22, 25);
+    overcast.mFogSunriseColor = clr(91, 99, 106);
+    overcast.mFogDayColor = clr(143, 146, 149);
+    overcast.mFogSunsetColor = clr(108, 115, 121);
+    overcast.mFogNightColor = clr(19, 22, 25);
+    overcast.mAmbientSunriseColor = clr(84, 88, 92);
+    overcast.mAmbientDayColor = clr(93, 96, 105);
+    overcast.mAmbientSunsetColor = clr(83, 77, 75);
+    overcast.mAmbientNightColor = clr(57, 60, 66);
+    overcast.mSunSunriseColor = clr(87, 125, 163);
+    overcast.mSunDayColor = clr(163, 169, 183);
+    overcast.mSunSunsetColor = clr(85, 103, 157);
+    overcast.mSunNightColor = clr(32, 54, 100);
+    overcast.mSunDiscSunsetColor = clr(128, 128, 128);
+    overcast.mLandFogDayDepth = 0.7;
+    overcast.mLandFogNightDepth = 0.7;
+    overcast.mWindSpeed = 0.2;
+    overcast.mCloudSpeed = 1.5;
+    overcast.mGlareView = 0;
+    mWeatherSettings["overcast"] = overcast;
+    
+    Weather ashstorm;
+    ashstorm.mCloudTexture = "tx_sky_ashstorm.dds";
+    ashstorm.mCloudsMaximumPercent = 1.0;
+    ashstorm.mTransitionDelta = 0.035;
+    ashstorm.mSkySunriseColor = clr(91, 56, 51);
+    ashstorm.mSkyDayColor = clr(124, 73, 58);
+    ashstorm.mSkySunsetColor = clr(106, 55, 40);
+    ashstorm.mSkyNightColor = clr(20, 21, 22);
+    ashstorm.mFogSunriseColor = clr(91, 56, 51);
+    ashstorm.mFogDayColor = clr(124, 73, 58);
+    ashstorm.mFogSunsetColor = clr(106, 55, 40);
+    ashstorm.mFogNightColor = clr(20, 21, 22);
+    ashstorm.mAmbientSunriseColor = clr(52, 42, 37);
+    ashstorm.mAmbientDayColor = clr(75, 49, 41);
+    ashstorm.mAmbientSunsetColor = clr(48, 39, 35);
+    ashstorm.mAmbientNightColor = clr(36, 42, 49);
+    ashstorm.mSunSunriseColor = clr(184, 91, 71);
+    ashstorm.mSunDayColor = clr(228, 139, 114);
+    ashstorm.mSunSunsetColor = clr(185, 86, 57);
+    ashstorm.mSunNightColor = clr(54, 66, 74);
+    ashstorm.mSunDiscSunsetColor = clr(128, 128, 128);
+    ashstorm.mLandFogDayDepth = 1.1;
+    ashstorm.mLandFogNightDepth = 1.2;
+    ashstorm.mWindSpeed = 0.8;
+    ashstorm.mCloudSpeed = 7;
+    ashstorm.mGlareView = 0;
+    ashstorm.mAmbientLoopSoundID = "ashstorm";
+    mWeatherSettings["ashstorm"] = ashstorm;
+    
+    Weather blight;
+    blight.mCloudTexture = "tx_sky_blight.dds";
+    blight.mCloudsMaximumPercent = 1.0;
+    blight.mTransitionDelta = 0.04;
+    blight.mSkySunriseColor = clr(90, 35, 35);
+    blight.mSkyDayColor = clr(90, 35, 35);
+    blight.mSkySunsetColor = clr(92, 33, 33);
+    blight.mSkyNightColor = clr(44, 14, 14);
+    blight.mFogSunriseColor = clr(90, 35, 35);
+    blight.mFogDayColor = clr(128, 19, 19);
+    blight.mFogSunsetColor = clr(92, 33, 33);
+    blight.mFogNightColor = clr(44, 14, 14);
+    blight.mAmbientSunriseColor = clr(61, 40, 40);
+    blight.mAmbientDayColor = clr(79, 54, 54);
+    blight.mAmbientSunsetColor = clr(61, 40, 40);
+    blight.mAmbientNightColor = clr(56, 58, 62);
+    blight.mSunSunriseColor = clr(180, 78, 78);
+    blight.mSunDayColor = clr(224, 84, 84);
+    blight.mSunSunsetColor = clr(180, 78, 78);
+    blight.mSunNightColor = clr(61, 91, 143);
+    blight.mSunDiscSunsetColor = clr(128, 128, 128);
+    blight.mLandFogDayDepth = 1.1;
+    blight.mLandFogNightDepth = 1.2;
+    blight.mWindSpeed = 0.9;
+    blight.mCloudSpeed = 9;
+    blight.mGlareView = 0;
+    blight.mAmbientLoopSoundID = "blight";
+    mWeatherSettings["blight"] = blight;
+    
+    Weather snow;
+    snow.mCloudTexture = "tx_bm_sky_snow.dds";
+    snow.mCloudsMaximumPercent = 1.0;
+    snow.mTransitionDelta = 0.014;
+    snow.mSkySunriseColor = clr(196, 91, 91);
+    snow.mSkyDayColor = clr(153, 158, 166);
+    snow.mSkySunsetColor = clr(96, 115, 134);
+    snow.mSkyNightColor = clr(31, 35, 39);
+    snow.mFogSunriseColor = clr(106, 91, 91);
+    snow.mFogDayColor = clr(153, 158, 166);
+    snow.mFogSunsetColor = clr(96, 115, 134);
+    snow.mFogNightColor = clr(31, 35, 39);
+    snow.mAmbientSunriseColor = clr(92, 84, 84);
+    snow.mAmbientDayColor = clr(93, 96, 105);
+    snow.mAmbientSunsetColor = clr(70, 79, 87);
+    snow.mAmbientNightColor = clr(49, 58, 68);
+    snow.mSunSunriseColor = clr(141, 109, 109);
+    snow.mSunDayColor = clr(163, 169, 183);
+    snow.mSunSunsetColor = clr(101, 121, 141);
+    snow.mSunNightColor = clr(55, 66, 77);
+    snow.mSunDiscSunsetColor = clr(128, 128, 128);
+    snow.mLandFogDayDepth = 1.0;
+    snow.mLandFogNightDepth = 1.2;
+    snow.mWindSpeed = 0;
+    snow.mCloudSpeed = 1.5;
+    snow.mGlareView = 0;
+    mWeatherSettings["snow"] = snow;
+    
+    Weather blizzard;
+    blizzard.mCloudTexture = "tx_bm_sky_blizzard.dds";
+    blizzard.mCloudsMaximumPercent = 1.0;
+    blizzard.mTransitionDelta = 0.030;
+    blizzard.mSkySunriseColor = clr(91, 99, 106);
+    blizzard.mSkyDayColor = clr(121, 133, 145);
+    blizzard.mSkySunsetColor = clr(108, 115, 121);
+    blizzard.mSkyNightColor = clr(27, 29, 31);
+    blizzard.mFogSunriseColor = clr(91, 99, 106);
+    blizzard.mFogDayColor = clr(121, 133, 145);
+    blizzard.mFogSunsetColor = clr(108, 115, 121);
+    blizzard.mFogNightColor = clr(21, 24, 28);
+    blizzard.mAmbientSunriseColor = clr(84, 88, 92);
+    blizzard.mAmbientDayColor = clr(93, 96, 105);
+    blizzard.mAmbientSunsetColor = clr(83, 77, 75);
+    blizzard.mAmbientNightColor = clr(53, 62, 70);
+    blizzard.mSunSunriseColor = clr(114, 128, 146);
+    blizzard.mSunDayColor = clr(163, 169, 183);
+    blizzard.mSunSunsetColor = clr(106, 114, 136);
+    blizzard.mSunNightColor = clr(57, 66, 74);
+    blizzard.mSunDiscSunsetColor = clr(128, 128, 128);
+    blizzard.mLandFogDayDepth = 2.8;
+    blizzard.mLandFogNightDepth = 3.0;
+    blizzard.mWindSpeed = 0.9;
+    blizzard.mCloudSpeed = 7.5;
+    blizzard.mGlareView = 0;
+    blizzard.mAmbientLoopSoundID = "BM Blizzard";
+    mWeatherSettings["blizzard"] = blizzard;
+}
+
+void WeatherManager::setWeather(const String& weather, bool instant)
+{
+    if (instant || mFirstUpdate)
+    {
+        mNextWeather = "";
+        mCurrentWeather = weather;
+        mFirstUpdate = false;
+    }
+    else
+    {
+        if (mNextWeather != "")
+        {
+            // transition more than 50% finished?
+            if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60) <= 0.5)
+                mCurrentWeather = mNextWeather;
+        }
+            
+        mNextWeather = weather;
+        mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60;
+    }
+}
+
+WeatherResult WeatherManager::getResult(const String& weather)
+{
+    const Weather& current = mWeatherSettings[weather];
+    WeatherResult result;
+    
+    result.mCloudTexture = current.mCloudTexture;
+    result.mCloudBlendFactor = 0;
+    result.mCloudOpacity = current.mCloudsMaximumPercent;
+    result.mWindSpeed = current.mWindSpeed;
+    result.mCloudSpeed = current.mCloudSpeed;
+    result.mGlareView = current.mGlareView;
+    result.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
+    result.mSunColor = current.mSunDiscSunsetColor;
+    
+    const float fade_duration = current.mTransitionDelta * 24.f;
+    
+    result.mNight = (mHour < 6.f+fade_duration || mHour > 20.f-fade_duration);
+    
+    result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth;
+    
+    // night
+    if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
+        || mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration))
+    {
+        result.mFogColor = current.mFogNightColor;
+        result.mAmbientColor = current.mAmbientNightColor;
+        result.mSunColor = current.mSunNightColor;
+        result.mSkyColor = current.mSkyNightColor;
+        result.mNightFade = 1.f;
+    }
+    
+    // sunrise
+    else if (mHour >= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) && mHour <= WeatherGlobals::mSunriseTime)
+    {
+        if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration))
+        {
+            // fade in
+            float advance = (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration)-mHour;
+            float factor = (advance / fade_duration);
+            result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor);
+            result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor);
+            result.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor);
+            result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor);
+            result.mNightFade = factor;
+        }
+        else if (mHour >= (WeatherGlobals::mSunriseTime-fade_duration))
+        {
+            // fade out
+            float advance = mHour-(WeatherGlobals::mSunriseTime-fade_duration);
+            float factor = advance / fade_duration;
+            result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor);
+            result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor);
+            result.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor);
+            result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor);
+        }
+        else 
+        {
+            result.mFogColor = current.mFogSunriseColor;
+            result.mAmbientColor = current.mAmbientSunriseColor;
+            result.mSunColor = current.mSunSunriseColor;
+            result.mSkyColor = current.mSkySunriseColor;
+        }
+    }
+    
+    // day
+    else if (mHour >= (WeatherGlobals::mSunriseTime) && mHour <= (WeatherGlobals::mSunsetTime))
+    {
+        result.mFogColor = current.mFogDayColor;
+        result.mAmbientColor = current.mAmbientDayColor;
+        result.mSunColor = current.mSunDayColor;
+        result.mSkyColor = current.mSkyDayColor;
+    }
+    
+    // sunset
+    else if (mHour >= (WeatherGlobals::mSunsetTime) && mHour <= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration))
+    {
+        if (mHour <= (WeatherGlobals::mSunsetTime+fade_duration))
+        {
+            // fade in
+            float advance = (WeatherGlobals::mSunsetTime+fade_duration)-mHour;
+            float factor = (advance / fade_duration);
+            result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor);
+            result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor);
+            result.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor);
+            result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor);
+        }
+        else if (mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration))
+        {
+            // fade out
+            float advance = mHour-(WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration);
+            float factor = advance / fade_duration;
+            result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor);
+            result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor);
+            result.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor);
+            result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor);
+            result.mNightFade = factor;
+        }
+        else 
+        {
+            result.mFogColor = current.mFogSunsetColor;
+            result.mAmbientColor = current.mAmbientSunsetColor;
+            result.mSunColor = current.mSunSunsetColor;
+            result.mSkyColor = current.mSkySunsetColor;
+        }
+    }
+    
+    return result;
+}
+
+WeatherResult WeatherManager::transition(float factor)
+{
+    const WeatherResult& current = getResult(mCurrentWeather);
+    const WeatherResult& other = getResult(mNextWeather);
+    WeatherResult result;
+    
+    result.mCloudTexture = current.mCloudTexture;
+    result.mNextCloudTexture = other.mCloudTexture;
+    result.mCloudBlendFactor = factor;
+    
+    result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
+    result.mFogColor = lerp(current.mFogColor, other.mFogColor);
+    result.mSunColor = lerp(current.mSunColor, other.mSunColor);
+    result.mSkyColor = lerp(current.mSkyColor, other.mSkyColor);
+    
+    result.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor);
+    result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor);
+    result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth);
+    result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed);
+    result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed);
+    result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
+    result.mGlareView = lerp(current.mGlareView, other.mGlareView);
+    
+    result.mNight = current.mNight;
+    
+    // sound change behaviour:
+    // if 'other' has a new sound, switch to it after 1/2 of the transition length
+    if (other.mAmbientLoopSoundID != "")
+        result.mAmbientLoopSoundID = factor>0.5 ? other.mAmbientLoopSoundID : current.mAmbientLoopSoundID;
+    // if 'current' has a sound and 'other' does not have a sound, turn off the sound immediately
+    else if (current.mAmbientLoopSoundID != "")
+        result.mAmbientLoopSoundID = "";
+        
+    return result;
+}
+
+void WeatherManager::update(float duration)
+{
+    mWeatherUpdateTime -= duration;
+    if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior())
+    {
+        std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region;
+        boost::algorithm::to_lower(regionstr);
+        
+        if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
+        {
+            mCurrentRegion = regionstr;
+            mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*60.f;
+            
+            std::string weather;
+            
+            if (mRegionOverrides.find(regionstr) != mRegionOverrides.end())
+                weather = mRegionOverrides[regionstr];
+            else
+            {
+                // get weather probabilities for the current region
+                const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr);
+                
+                float clear = region->data.clear/255.f;
+                float cloudy = region->data.cloudy/255.f;
+                float foggy = region->data.foggy/255.f;
+                float overcast = region->data.overcast/255.f;
+                float rain = region->data.rain/255.f;
+                float thunder = region->data.thunder/255.f;
+                float ash = region->data.ash/255.f;
+                float blight = region->data.blight/255.f;
+                float snow = region->data.a/255.f;
+                float blizzard = region->data.b/255.f;
+                
+                // re-scale to 100 percent
+                const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard;
+                            
+                srand(time(NULL));
+                float random = ((rand()%100)/100.f) * total;
+                                
+                if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
+                    weather = "blizzard";
+                else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
+                    weather = "snow";
+                else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear)
+                    weather = "blight";
+                else if (random >= thunder+rain+overcast+foggy+cloudy+clear)
+                    weather = "ashstorm";
+                else if (random >= rain+overcast+foggy+cloudy+clear)
+                    weather = "thunderstorm";
+                else if (random >= overcast+foggy+cloudy+clear)
+                    weather = "rain";
+                else if (random >= foggy+cloudy+clear)
+                    weather = "overcast";
+                else if (random >= cloudy+clear)
+                    weather = "foggy";
+                else if (random >= clear)
+                    weather = "cloudy";
+                else
+                    weather = "clear";
+            }
+            
+            setWeather(weather, false);
+            /*
+            std::cout << "roll result: " << random << std::endl;
+            
+            std::cout << regionstr << " weather probabilities: " << clear << " " << cloudy << " " << foggy << " " 
+                << overcast << " " << rain << " " << thunder << " " << ash << " " << blight << " " << snow << " " 
+                << blizzard << std::endl;
+            
+            std::cout << "New weather : " << weather << std::endl;
+            */
+        }
+                
+        WeatherResult result;
+        
+        if (mNextWeather != "")
+        {
+            mRemainingTransitionTime -= duration;
+            if (mRemainingTransitionTime < 0)
+            {
+                mCurrentWeather = mNextWeather;
+                mNextWeather = "";
+            }
+        }
+        
+        if (mNextWeather != "")
+            result = transition(1-(mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60)));
+        else
+            result = getResult(mCurrentWeather);
+        
+        mRendering->configureFog(result.mFogDepth, result.mFogColor);
+        
+        // disable sun during night
+        if (mHour >= WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration
+            || mHour <= WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
+            mRendering->getSkyManager()->sunDisable();
+        else
+        {
+            // during day, calculate sun angle
+            float height = 1-std::abs(((mHour-13)/7.f));
+            int facing = mHour > 13.f ? 1 : -1;
+            Vector3 final(
+                (1-height)*facing, 
+                (1-height)*facing, 
+                height);
+            mRendering->setSunDirection(final);
+            
+            mRendering->getSkyManager()->sunEnable();
+        }
+        
+        // moon calculations
+        float night;
+        if (mHour >= 14)
+            night = mHour-14;
+        else if (mHour <= 10)
+            night = mHour+10;
+        else
+            night = 0;
+            
+        night /= 20.f;
+        
+        if (night != 0)
+        {
+            float moonHeight = 1-std::abs((night-0.5)*2);
+            int facing = (mHour > 0.f && mHour<12.f) ? 1 : -1;
+            Vector3 masser(
+                (1-moonHeight)*facing, 
+                (1-moonHeight)*facing, 
+                moonHeight);
+            
+            Vector3 secunda(
+                (1-moonHeight)*facing*0.8, 
+                (1-moonHeight)*facing*1.25, 
+                moonHeight);
+            
+            mRendering->getSkyManager()->setMasserDirection(masser);
+            mRendering->getSkyManager()->setSecundaDirection(secunda);
+            mRendering->getSkyManager()->masserEnable();
+            mRendering->getSkyManager()->secundaEnable();
+            
+            float hour_fade;
+            if (mHour >= 7.f && mHour <= 14.f)
+                hour_fade = 1-(mHour-7)/3.f;
+            else if (mHour >= 14 && mHour <= 15.f)
+                hour_fade = mHour-14;
+            else
+                hour_fade = 1;
+            
+            float secunda_angle_fade;
+            float masser_angle_fade;
+            float angle = moonHeight*90.f;
+            
+            if (angle >= 30 && angle <= 50)
+                secunda_angle_fade = (angle-30)/20.f;
+            else if (angle <30)
+                secunda_angle_fade = 0.f;
+            else
+                secunda_angle_fade = 1.f;
+            
+            if (angle >= 40 && angle <= 50)
+                masser_angle_fade = (angle-40)/10.f;
+            else if (angle <40)
+                masser_angle_fade = 0.f;
+            else
+                masser_angle_fade = 1.f;
+                
+            masser_angle_fade *= hour_fade;
+            secunda_angle_fade *= hour_fade;
+            
+            mRendering->getSkyManager()->setMasserFade(masser_angle_fade);
+            mRendering->getSkyManager()->setSecundaFade(secunda_angle_fade);
+        }
+        else
+        {
+            mRendering->getSkyManager()->masserDisable();
+            mRendering->getSkyManager()->secundaDisable();
+        }
+        
+        if (mCurrentWeather == "thunderstorm" && mNextWeather == "")
+        {
+            if (mThunderFlash > 0)
+            {
+                // play the sound after a delay
+                mThunderSoundDelay -= duration;
+                if (mThunderSoundDelay <= 0)
+                {
+                    // pick a random sound
+                    int sound = rand() % 4;
+                    std::string soundname;
+                    if (sound == 0) soundname = WeatherGlobals::mThunderSoundID0;
+                    else if (sound == 1) soundname = WeatherGlobals::mThunderSoundID1;
+                    else if (sound == 2) soundname = WeatherGlobals::mThunderSoundID2;
+                    else if (sound == 3) soundname = WeatherGlobals::mThunderSoundID3;
+                    mEnvironment->mSoundManager->playSound(soundname, 1.0, 1.0);
+                    mThunderSoundDelay = 1000;
+                }
+                
+                mThunderFlash -= duration;
+                if (mThunderFlash > 0)
+                    mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
+                else
+                {
+                    srand(time(NULL));
+                    mThunderChanceNeeded = rand() % 100;
+                    mThunderChance = 0;
+                    mRendering->getSkyManager()->setThunder( 0.f );
+                }
+            }
+            else
+            {
+                // no thunder active
+                mThunderChance += duration*4; // chance increases by 4 percent every second
+                if (mThunderChance >= mThunderChanceNeeded)
+                {
+                    mThunderFlash = WeatherGlobals::mThunderThreshold;
+                    
+                    mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
+                    
+                    mThunderSoundDelay = WeatherGlobals::mThunderSoundDelay;
+                }
+            }
+        }
+        else
+            mRendering->getSkyManager()->setThunder(0.f);
+        
+        mRendering->setAmbientColour(result.mAmbientColor);
+        mRendering->sunEnable();
+        mRendering->setSunColour(result.mSunColor);
+        
+        mRendering->getSkyManager()->setWeather(result);
+    }
+    else
+    {
+        mRendering->sunDisable();
+        mRendering->skyDisable();
+        mRendering->getSkyManager()->setThunder(0.f);
+    }
+}
+
+void WeatherManager::setHour(const float hour)
+{
+    // accelerate a bit for testing
+    /*
+    mHour += 0.005;
+    
+    if (mHour >= 24.f) mHour = 0.f;
+    
+    std::cout << "hour " << mHour << std::endl;
+    */
+    
+    mHour = hour;
+}
+
+void WeatherManager::setDate(const int day, const int month)
+{
+    mDay = day;
+    mMonth = month;
+}
+
+unsigned int WeatherManager::getWeatherID() const
+{
+    // Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather
+    
+    if (mCurrentWeather == "clear")
+        return 0;
+    else if (mCurrentWeather == "cloudy")
+        return 1;
+    else if (mCurrentWeather == "foggy")
+        return 2;
+    else if (mCurrentWeather == "overcast")
+        return 3;
+    else if (mCurrentWeather == "rain")
+        return 4;
+    else if (mCurrentWeather == "thunderstorm")
+        return 5;
+    else if (mCurrentWeather == "ashstorm")
+        return 6;
+    else if (mCurrentWeather == "blight")
+        return 7;
+    else if (mCurrentWeather == "snow")
+        return 8;
+    else if (mCurrentWeather == "blizzard")
+        return 9;
+    
+    else
+        return 0;
+}
+
+void WeatherManager::changeWeather(const std::string& region, const unsigned int id)
+{
+    std::string weather;
+    if (id==0)
+        weather = "clear";
+    else if (id==1)
+        weather = "cloudy";
+    else if (id==2)
+        weather = "foggy";
+    else if (id==3)
+        weather = "overcast";
+    else if (id==4)
+        weather = "rain";
+    else if (id==5)
+        weather = "thunderstorm";
+    else if (id==6)
+        weather = "ashstorm";
+    else if (id==7)
+        weather = "blight";
+    else if (id==8)
+        weather = "snow";
+    else if (id==9)
+        weather = "blizzard";
+    else
+        weather = "clear";
+
+    mRegionOverrides[region] = weather;
+}
diff --git a/libs/openengine/bullet/weather.hpp b/libs/openengine/bullet/weather.hpp
new file mode 100644
index 000000000..9353f7cd1
--- /dev/null
+++ b/libs/openengine/bullet/weather.hpp
@@ -0,0 +1,272 @@
+#ifndef GAME_MWWORLD_WEATHER_H
+#define GAME_MWWORLD_WEATHER_H
+
+#include <OgreString.h>
+#include <OgreColourValue.h>
+
+namespace MWRender
+{
+    class RenderingManager;
+}
+
+namespace MWWorld
+{
+    class Environment;
+    
+    /// Global weather manager properties (according to INI)
+    struct WeatherGlobals
+    {
+        /*
+        [Weather]
+        EnvReduceColor=255,255,255,255
+        LerpCloseColor=037,046,048,255
+        BumpFadeColor=230,239,255,255
+        AlphaReduce=0.35
+        Minimum Time Between Environmental Sounds=1.0
+        Maximum Time Between Environmental Sounds=5.0
+        Sun Glare Fader Max=0.5
+        Sun Glare Fader Angle Max=30.0
+        Sun Glare Fader Color=222,095,039
+        Timescale Clouds=0
+        Precip Gravity=575
+        Hours Between Weather Changes=20
+        Rain Ripples=1
+        Rain Ripple Radius=1024
+        Rain Ripples Per Drop=1
+        Rain Ripple Scale=0.3
+        Rain Ripple Speed=1.0
+        Fog Depth Change Speed=3
+        Sunrise Time=6
+        Sunset Time=18
+        Sunrise Duration=2
+        Sunset Duration=2
+        Sky Pre-Sunrise Time=.5
+        Sky Post-Sunrise Time=1
+        Sky Pre-Sunset Time=1.5
+        Sky Post-Sunset Time=.5
+        Ambient Pre-Sunrise Time=.5
+        Ambient Post-Sunrise Time=2
+        Ambient Pre-Sunset Time=1
+        Ambient Post-Sunset Time=1.25
+        Fog Pre-Sunrise Time=.5
+        Fog Post-Sunrise Time=1
+        Fog Pre-Sunset Time=2
+        Fog Post-Sunset Time=1
+        Sun Pre-Sunrise Time=0
+        Sun Post-Sunrise Time=0
+        Sun Pre-Sunset Time=1
+        Sun Post-Sunset Time=1.25
+        Stars Post-Sunset Start=1
+        Stars Pre-Sunrise Finish=2
+        Stars Fading Duration=2
+        Snow Ripples=0
+        Snow Ripple Radius=1024
+        Snow Ripples Per Flake=1
+        Snow Ripple Scale=0.3
+        Snow Ripple Speed=1.0
+        Snow Gravity Scale=0.1
+        Snow High Kill=700
+        Snow Low Kill=150
+        
+        
+        [Moons]
+        Masser Size=94
+        Masser Fade In Start=14
+        Masser Fade In Finish=15
+        Masser Fade Out Start=7
+        Masser Fade Out Finish=10
+        Masser Axis Offset=35
+        Masser Speed=.5
+        Masser Daily Increment=1
+        Masser Fade Start Angle=50
+        Masser Fade End Angle=40
+        Masser Moon Shadow Early Fade Angle=0.5
+        Secunda Size=40
+        Secunda Fade In Start=14
+        Secunda Fade In Finish=15
+        Secunda Fade Out Start=7
+        Secunda Fade Out Finish=10
+        Secunda Axis Offset=50
+        Secunda Speed=.6
+        Secunda Daily Increment=1.2
+        Secunda Fade Start Angle=50
+        Secunda Fade End Angle=30
+        Secunda Moon Shadow Early Fade Angle=0.5
+        Script Color=255,20,20
+        */
+        
+        static const float mSunriseTime;
+        static const float mSunsetTime;
+        static const float mSunriseDuration;
+        static const float mSunsetDuration;
+        
+        static const float mWeatherUpdateTime;
+        
+        // morrowind sets these per-weather, but since they are only used by 'thunderstorm'
+        // weather setting anyway, we can just as well set them globally
+        static const float mThunderFrequency;
+        static const float mThunderThreshold;
+        static const float mThunderSoundDelay;
+        static const std::string mThunderSoundID0;
+        static const std::string mThunderSoundID1;
+        static const std::string mThunderSoundID2;
+        static const std::string mThunderSoundID3;
+    };
+
+    /// Defines the actual weather that results from weather setting (see below), time of day and weather transition
+    struct WeatherResult
+    {
+        Ogre::String mCloudTexture;
+        Ogre::String mNextCloudTexture;
+        float mCloudBlendFactor;
+        
+        Ogre::ColourValue mFogColor;
+        
+        Ogre::ColourValue mAmbientColor;
+        
+        Ogre::ColourValue mSkyColor;
+        
+        Ogre::ColourValue mSunColor;
+        
+        Ogre::ColourValue mSunDiscColor;
+        
+        float mFogDepth;
+        
+        float mWindSpeed;
+        
+        float mCloudSpeed;
+        
+        float mCloudOpacity;
+        
+        float mGlareView;
+        
+        bool mNight; // use night skybox
+        float mNightFade; // fading factor for night skybox
+        
+        Ogre::String mAmbientLoopSoundID;
+    };
+    
+    
+    /// Defines a single weather setting (according to INI)
+    struct Weather
+    {
+        Ogre::String mCloudTexture;
+        
+        // Sky (atmosphere) colors 
+        Ogre::ColourValue   mSkySunriseColor,
+                            mSkyDayColor,
+                            mSkySunsetColor,
+                            mSkyNightColor;
+        
+        // Fog colors
+        Ogre::ColourValue   mFogSunriseColor,
+                            mFogDayColor,
+                            mFogSunsetColor,
+                            mFogNightColor;
+        
+        // Ambient lighting colors
+        Ogre::ColourValue   mAmbientSunriseColor,
+                            mAmbientDayColor,
+                            mAmbientSunsetColor,
+                            mAmbientNightColor;
+        
+        // Sun (directional) lighting colors
+        Ogre::ColourValue   mSunSunriseColor,
+                            mSunDayColor,
+                            mSunSunsetColor,
+                            mSunNightColor;
+        
+        // Fog depth/density
+        float   mLandFogDayDepth,
+                mLandFogNightDepth;
+        
+        // Color modulation for the sun itself during sunset (not completely sure)
+        Ogre::ColourValue mSunDiscSunsetColor;
+        
+        // Duration of weather transition (in days)
+        float mTransitionDelta;
+        
+        // No idea what this one is used for?
+        float mWindSpeed;
+        
+        // Cloud animation speed multiplier
+        float mCloudSpeed;
+        
+        // Multiplier for clouds transparency
+        float mCloudsMaximumPercent;
+        
+        // Value between 0 and 1, defines the strength of the sun glare effect
+        float mGlareView;
+        
+        // Sound effect
+        // This is used for Blight, Ashstorm and Blizzard (Bloodmoon)
+        Ogre::String mAmbientLoopSoundID;
+        
+        // Rain sound effect
+        Ogre::String mRainLoopSoundID;
+        
+        /// \todo disease chance
+    };
+    
+    ///
+    /// Interface for weather settings
+    ///
+    class WeatherManager
+    {
+    public:
+        WeatherManager(MWRender::RenderingManager*, MWWorld::Environment*);
+        
+        /**
+         * Change the weather in the specified region
+         * @param region that should be changed
+         * @param ID of the weather setting to shift to
+         */
+        void changeWeather(const std::string& region, const unsigned int id);
+        
+        /**
+         * Per-frame update
+         * @param duration
+         */
+        void update(float duration);
+        
+        void setHour(const float hour);
+        
+        void setDate(const int day, const int month);
+        
+        unsigned int getWeatherID() const;
+        
+    private:
+        float mHour;
+        int mDay, mMonth;
+        
+        MWRender::RenderingManager* mRendering;
+        MWWorld::Environment* mEnvironment;
+        
+        std::map<Ogre::String, Weather> mWeatherSettings;
+        
+        std::map<std::string, std::string> mRegionOverrides;
+        
+        Ogre::String mCurrentWeather;
+        Ogre::String mNextWeather;
+        
+        std::string mCurrentRegion;
+        
+        bool mFirstUpdate;
+        
+        float mWeatherUpdateTime;
+        
+        float mRemainingTransitionTime;
+        
+        float mThunderFlash;
+        float mThunderChance;
+        float mThunderChanceNeeded;
+        float mThunderSoundDelay;
+        
+        WeatherResult transition(const float factor);
+        WeatherResult getResult(const Ogre::String& weather);
+        
+        void setWeather(const Ogre::String& weather, bool instant=false);
+    };
+}
+
+#endif // GAME_MWWORLD_WEATHER_H

From e4251be5299c7114a9b3f9053b5bb35706062453 Mon Sep 17 00:00:00 2001
From: Jason Hooks <jhooks1@mix.wvu.edu>
Date: Sun, 25 Mar 2012 15:16:02 -0400
Subject: [PATCH 02/20] Down gravity

---
 apps/openmw/mwworld/physicssystem.cpp |   1 +
 libs/openengine/bullet/pmove.cpp      |  75 +--
 libs/openengine/bullet/trace.cpp      |  10 +-
 libs/openengine/bullet/weather.cpp    | 811 --------------------------
 libs/openengine/bullet/weather.hpp    | 272 ---------
 5 files changed, 46 insertions(+), 1123 deletions(-)
 delete mode 100644 libs/openengine/bullet/weather.cpp
 delete mode 100644 libs/openengine/bullet/weather.hpp

diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp
index d54f4696a..15d2d3f9f 100644
--- a/apps/openmw/mwworld/physicssystem.cpp
+++ b/apps/openmw/mwworld/physicssystem.cpp
@@ -148,6 +148,7 @@ namespace MWWorld
 			if(it->first == "player"){
 				
 				coord = playerphysics->ps.origin;
+				//std::cout << "ZCoord: " << coord.z << "\n";
 				//std::cout << "Coord" << coord << "\n";
 				//coord = Ogre::Vector3(coord.x, coord.z, coord.y);   //x, z, -y
 				
diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 71c15fe45..8dd01ef19 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -178,7 +178,7 @@ bool	PM_SlideMove( bool gravity )
 	float		into;
 	Ogre::Vector3		endVelocity;
 	Ogre::Vector3		endClipVelocity;
-	
+	std::cout << "Slide move\n";
 	numbumps = 4;
 
 	// primal_velocity = pm->ps->velocity
@@ -191,14 +191,14 @@ bool	PM_SlideMove( bool gravity )
 		//VectorCopy( pm->ps->velocity, endVelocity );
 		endVelocity = pm->ps.velocity;
 		//endVelocity[2] -= pm->ps->gravity * pml.frametime;
-		endVelocity.y -= pm->ps.gravity * pml.frametime;
+		endVelocity.z -= pm->ps.gravity * pml.frametime;
 
 		// pm->ps->velocity = avg(pm->ps->velocity.z, endVelocity.z)
 		//pm->ps->velocity[2] = ( pm->ps->velocity[2] + endVelocity[2] ) * 0.5;
-		pm->ps.velocity.y= (pm->ps.velocity.y + endVelocity.y) * 0.5f;
+		pm->ps.velocity.z= (pm->ps.velocity.z + endVelocity.z) * 0.5f;
 
 		//primal_velocity[2] = endVelocity[2];
-		primal_velocity.y = endVelocity.y;
+		primal_velocity.z = endVelocity.z;
 
 		if ( pml.groundPlane ) 
 			// slide along the ground plane
@@ -239,7 +239,7 @@ bool	PM_SlideMove( bool gravity )
 		{
 			// entity is completely trapped in another solid
 			//pm->ps->velocity[2] = 0;	// don't build up falling damage, but allow sideways acceleration
-			pm->ps.velocity.y = 0;
+			pm->ps.velocity.z = 0;
 			return true;
 		}
 
@@ -427,10 +427,11 @@ int PM_StepSlideMove( bool gravity )
 	if ( PM_SlideMove( gravity ) == false )
 		return 1;		// we got exactly where we wanted to go first try	
 
+	std::cout << "Step Slide move\n";
 	// down = start_o - vec3(0, 0, STEPSIZE)
 	//VectorCopy(start_o, down);
 	down = start_o;
-	down.y -= STEPSIZE;
+	down.z -= STEPSIZE;
 
 	//pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
 	//tracefunc(&trace, start_o, down, , 0, pml.scene);
@@ -439,11 +440,11 @@ int PM_StepSlideMove( bool gravity )
 	
 	// up = vec3(0, 0, 1)
 	//VectorSet(up, 0, 0, 1);
-	up = Ogre::Vector3(0.0f, 1.0f, 0.0f);
+	up = Ogre::Vector3(0.0f, 0.0f, 1.0f);
 
 	// never step up when you still have up velocity
 	//if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 || DotProduct(trace.plane.normal, up) < 0.7)) 
-	if (pm->ps.velocity.y > 0 && (
+	if (pm->ps.velocity.z > 0 && (
 		trace.fraction == 1.0 || trace.planenormal.dotProduct(up) < 0.7
 		) )
 		return 2;
@@ -460,7 +461,7 @@ int PM_StepSlideMove( bool gravity )
 	//VectorCopy (start_o, up);
 	up = start_o;
 	//up[2] += STEPSIZE;
-	up.y += STEPSIZE;
+	up.z += STEPSIZE;
 
 	// test the player position if they were a stepheight higher
 	//pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
@@ -475,7 +476,7 @@ int PM_StepSlideMove( bool gravity )
 	}
 
 	//stepSize = trace.endpos[2] - start_o[2];
-	stepSize = trace.endpos.y - start_o.y;
+	stepSize = trace.endpos.z - start_o.z;
 
 	// try slidemove from this position
 	//VectorCopy (trace.endpos, pm->ps->origin); // pm->ps->origin = trace.endpos
@@ -491,7 +492,7 @@ int PM_StepSlideMove( bool gravity )
 	//VectorCopy (pm->ps->origin, down);
 	down = pm->ps.origin;
 	//down[2] -= stepSize;
-	down.y -= stepSize;
+	down.z -= stepSize;
 
 
 	//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
@@ -510,7 +511,7 @@ int PM_StepSlideMove( bool gravity )
 		float	delta;
 
 		//delta = pm->ps->origin[2] - start_o[2];
-		delta = pm->ps.origin.y - start_o.y;
+		delta = pm->ps.origin.z - start_o.z;
 		if ( delta > 2 ) 
 		{
 			if (gravity)
@@ -541,6 +542,7 @@ int PM_StepSlideMove( bool gravity )
 
 void PM_Friction(void)
 {
+	std::cout << "Friction\n";
 	Ogre::Vector3	vec;
 	float* vel;
 	float	speed, newspeed, control;
@@ -554,14 +556,14 @@ void PM_Friction(void)
 
 	if ( pml.walking )
 		//vec[2] = 0;	// ignore slope movement
-		vec.y = 0;
+		vec.z = 0;
 
 	//speed = VectorLength(vec);
 	speed = vec.length();
 	if (speed < 1) 
 	{
 		vel[0] = 0;
-		vel[2] = 0;		// allow sinking underwater
+		vel[1] = 0;		// allow sinking underwater
 		// FIXME: still have z friction underwater?
 		//bprintf("Static friction (vec = [%f, %f, %f]) (vec.length = %f)\n", vec.x, vec.y, vec.z, speed);
 		return;
@@ -636,6 +638,7 @@ static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel
 {
 //	int			i;
 	float		addspeed, accelspeed, currentspeed;
+	std::cout << "Accelerate\n";
 
 	// currentspeed = pm->ps->velocity dot wishdir
 	//currentspeed = DotProduct (pm->ps->velocity, wishdir);
@@ -681,7 +684,7 @@ static bool PM_CheckJump(void)
 	//pm->ps->pm_flags |= PMF_JUMP_HELD;
 
 	pm->ps.groundEntityNum = ENTITYNUM_NONE;
-	pm->ps.velocity.y = JUMP_VELOCITY;
+	pm->ps.velocity.z = JUMP_VELOCITY;
 	//PM_AddEvent( EV_JUMP );
 
 	/*if ( pm->cmd.forwardmove >= 0 ) 
@@ -776,8 +779,8 @@ static void PM_WaterMove( playerMove* const pm )
 		wishvel[2] = -60;		// sink towards bottom
 		*/
 		wishvel.x = 0;
-		wishvel.y = -60;
-		wishvel.z = 0;
+		wishvel.z = -60;
+		wishvel.y = 0;
 	} 
 	else 
 	{
@@ -834,6 +837,7 @@ static void PM_WalkMove( playerMove* const pmove )
 	playerMove::playercmd cmd;
 	float		accelerate;
 	float		vel;
+	std::cout << "Walking\n";
 
 	if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) 
 		pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f)
@@ -937,10 +941,10 @@ static void PM_WalkMove( playerMove* const pmove )
 
 	// project moves down to flat plane
 	//pml.forward[2] = 0;
-	pml.forward.y = 0;
+	pml.forward.z = 0;
 
 	//pml.right[2] = 0;
-	pml.right.y = 0;
+	pml.right.z = 0;
 
 	// project the forward and right directions onto the ground plane
 	PM_ClipVelocity (pml.forward, pml.groundTrace.planenormal, pml.forward, OVERCLIP );
@@ -1035,7 +1039,7 @@ void PM_UpdateViewAngles( playerMove::playerStruct* const ps, playerMove::player
 {
 	short		temp;
 	int		i;
-
+	std::cout << "Updating viewangles\n";
 	//while(1);
 
 	//if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPINTERMISSION) 
@@ -1128,7 +1132,7 @@ void PM_GroundTraceMissed()
 		//VectorCopy( pm->ps->origin, point );
 		point = pm->ps.origin;
 		//point[2] -= 64;
-		point.y -= 64;
+		point.z -= 64;
 
 		//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
 		//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -64.0f, 0.0f), 0, pml.traceObj);
@@ -1188,7 +1192,7 @@ static bool PM_CorrectAllSolid(traceResults* const trace)
 					point[1] = pm->ps->origin[1];
 					point[2] = pm->ps->origin[2] - 0.25;*/
 					point = pm->ps.origin;
-					point.y -= 0.25f;
+					point.z -= 0.25f;
 
 					//pm->trace (trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
 					//tracefunc(trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj);
@@ -1215,7 +1219,7 @@ static void PM_CrashLand( void )
 	float		vel, acc;
 	float		t;
 	float		a, b, c, den;
-
+	std::cout << "Crash land\n";
 	// decide which landing animation to use
 	/*if ( pm->ps->pm_flags & PMF_BACKWARDS_JUMP ) 
 		PM_ForceLegsAnim( LEGS_LANDB );
@@ -1227,10 +1231,10 @@ static void PM_CrashLand( void )
 	// calculate the exact velocity on landing
 	//dist = pm->ps->origin[2] - pml.previous_origin[2];
 
-	dist = pm->ps.origin.y - pml.previous_origin.y;
+	dist = pm->ps.origin.z - pml.previous_origin.z;
 
 	//vel = pml.previous_velocity[2];
-	vel = pml.previous_velocity.y;
+	vel = pml.previous_velocity.z;
 
 	//acc = -pm->ps->gravity;
 	acc = -pm->ps.gravity;
@@ -1294,7 +1298,7 @@ static void PM_CrashLand( void )
 				
 					const float waterHeight = pm->waterHeight;
 					const float waterHeightSplash = waterHeight + halfExtents.y;
-					if (pm->ps.origin.y < waterHeightSplash)
+					if (pm->ps.origin.z < waterHeightSplash)
 					{
 						splashSound = true;
 					}
@@ -1357,7 +1361,7 @@ static void PM_CrashLand( void )
 
 static void PM_GroundTrace( void ) 
 {
-	//std::cout << "Ground trace\n";
+	std::cout << "Ground trace\n";
 	Ogre::Vector3		point;
 	traceResults		trace;
 
@@ -1365,7 +1369,7 @@ static void PM_GroundTrace( void )
 	point[1] = pm->ps->origin[1];
 	point[2] = pm->ps->origin[2] - 0.25;*/
 	point = pm->ps.origin;
-	point.y -= 0.25f;
+	point.z -= 0.25f;
 
 	//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
 	//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj);
@@ -1392,7 +1396,7 @@ static void PM_GroundTrace( void )
 
 	// check if getting thrown off the ground
 	//if ( pm->ps->velocity[2] > 0 && DotProduct( pm->ps->velocity, trace.plane.normal ) > 10 ) 
-	if (pm->ps.velocity.y > 0 && pm->ps.velocity.dotProduct(trace.planenormal) > 10.0f)
+	if (pm->ps.velocity.z > 0 && pm->ps.velocity.dotProduct(trace.planenormal) > 10.0f)
 	{
 		//if ( pm->debugLevel ) 
 			//Com_Printf("%i:kickoff\n", c_pmove);
@@ -1417,7 +1421,7 @@ static void PM_GroundTrace( void )
 	
 	// slopes that are too steep will not be considered onground
 	//if ( trace.plane.normal[2] < MIN_WALK_NORMAL ) 
-	if (trace.planenormal.y < MIN_WALK_NORMAL)
+	if (trace.planenormal.z < MIN_WALK_NORMAL)
 	{
 		//if ( pm->debugLevel )
 			//Com_Printf("%i:steep\n", c_pmove);
@@ -1451,7 +1455,7 @@ static void PM_GroundTrace( void )
 
 		// don't do landing time if we were just going down a slope
 		//if ( pml.previous_velocity[2] < -200 ) 
-		if (pml.previous_velocity.y < -200)
+		if (pml.previous_velocity.z < -200)
 		{
 			// don't allow another jump for a little while
 			//pm->ps->pm_flags |= PMF_TIME_LAND;
@@ -1469,6 +1473,7 @@ static void PM_GroundTrace( void )
 
 static void PM_AirMove()
 {
+	std::cout << "Air move\n";
 	//int			i;
 	Ogre::Vector3		wishvel;
 	float		fmove, smove;
@@ -1490,7 +1495,7 @@ static void PM_AirMove()
 
 	// project moves down to flat plane
 	//pml.forward[2] = 0;
-	pml.forward.y = 0;
+	pml.forward.y = 0;             //Z or Y?
 	//pml.right[2] = 0;
 	pml.right.y = 0;
 	//VectorNormalize (pml.forward);
@@ -1503,7 +1508,7 @@ static void PM_AirMove()
 	wishvel = pml.forward * fmove + pml.right * smove;
 
 	//wishvel[2] = 0;
-	wishvel.y = 0;
+	wishvel.z = 0;
 
 	//VectorCopy (wishvel, wishdir);
 	wishdir = wishvel;
@@ -1659,7 +1664,7 @@ static void PM_FlyMove( void )
 		wishvel = pml.forward * scale * pm->cmd.forwardmove + pml.right * scale * pm->cmd.rightmove;
 
 		//wishvel[2] += scale * pm->cmd.upmove;
-		wishvel.y += /*6.35f * */pm->cmd.upmove * scale;
+		wishvel.z += /*6.35f * */pm->cmd.upmove * scale;
 	}
 
 	//VectorCopy (wishvel, wishdir);
@@ -1939,7 +1944,7 @@ void PmoveSingle (playerMove* const pmove)
 		PM_WaterMove(pmove);
 	else if ( pml.walking ) 
 	{
-		std::cout << "WALKING\n";
+		
 		// walking on ground
 		PM_WalkMove(pmove);
 		//bprintf("WalkMove\n");
diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp
index 57d071f17..8f2423c24 100644
--- a/libs/openengine/bullet/trace.cpp
+++ b/libs/openengine/bullet/trace.cpp
@@ -28,11 +28,11 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr
 
 	NewPhysTraceResults out;
 	//std::cout << "Starting trace\n";
-	Ogre::Vector3 startReplace = Ogre::Vector3(650,950, 45);
-	Ogre::Vector3 endReplace = startReplace;
-	endReplace.y -= .25;
+	//Ogre::Vector3 startReplace = Ogre::Vector3(650,950, 45);
+	//Ogre::Vector3 endReplace = startReplace;
+	//endReplace.z -= .25;
 	
-	const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, rotation, 0.0f), isInterior, enginePass);
+	const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0f, rotation), isInterior, enginePass);
 	if(hasHit)
 		std::cout << "Has hit\n";
 	if (out.fraction < 0.001f)
@@ -65,7 +65,7 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr
 	if (!hasHit)
 	{
 		results->endpos = end;
-		results->planenormal = Ogre::Vector3(0.0f, 1.0f, 0.0f);
+		results->planenormal = Ogre::Vector3(0.0f, 0.0f, 1.0f);
 		results->entityNum = ENTITYNUM_NONE;
 		results->fraction = 1.0f;
 	}
diff --git a/libs/openengine/bullet/weather.cpp b/libs/openengine/bullet/weather.cpp
deleted file mode 100644
index 90afc4e78..000000000
--- a/libs/openengine/bullet/weather.cpp
+++ /dev/null
@@ -1,811 +0,0 @@
-#include "weather.hpp"
-#include "world.hpp"
-#include "player.hpp"
-
-#include "../mwrender/renderingmanager.hpp"
-#include "../mwsound/soundmanager.hpp"
-
-#include <ctime>
-#include <cstdlib>
-#include <iostream>
-
-#include <boost/algorithm/string.hpp>   
-
-using namespace Ogre;
-using namespace MWWorld;
-using namespace MWSound;
-
-#define lerp(x, y) (x * (1-factor) + y * factor)
-
-const std::string WeatherGlobals::mThunderSoundID0 = "Thunder0";
-const std::string WeatherGlobals::mThunderSoundID1 = "Thunder1";
-const std::string WeatherGlobals::mThunderSoundID2 = "Thunder2";
-const std::string WeatherGlobals::mThunderSoundID3 = "Thunder3";
-const float WeatherGlobals::mSunriseTime = 8;
-const float WeatherGlobals::mSunsetTime = 18;
-const float WeatherGlobals::mSunriseDuration = 2;
-const float WeatherGlobals::mSunsetDuration = 2;
-const float WeatherGlobals::mWeatherUpdateTime = 20.f;
-const float WeatherGlobals::mThunderFrequency = .4;
-const float WeatherGlobals::mThunderThreshold = 0.6;
-const float WeatherGlobals::mThunderSoundDelay = 0.25;
-
-WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) : 
-     mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
-     mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0)
-{
-    mRendering = rendering;
-    mEnvironment = env;
-    
-    #define clr(r,g,b) ColourValue(r/255.f, g/255.f, b/255.f)
-    
-    /// \todo read these from Morrowind.ini
-    Weather clear;
-    clear.mCloudTexture = "tx_sky_clear.dds";
-    clear.mCloudsMaximumPercent = 1.0;
-    clear.mTransitionDelta = 0.015;
-    clear.mSkySunriseColor = clr(118, 141, 164);
-    clear.mSkyDayColor = clr(95, 135, 203);
-    clear.mSkySunsetColor = clr(56, 89, 129);
-    clear.mSkyNightColor = clr(9, 10, 11);
-    clear.mFogSunriseColor = clr(255, 189, 157);
-    clear.mFogDayColor = clr(206, 227, 255);
-    clear.mFogSunsetColor = clr(255, 189, 157);
-    clear.mFogNightColor = clr(9, 10, 11);
-    clear.mAmbientSunriseColor = clr(47, 66, 96);
-    clear.mAmbientDayColor = clr(137, 140, 160);
-    clear.mAmbientSunsetColor = clr(68, 75, 96);
-    clear.mAmbientNightColor = clr(32, 35, 42);
-    clear.mSunSunriseColor = clr(242, 159, 99);
-    clear.mSunDayColor = clr(255, 252, 238);
-    clear.mSunSunsetColor = clr(255, 115, 79);
-    clear.mSunNightColor = clr(59, 97, 176);
-    clear.mSunDiscSunsetColor = clr(255, 189, 157);
-    clear.mLandFogDayDepth = 0.69;
-    clear.mLandFogNightDepth = 0.69;
-    clear.mWindSpeed = 0.1;
-    clear.mCloudSpeed = 1.25;
-    clear.mGlareView = 1.0;
-    mWeatherSettings["clear"] = clear;
-    
-    Weather cloudy;
-    cloudy.mCloudTexture = "tx_sky_cloudy.dds";
-    cloudy.mCloudsMaximumPercent = 1.0;
-    cloudy.mTransitionDelta = 0.015;
-    cloudy.mSkySunriseColor = clr(126, 158, 173);
-    cloudy.mSkyDayColor = clr(117, 160, 215);
-    cloudy.mSkySunsetColor = clr(111, 114, 159);
-    cloudy.mSkyNightColor = clr(9, 10, 11);
-    cloudy.mFogSunriseColor = clr(255, 207, 149);
-    cloudy.mFogDayColor = clr(245, 235, 224);
-    cloudy.mFogSunsetColor = clr(255, 155, 106);
-    cloudy.mFogNightColor = clr(9, 10, 11);
-    cloudy.mAmbientSunriseColor = clr(66, 74, 87);
-    cloudy.mAmbientDayColor = clr(137, 145, 160);
-    cloudy.mAmbientSunsetColor = clr(71, 80, 92);
-    cloudy.mAmbientNightColor = clr(32, 39, 54);
-    cloudy.mSunSunriseColor = clr(241, 177, 99);
-    cloudy.mSunDayColor = clr(255, 236, 221);
-    cloudy.mSunSunsetColor = clr(255, 89, 00);
-    cloudy.mSunNightColor = clr(77, 91, 124);
-    cloudy.mSunDiscSunsetColor = clr(255, 202, 179);
-    cloudy.mLandFogDayDepth = 0.72;
-    cloudy.mLandFogNightDepth = 0.72;
-    cloudy.mWindSpeed = 0.2;
-    cloudy.mCloudSpeed = 2;
-    cloudy.mGlareView = 1.0;
-    mWeatherSettings["cloudy"] = cloudy;
-    
-    Weather foggy;
-    foggy.mCloudTexture = "tx_sky_foggy.dds";
-    foggy.mCloudsMaximumPercent = 1.0;
-    foggy.mTransitionDelta = 0.015;
-    foggy.mSkySunriseColor = clr(197, 190, 180);
-    foggy.mSkyDayColor = clr(184, 211, 228);
-    foggy.mSkySunsetColor = clr(142, 159, 176);
-    foggy.mSkyNightColor = clr(18, 23, 28);
-    foggy.mFogSunriseColor = clr(173, 164, 148);
-    foggy.mFogDayColor = clr(150, 187, 209);
-    foggy.mFogSunsetColor = clr(113, 135, 157);
-    foggy.mFogNightColor = clr(19, 24, 29);
-    foggy.mAmbientSunriseColor = clr(48, 43, 37);
-    foggy.mAmbientDayColor = clr(92, 109, 120);
-    foggy.mAmbientSunsetColor = clr(28, 33, 39);
-    foggy.mAmbientNightColor = clr(28, 33, 39);
-    foggy.mSunSunriseColor = clr(177, 162, 137);
-    foggy.mSunDayColor = clr(111, 131, 151);
-    foggy.mSunSunsetColor = clr(125, 157, 189);
-    foggy.mSunNightColor = clr(81, 100, 119);
-    foggy.mSunDiscSunsetColor = clr(223, 223, 223);
-    foggy.mLandFogDayDepth = 1.0;
-    foggy.mLandFogNightDepth = 1.9;
-    foggy.mWindSpeed = 0;
-    foggy.mCloudSpeed = 1.25;
-    foggy.mGlareView = 0.25;
-    mWeatherSettings["foggy"] = foggy;
-    
-    Weather thunderstorm;
-    thunderstorm.mCloudTexture = "tx_sky_thunder.dds";
-    thunderstorm.mCloudsMaximumPercent = 0.66;
-    thunderstorm.mTransitionDelta = 0.03;
-    thunderstorm.mSkySunriseColor = clr(35, 36, 39);
-    thunderstorm.mSkyDayColor = clr(97, 104, 115);
-    thunderstorm.mSkySunsetColor = clr(35, 36, 39);
-    thunderstorm.mSkyNightColor = clr(19, 20, 22);
-    thunderstorm.mFogSunriseColor = clr(70, 74, 85);
-    thunderstorm.mFogDayColor = clr(97, 104, 115);
-    thunderstorm.mFogSunsetColor = clr(70, 74, 85);
-    thunderstorm.mFogNightColor = clr(19, 20, 22);
-    thunderstorm.mAmbientSunriseColor = clr(54, 54, 54);
-    thunderstorm.mAmbientDayColor = clr(90, 90, 90);
-    thunderstorm.mAmbientSunsetColor = clr(54, 54, 54);
-    thunderstorm.mAmbientNightColor = clr(49, 51, 54);
-    thunderstorm.mSunSunriseColor = clr(91, 99, 122);
-    thunderstorm.mSunDayColor = clr(138, 144, 155);
-    thunderstorm.mSunSunsetColor = clr(96, 101, 117);
-    thunderstorm.mSunNightColor = clr(55, 76, 110);
-    thunderstorm.mSunDiscSunsetColor = clr(128, 128, 128);
-    thunderstorm.mLandFogDayDepth = 1;
-    thunderstorm.mLandFogNightDepth = 1.15;
-    thunderstorm.mWindSpeed = 0.5;
-    thunderstorm.mCloudSpeed = 3;
-    thunderstorm.mGlareView = 0;
-    thunderstorm.mRainLoopSoundID = "rain heavy";
-    mWeatherSettings["thunderstorm"] = thunderstorm;
-    
-    Weather rain;
-    rain.mCloudTexture = "tx_sky_rainy.dds";
-    rain.mCloudsMaximumPercent = 0.66;
-    rain.mTransitionDelta = 0.015;
-    rain.mSkySunriseColor = clr(71, 74, 75);
-    rain.mSkyDayColor = clr(116, 120, 122);
-    rain.mSkySunsetColor = clr(73, 73, 73);
-    rain.mSkyNightColor = clr(24, 25, 26);
-    rain.mFogSunriseColor = clr(71, 74, 75);
-    rain.mFogDayColor = clr(116, 120, 122);
-    rain.mFogSunsetColor = clr(73, 73, 73);
-    rain.mFogNightColor = clr(24, 25, 26);
-    rain.mAmbientSunriseColor = clr(97, 90, 88);
-    rain.mAmbientDayColor = clr(105, 110, 113);
-    rain.mAmbientSunsetColor = clr(88, 97, 97);
-    rain.mAmbientNightColor = clr(50, 55, 67);
-    rain.mSunSunriseColor = clr(131, 122, 120);
-    rain.mSunDayColor = clr(149, 157, 170);
-    rain.mSunSunsetColor = clr(120, 126, 131);
-    rain.mSunNightColor = clr(50, 62, 101);
-    rain.mSunDiscSunsetColor = clr(128, 128, 128);
-    rain.mLandFogDayDepth = 0.8;
-    rain.mLandFogNightDepth = 0.8;
-    rain.mWindSpeed = 0.3;
-    rain.mCloudSpeed = 2;
-    rain.mGlareView = 0;
-    rain.mRainLoopSoundID = "rain";
-    mWeatherSettings["rain"] = rain;
-    
-    Weather overcast;
-    overcast.mCloudTexture = "tx_sky_overcast.dds";
-    overcast.mCloudsMaximumPercent = 1.0;
-    overcast.mTransitionDelta = 0.015;
-    overcast.mSkySunriseColor = clr(91, 99, 106);
-    overcast.mSkyDayColor = clr(143, 146, 149);
-    overcast.mSkySunsetColor = clr(108, 115, 121);
-    overcast.mSkyNightColor = clr(19, 22, 25);
-    overcast.mFogSunriseColor = clr(91, 99, 106);
-    overcast.mFogDayColor = clr(143, 146, 149);
-    overcast.mFogSunsetColor = clr(108, 115, 121);
-    overcast.mFogNightColor = clr(19, 22, 25);
-    overcast.mAmbientSunriseColor = clr(84, 88, 92);
-    overcast.mAmbientDayColor = clr(93, 96, 105);
-    overcast.mAmbientSunsetColor = clr(83, 77, 75);
-    overcast.mAmbientNightColor = clr(57, 60, 66);
-    overcast.mSunSunriseColor = clr(87, 125, 163);
-    overcast.mSunDayColor = clr(163, 169, 183);
-    overcast.mSunSunsetColor = clr(85, 103, 157);
-    overcast.mSunNightColor = clr(32, 54, 100);
-    overcast.mSunDiscSunsetColor = clr(128, 128, 128);
-    overcast.mLandFogDayDepth = 0.7;
-    overcast.mLandFogNightDepth = 0.7;
-    overcast.mWindSpeed = 0.2;
-    overcast.mCloudSpeed = 1.5;
-    overcast.mGlareView = 0;
-    mWeatherSettings["overcast"] = overcast;
-    
-    Weather ashstorm;
-    ashstorm.mCloudTexture = "tx_sky_ashstorm.dds";
-    ashstorm.mCloudsMaximumPercent = 1.0;
-    ashstorm.mTransitionDelta = 0.035;
-    ashstorm.mSkySunriseColor = clr(91, 56, 51);
-    ashstorm.mSkyDayColor = clr(124, 73, 58);
-    ashstorm.mSkySunsetColor = clr(106, 55, 40);
-    ashstorm.mSkyNightColor = clr(20, 21, 22);
-    ashstorm.mFogSunriseColor = clr(91, 56, 51);
-    ashstorm.mFogDayColor = clr(124, 73, 58);
-    ashstorm.mFogSunsetColor = clr(106, 55, 40);
-    ashstorm.mFogNightColor = clr(20, 21, 22);
-    ashstorm.mAmbientSunriseColor = clr(52, 42, 37);
-    ashstorm.mAmbientDayColor = clr(75, 49, 41);
-    ashstorm.mAmbientSunsetColor = clr(48, 39, 35);
-    ashstorm.mAmbientNightColor = clr(36, 42, 49);
-    ashstorm.mSunSunriseColor = clr(184, 91, 71);
-    ashstorm.mSunDayColor = clr(228, 139, 114);
-    ashstorm.mSunSunsetColor = clr(185, 86, 57);
-    ashstorm.mSunNightColor = clr(54, 66, 74);
-    ashstorm.mSunDiscSunsetColor = clr(128, 128, 128);
-    ashstorm.mLandFogDayDepth = 1.1;
-    ashstorm.mLandFogNightDepth = 1.2;
-    ashstorm.mWindSpeed = 0.8;
-    ashstorm.mCloudSpeed = 7;
-    ashstorm.mGlareView = 0;
-    ashstorm.mAmbientLoopSoundID = "ashstorm";
-    mWeatherSettings["ashstorm"] = ashstorm;
-    
-    Weather blight;
-    blight.mCloudTexture = "tx_sky_blight.dds";
-    blight.mCloudsMaximumPercent = 1.0;
-    blight.mTransitionDelta = 0.04;
-    blight.mSkySunriseColor = clr(90, 35, 35);
-    blight.mSkyDayColor = clr(90, 35, 35);
-    blight.mSkySunsetColor = clr(92, 33, 33);
-    blight.mSkyNightColor = clr(44, 14, 14);
-    blight.mFogSunriseColor = clr(90, 35, 35);
-    blight.mFogDayColor = clr(128, 19, 19);
-    blight.mFogSunsetColor = clr(92, 33, 33);
-    blight.mFogNightColor = clr(44, 14, 14);
-    blight.mAmbientSunriseColor = clr(61, 40, 40);
-    blight.mAmbientDayColor = clr(79, 54, 54);
-    blight.mAmbientSunsetColor = clr(61, 40, 40);
-    blight.mAmbientNightColor = clr(56, 58, 62);
-    blight.mSunSunriseColor = clr(180, 78, 78);
-    blight.mSunDayColor = clr(224, 84, 84);
-    blight.mSunSunsetColor = clr(180, 78, 78);
-    blight.mSunNightColor = clr(61, 91, 143);
-    blight.mSunDiscSunsetColor = clr(128, 128, 128);
-    blight.mLandFogDayDepth = 1.1;
-    blight.mLandFogNightDepth = 1.2;
-    blight.mWindSpeed = 0.9;
-    blight.mCloudSpeed = 9;
-    blight.mGlareView = 0;
-    blight.mAmbientLoopSoundID = "blight";
-    mWeatherSettings["blight"] = blight;
-    
-    Weather snow;
-    snow.mCloudTexture = "tx_bm_sky_snow.dds";
-    snow.mCloudsMaximumPercent = 1.0;
-    snow.mTransitionDelta = 0.014;
-    snow.mSkySunriseColor = clr(196, 91, 91);
-    snow.mSkyDayColor = clr(153, 158, 166);
-    snow.mSkySunsetColor = clr(96, 115, 134);
-    snow.mSkyNightColor = clr(31, 35, 39);
-    snow.mFogSunriseColor = clr(106, 91, 91);
-    snow.mFogDayColor = clr(153, 158, 166);
-    snow.mFogSunsetColor = clr(96, 115, 134);
-    snow.mFogNightColor = clr(31, 35, 39);
-    snow.mAmbientSunriseColor = clr(92, 84, 84);
-    snow.mAmbientDayColor = clr(93, 96, 105);
-    snow.mAmbientSunsetColor = clr(70, 79, 87);
-    snow.mAmbientNightColor = clr(49, 58, 68);
-    snow.mSunSunriseColor = clr(141, 109, 109);
-    snow.mSunDayColor = clr(163, 169, 183);
-    snow.mSunSunsetColor = clr(101, 121, 141);
-    snow.mSunNightColor = clr(55, 66, 77);
-    snow.mSunDiscSunsetColor = clr(128, 128, 128);
-    snow.mLandFogDayDepth = 1.0;
-    snow.mLandFogNightDepth = 1.2;
-    snow.mWindSpeed = 0;
-    snow.mCloudSpeed = 1.5;
-    snow.mGlareView = 0;
-    mWeatherSettings["snow"] = snow;
-    
-    Weather blizzard;
-    blizzard.mCloudTexture = "tx_bm_sky_blizzard.dds";
-    blizzard.mCloudsMaximumPercent = 1.0;
-    blizzard.mTransitionDelta = 0.030;
-    blizzard.mSkySunriseColor = clr(91, 99, 106);
-    blizzard.mSkyDayColor = clr(121, 133, 145);
-    blizzard.mSkySunsetColor = clr(108, 115, 121);
-    blizzard.mSkyNightColor = clr(27, 29, 31);
-    blizzard.mFogSunriseColor = clr(91, 99, 106);
-    blizzard.mFogDayColor = clr(121, 133, 145);
-    blizzard.mFogSunsetColor = clr(108, 115, 121);
-    blizzard.mFogNightColor = clr(21, 24, 28);
-    blizzard.mAmbientSunriseColor = clr(84, 88, 92);
-    blizzard.mAmbientDayColor = clr(93, 96, 105);
-    blizzard.mAmbientSunsetColor = clr(83, 77, 75);
-    blizzard.mAmbientNightColor = clr(53, 62, 70);
-    blizzard.mSunSunriseColor = clr(114, 128, 146);
-    blizzard.mSunDayColor = clr(163, 169, 183);
-    blizzard.mSunSunsetColor = clr(106, 114, 136);
-    blizzard.mSunNightColor = clr(57, 66, 74);
-    blizzard.mSunDiscSunsetColor = clr(128, 128, 128);
-    blizzard.mLandFogDayDepth = 2.8;
-    blizzard.mLandFogNightDepth = 3.0;
-    blizzard.mWindSpeed = 0.9;
-    blizzard.mCloudSpeed = 7.5;
-    blizzard.mGlareView = 0;
-    blizzard.mAmbientLoopSoundID = "BM Blizzard";
-    mWeatherSettings["blizzard"] = blizzard;
-}
-
-void WeatherManager::setWeather(const String& weather, bool instant)
-{
-    if (instant || mFirstUpdate)
-    {
-        mNextWeather = "";
-        mCurrentWeather = weather;
-        mFirstUpdate = false;
-    }
-    else
-    {
-        if (mNextWeather != "")
-        {
-            // transition more than 50% finished?
-            if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60) <= 0.5)
-                mCurrentWeather = mNextWeather;
-        }
-            
-        mNextWeather = weather;
-        mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60;
-    }
-}
-
-WeatherResult WeatherManager::getResult(const String& weather)
-{
-    const Weather& current = mWeatherSettings[weather];
-    WeatherResult result;
-    
-    result.mCloudTexture = current.mCloudTexture;
-    result.mCloudBlendFactor = 0;
-    result.mCloudOpacity = current.mCloudsMaximumPercent;
-    result.mWindSpeed = current.mWindSpeed;
-    result.mCloudSpeed = current.mCloudSpeed;
-    result.mGlareView = current.mGlareView;
-    result.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
-    result.mSunColor = current.mSunDiscSunsetColor;
-    
-    const float fade_duration = current.mTransitionDelta * 24.f;
-    
-    result.mNight = (mHour < 6.f+fade_duration || mHour > 20.f-fade_duration);
-    
-    result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth;
-    
-    // night
-    if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
-        || mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration))
-    {
-        result.mFogColor = current.mFogNightColor;
-        result.mAmbientColor = current.mAmbientNightColor;
-        result.mSunColor = current.mSunNightColor;
-        result.mSkyColor = current.mSkyNightColor;
-        result.mNightFade = 1.f;
-    }
-    
-    // sunrise
-    else if (mHour >= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) && mHour <= WeatherGlobals::mSunriseTime)
-    {
-        if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration))
-        {
-            // fade in
-            float advance = (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration)-mHour;
-            float factor = (advance / fade_duration);
-            result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor);
-            result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor);
-            result.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor);
-            result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor);
-            result.mNightFade = factor;
-        }
-        else if (mHour >= (WeatherGlobals::mSunriseTime-fade_duration))
-        {
-            // fade out
-            float advance = mHour-(WeatherGlobals::mSunriseTime-fade_duration);
-            float factor = advance / fade_duration;
-            result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor);
-            result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor);
-            result.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor);
-            result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor);
-        }
-        else 
-        {
-            result.mFogColor = current.mFogSunriseColor;
-            result.mAmbientColor = current.mAmbientSunriseColor;
-            result.mSunColor = current.mSunSunriseColor;
-            result.mSkyColor = current.mSkySunriseColor;
-        }
-    }
-    
-    // day
-    else if (mHour >= (WeatherGlobals::mSunriseTime) && mHour <= (WeatherGlobals::mSunsetTime))
-    {
-        result.mFogColor = current.mFogDayColor;
-        result.mAmbientColor = current.mAmbientDayColor;
-        result.mSunColor = current.mSunDayColor;
-        result.mSkyColor = current.mSkyDayColor;
-    }
-    
-    // sunset
-    else if (mHour >= (WeatherGlobals::mSunsetTime) && mHour <= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration))
-    {
-        if (mHour <= (WeatherGlobals::mSunsetTime+fade_duration))
-        {
-            // fade in
-            float advance = (WeatherGlobals::mSunsetTime+fade_duration)-mHour;
-            float factor = (advance / fade_duration);
-            result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor);
-            result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor);
-            result.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor);
-            result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor);
-        }
-        else if (mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration))
-        {
-            // fade out
-            float advance = mHour-(WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration);
-            float factor = advance / fade_duration;
-            result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor);
-            result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor);
-            result.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor);
-            result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor);
-            result.mNightFade = factor;
-        }
-        else 
-        {
-            result.mFogColor = current.mFogSunsetColor;
-            result.mAmbientColor = current.mAmbientSunsetColor;
-            result.mSunColor = current.mSunSunsetColor;
-            result.mSkyColor = current.mSkySunsetColor;
-        }
-    }
-    
-    return result;
-}
-
-WeatherResult WeatherManager::transition(float factor)
-{
-    const WeatherResult& current = getResult(mCurrentWeather);
-    const WeatherResult& other = getResult(mNextWeather);
-    WeatherResult result;
-    
-    result.mCloudTexture = current.mCloudTexture;
-    result.mNextCloudTexture = other.mCloudTexture;
-    result.mCloudBlendFactor = factor;
-    
-    result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
-    result.mFogColor = lerp(current.mFogColor, other.mFogColor);
-    result.mSunColor = lerp(current.mSunColor, other.mSunColor);
-    result.mSkyColor = lerp(current.mSkyColor, other.mSkyColor);
-    
-    result.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor);
-    result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor);
-    result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth);
-    result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed);
-    result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed);
-    result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
-    result.mGlareView = lerp(current.mGlareView, other.mGlareView);
-    
-    result.mNight = current.mNight;
-    
-    // sound change behaviour:
-    // if 'other' has a new sound, switch to it after 1/2 of the transition length
-    if (other.mAmbientLoopSoundID != "")
-        result.mAmbientLoopSoundID = factor>0.5 ? other.mAmbientLoopSoundID : current.mAmbientLoopSoundID;
-    // if 'current' has a sound and 'other' does not have a sound, turn off the sound immediately
-    else if (current.mAmbientLoopSoundID != "")
-        result.mAmbientLoopSoundID = "";
-        
-    return result;
-}
-
-void WeatherManager::update(float duration)
-{
-    mWeatherUpdateTime -= duration;
-    if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior())
-    {
-        std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region;
-        boost::algorithm::to_lower(regionstr);
-        
-        if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
-        {
-            mCurrentRegion = regionstr;
-            mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*60.f;
-            
-            std::string weather;
-            
-            if (mRegionOverrides.find(regionstr) != mRegionOverrides.end())
-                weather = mRegionOverrides[regionstr];
-            else
-            {
-                // get weather probabilities for the current region
-                const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr);
-                
-                float clear = region->data.clear/255.f;
-                float cloudy = region->data.cloudy/255.f;
-                float foggy = region->data.foggy/255.f;
-                float overcast = region->data.overcast/255.f;
-                float rain = region->data.rain/255.f;
-                float thunder = region->data.thunder/255.f;
-                float ash = region->data.ash/255.f;
-                float blight = region->data.blight/255.f;
-                float snow = region->data.a/255.f;
-                float blizzard = region->data.b/255.f;
-                
-                // re-scale to 100 percent
-                const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard;
-                            
-                srand(time(NULL));
-                float random = ((rand()%100)/100.f) * total;
-                                
-                if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
-                    weather = "blizzard";
-                else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
-                    weather = "snow";
-                else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear)
-                    weather = "blight";
-                else if (random >= thunder+rain+overcast+foggy+cloudy+clear)
-                    weather = "ashstorm";
-                else if (random >= rain+overcast+foggy+cloudy+clear)
-                    weather = "thunderstorm";
-                else if (random >= overcast+foggy+cloudy+clear)
-                    weather = "rain";
-                else if (random >= foggy+cloudy+clear)
-                    weather = "overcast";
-                else if (random >= cloudy+clear)
-                    weather = "foggy";
-                else if (random >= clear)
-                    weather = "cloudy";
-                else
-                    weather = "clear";
-            }
-            
-            setWeather(weather, false);
-            /*
-            std::cout << "roll result: " << random << std::endl;
-            
-            std::cout << regionstr << " weather probabilities: " << clear << " " << cloudy << " " << foggy << " " 
-                << overcast << " " << rain << " " << thunder << " " << ash << " " << blight << " " << snow << " " 
-                << blizzard << std::endl;
-            
-            std::cout << "New weather : " << weather << std::endl;
-            */
-        }
-                
-        WeatherResult result;
-        
-        if (mNextWeather != "")
-        {
-            mRemainingTransitionTime -= duration;
-            if (mRemainingTransitionTime < 0)
-            {
-                mCurrentWeather = mNextWeather;
-                mNextWeather = "";
-            }
-        }
-        
-        if (mNextWeather != "")
-            result = transition(1-(mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60)));
-        else
-            result = getResult(mCurrentWeather);
-        
-        mRendering->configureFog(result.mFogDepth, result.mFogColor);
-        
-        // disable sun during night
-        if (mHour >= WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration
-            || mHour <= WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
-            mRendering->getSkyManager()->sunDisable();
-        else
-        {
-            // during day, calculate sun angle
-            float height = 1-std::abs(((mHour-13)/7.f));
-            int facing = mHour > 13.f ? 1 : -1;
-            Vector3 final(
-                (1-height)*facing, 
-                (1-height)*facing, 
-                height);
-            mRendering->setSunDirection(final);
-            
-            mRendering->getSkyManager()->sunEnable();
-        }
-        
-        // moon calculations
-        float night;
-        if (mHour >= 14)
-            night = mHour-14;
-        else if (mHour <= 10)
-            night = mHour+10;
-        else
-            night = 0;
-            
-        night /= 20.f;
-        
-        if (night != 0)
-        {
-            float moonHeight = 1-std::abs((night-0.5)*2);
-            int facing = (mHour > 0.f && mHour<12.f) ? 1 : -1;
-            Vector3 masser(
-                (1-moonHeight)*facing, 
-                (1-moonHeight)*facing, 
-                moonHeight);
-            
-            Vector3 secunda(
-                (1-moonHeight)*facing*0.8, 
-                (1-moonHeight)*facing*1.25, 
-                moonHeight);
-            
-            mRendering->getSkyManager()->setMasserDirection(masser);
-            mRendering->getSkyManager()->setSecundaDirection(secunda);
-            mRendering->getSkyManager()->masserEnable();
-            mRendering->getSkyManager()->secundaEnable();
-            
-            float hour_fade;
-            if (mHour >= 7.f && mHour <= 14.f)
-                hour_fade = 1-(mHour-7)/3.f;
-            else if (mHour >= 14 && mHour <= 15.f)
-                hour_fade = mHour-14;
-            else
-                hour_fade = 1;
-            
-            float secunda_angle_fade;
-            float masser_angle_fade;
-            float angle = moonHeight*90.f;
-            
-            if (angle >= 30 && angle <= 50)
-                secunda_angle_fade = (angle-30)/20.f;
-            else if (angle <30)
-                secunda_angle_fade = 0.f;
-            else
-                secunda_angle_fade = 1.f;
-            
-            if (angle >= 40 && angle <= 50)
-                masser_angle_fade = (angle-40)/10.f;
-            else if (angle <40)
-                masser_angle_fade = 0.f;
-            else
-                masser_angle_fade = 1.f;
-                
-            masser_angle_fade *= hour_fade;
-            secunda_angle_fade *= hour_fade;
-            
-            mRendering->getSkyManager()->setMasserFade(masser_angle_fade);
-            mRendering->getSkyManager()->setSecundaFade(secunda_angle_fade);
-        }
-        else
-        {
-            mRendering->getSkyManager()->masserDisable();
-            mRendering->getSkyManager()->secundaDisable();
-        }
-        
-        if (mCurrentWeather == "thunderstorm" && mNextWeather == "")
-        {
-            if (mThunderFlash > 0)
-            {
-                // play the sound after a delay
-                mThunderSoundDelay -= duration;
-                if (mThunderSoundDelay <= 0)
-                {
-                    // pick a random sound
-                    int sound = rand() % 4;
-                    std::string soundname;
-                    if (sound == 0) soundname = WeatherGlobals::mThunderSoundID0;
-                    else if (sound == 1) soundname = WeatherGlobals::mThunderSoundID1;
-                    else if (sound == 2) soundname = WeatherGlobals::mThunderSoundID2;
-                    else if (sound == 3) soundname = WeatherGlobals::mThunderSoundID3;
-                    mEnvironment->mSoundManager->playSound(soundname, 1.0, 1.0);
-                    mThunderSoundDelay = 1000;
-                }
-                
-                mThunderFlash -= duration;
-                if (mThunderFlash > 0)
-                    mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
-                else
-                {
-                    srand(time(NULL));
-                    mThunderChanceNeeded = rand() % 100;
-                    mThunderChance = 0;
-                    mRendering->getSkyManager()->setThunder( 0.f );
-                }
-            }
-            else
-            {
-                // no thunder active
-                mThunderChance += duration*4; // chance increases by 4 percent every second
-                if (mThunderChance >= mThunderChanceNeeded)
-                {
-                    mThunderFlash = WeatherGlobals::mThunderThreshold;
-                    
-                    mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
-                    
-                    mThunderSoundDelay = WeatherGlobals::mThunderSoundDelay;
-                }
-            }
-        }
-        else
-            mRendering->getSkyManager()->setThunder(0.f);
-        
-        mRendering->setAmbientColour(result.mAmbientColor);
-        mRendering->sunEnable();
-        mRendering->setSunColour(result.mSunColor);
-        
-        mRendering->getSkyManager()->setWeather(result);
-    }
-    else
-    {
-        mRendering->sunDisable();
-        mRendering->skyDisable();
-        mRendering->getSkyManager()->setThunder(0.f);
-    }
-}
-
-void WeatherManager::setHour(const float hour)
-{
-    // accelerate a bit for testing
-    /*
-    mHour += 0.005;
-    
-    if (mHour >= 24.f) mHour = 0.f;
-    
-    std::cout << "hour " << mHour << std::endl;
-    */
-    
-    mHour = hour;
-}
-
-void WeatherManager::setDate(const int day, const int month)
-{
-    mDay = day;
-    mMonth = month;
-}
-
-unsigned int WeatherManager::getWeatherID() const
-{
-    // Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather
-    
-    if (mCurrentWeather == "clear")
-        return 0;
-    else if (mCurrentWeather == "cloudy")
-        return 1;
-    else if (mCurrentWeather == "foggy")
-        return 2;
-    else if (mCurrentWeather == "overcast")
-        return 3;
-    else if (mCurrentWeather == "rain")
-        return 4;
-    else if (mCurrentWeather == "thunderstorm")
-        return 5;
-    else if (mCurrentWeather == "ashstorm")
-        return 6;
-    else if (mCurrentWeather == "blight")
-        return 7;
-    else if (mCurrentWeather == "snow")
-        return 8;
-    else if (mCurrentWeather == "blizzard")
-        return 9;
-    
-    else
-        return 0;
-}
-
-void WeatherManager::changeWeather(const std::string& region, const unsigned int id)
-{
-    std::string weather;
-    if (id==0)
-        weather = "clear";
-    else if (id==1)
-        weather = "cloudy";
-    else if (id==2)
-        weather = "foggy";
-    else if (id==3)
-        weather = "overcast";
-    else if (id==4)
-        weather = "rain";
-    else if (id==5)
-        weather = "thunderstorm";
-    else if (id==6)
-        weather = "ashstorm";
-    else if (id==7)
-        weather = "blight";
-    else if (id==8)
-        weather = "snow";
-    else if (id==9)
-        weather = "blizzard";
-    else
-        weather = "clear";
-
-    mRegionOverrides[region] = weather;
-}
diff --git a/libs/openengine/bullet/weather.hpp b/libs/openengine/bullet/weather.hpp
deleted file mode 100644
index 9353f7cd1..000000000
--- a/libs/openengine/bullet/weather.hpp
+++ /dev/null
@@ -1,272 +0,0 @@
-#ifndef GAME_MWWORLD_WEATHER_H
-#define GAME_MWWORLD_WEATHER_H
-
-#include <OgreString.h>
-#include <OgreColourValue.h>
-
-namespace MWRender
-{
-    class RenderingManager;
-}
-
-namespace MWWorld
-{
-    class Environment;
-    
-    /// Global weather manager properties (according to INI)
-    struct WeatherGlobals
-    {
-        /*
-        [Weather]
-        EnvReduceColor=255,255,255,255
-        LerpCloseColor=037,046,048,255
-        BumpFadeColor=230,239,255,255
-        AlphaReduce=0.35
-        Minimum Time Between Environmental Sounds=1.0
-        Maximum Time Between Environmental Sounds=5.0
-        Sun Glare Fader Max=0.5
-        Sun Glare Fader Angle Max=30.0
-        Sun Glare Fader Color=222,095,039
-        Timescale Clouds=0
-        Precip Gravity=575
-        Hours Between Weather Changes=20
-        Rain Ripples=1
-        Rain Ripple Radius=1024
-        Rain Ripples Per Drop=1
-        Rain Ripple Scale=0.3
-        Rain Ripple Speed=1.0
-        Fog Depth Change Speed=3
-        Sunrise Time=6
-        Sunset Time=18
-        Sunrise Duration=2
-        Sunset Duration=2
-        Sky Pre-Sunrise Time=.5
-        Sky Post-Sunrise Time=1
-        Sky Pre-Sunset Time=1.5
-        Sky Post-Sunset Time=.5
-        Ambient Pre-Sunrise Time=.5
-        Ambient Post-Sunrise Time=2
-        Ambient Pre-Sunset Time=1
-        Ambient Post-Sunset Time=1.25
-        Fog Pre-Sunrise Time=.5
-        Fog Post-Sunrise Time=1
-        Fog Pre-Sunset Time=2
-        Fog Post-Sunset Time=1
-        Sun Pre-Sunrise Time=0
-        Sun Post-Sunrise Time=0
-        Sun Pre-Sunset Time=1
-        Sun Post-Sunset Time=1.25
-        Stars Post-Sunset Start=1
-        Stars Pre-Sunrise Finish=2
-        Stars Fading Duration=2
-        Snow Ripples=0
-        Snow Ripple Radius=1024
-        Snow Ripples Per Flake=1
-        Snow Ripple Scale=0.3
-        Snow Ripple Speed=1.0
-        Snow Gravity Scale=0.1
-        Snow High Kill=700
-        Snow Low Kill=150
-        
-        
-        [Moons]
-        Masser Size=94
-        Masser Fade In Start=14
-        Masser Fade In Finish=15
-        Masser Fade Out Start=7
-        Masser Fade Out Finish=10
-        Masser Axis Offset=35
-        Masser Speed=.5
-        Masser Daily Increment=1
-        Masser Fade Start Angle=50
-        Masser Fade End Angle=40
-        Masser Moon Shadow Early Fade Angle=0.5
-        Secunda Size=40
-        Secunda Fade In Start=14
-        Secunda Fade In Finish=15
-        Secunda Fade Out Start=7
-        Secunda Fade Out Finish=10
-        Secunda Axis Offset=50
-        Secunda Speed=.6
-        Secunda Daily Increment=1.2
-        Secunda Fade Start Angle=50
-        Secunda Fade End Angle=30
-        Secunda Moon Shadow Early Fade Angle=0.5
-        Script Color=255,20,20
-        */
-        
-        static const float mSunriseTime;
-        static const float mSunsetTime;
-        static const float mSunriseDuration;
-        static const float mSunsetDuration;
-        
-        static const float mWeatherUpdateTime;
-        
-        // morrowind sets these per-weather, but since they are only used by 'thunderstorm'
-        // weather setting anyway, we can just as well set them globally
-        static const float mThunderFrequency;
-        static const float mThunderThreshold;
-        static const float mThunderSoundDelay;
-        static const std::string mThunderSoundID0;
-        static const std::string mThunderSoundID1;
-        static const std::string mThunderSoundID2;
-        static const std::string mThunderSoundID3;
-    };
-
-    /// Defines the actual weather that results from weather setting (see below), time of day and weather transition
-    struct WeatherResult
-    {
-        Ogre::String mCloudTexture;
-        Ogre::String mNextCloudTexture;
-        float mCloudBlendFactor;
-        
-        Ogre::ColourValue mFogColor;
-        
-        Ogre::ColourValue mAmbientColor;
-        
-        Ogre::ColourValue mSkyColor;
-        
-        Ogre::ColourValue mSunColor;
-        
-        Ogre::ColourValue mSunDiscColor;
-        
-        float mFogDepth;
-        
-        float mWindSpeed;
-        
-        float mCloudSpeed;
-        
-        float mCloudOpacity;
-        
-        float mGlareView;
-        
-        bool mNight; // use night skybox
-        float mNightFade; // fading factor for night skybox
-        
-        Ogre::String mAmbientLoopSoundID;
-    };
-    
-    
-    /// Defines a single weather setting (according to INI)
-    struct Weather
-    {
-        Ogre::String mCloudTexture;
-        
-        // Sky (atmosphere) colors 
-        Ogre::ColourValue   mSkySunriseColor,
-                            mSkyDayColor,
-                            mSkySunsetColor,
-                            mSkyNightColor;
-        
-        // Fog colors
-        Ogre::ColourValue   mFogSunriseColor,
-                            mFogDayColor,
-                            mFogSunsetColor,
-                            mFogNightColor;
-        
-        // Ambient lighting colors
-        Ogre::ColourValue   mAmbientSunriseColor,
-                            mAmbientDayColor,
-                            mAmbientSunsetColor,
-                            mAmbientNightColor;
-        
-        // Sun (directional) lighting colors
-        Ogre::ColourValue   mSunSunriseColor,
-                            mSunDayColor,
-                            mSunSunsetColor,
-                            mSunNightColor;
-        
-        // Fog depth/density
-        float   mLandFogDayDepth,
-                mLandFogNightDepth;
-        
-        // Color modulation for the sun itself during sunset (not completely sure)
-        Ogre::ColourValue mSunDiscSunsetColor;
-        
-        // Duration of weather transition (in days)
-        float mTransitionDelta;
-        
-        // No idea what this one is used for?
-        float mWindSpeed;
-        
-        // Cloud animation speed multiplier
-        float mCloudSpeed;
-        
-        // Multiplier for clouds transparency
-        float mCloudsMaximumPercent;
-        
-        // Value between 0 and 1, defines the strength of the sun glare effect
-        float mGlareView;
-        
-        // Sound effect
-        // This is used for Blight, Ashstorm and Blizzard (Bloodmoon)
-        Ogre::String mAmbientLoopSoundID;
-        
-        // Rain sound effect
-        Ogre::String mRainLoopSoundID;
-        
-        /// \todo disease chance
-    };
-    
-    ///
-    /// Interface for weather settings
-    ///
-    class WeatherManager
-    {
-    public:
-        WeatherManager(MWRender::RenderingManager*, MWWorld::Environment*);
-        
-        /**
-         * Change the weather in the specified region
-         * @param region that should be changed
-         * @param ID of the weather setting to shift to
-         */
-        void changeWeather(const std::string& region, const unsigned int id);
-        
-        /**
-         * Per-frame update
-         * @param duration
-         */
-        void update(float duration);
-        
-        void setHour(const float hour);
-        
-        void setDate(const int day, const int month);
-        
-        unsigned int getWeatherID() const;
-        
-    private:
-        float mHour;
-        int mDay, mMonth;
-        
-        MWRender::RenderingManager* mRendering;
-        MWWorld::Environment* mEnvironment;
-        
-        std::map<Ogre::String, Weather> mWeatherSettings;
-        
-        std::map<std::string, std::string> mRegionOverrides;
-        
-        Ogre::String mCurrentWeather;
-        Ogre::String mNextWeather;
-        
-        std::string mCurrentRegion;
-        
-        bool mFirstUpdate;
-        
-        float mWeatherUpdateTime;
-        
-        float mRemainingTransitionTime;
-        
-        float mThunderFlash;
-        float mThunderChance;
-        float mThunderChanceNeeded;
-        float mThunderSoundDelay;
-        
-        WeatherResult transition(const float factor);
-        WeatherResult getResult(const Ogre::String& weather);
-        
-        void setWeather(const Ogre::String& weather, bool instant=false);
-    };
-}
-
-#endif // GAME_MWWORLD_WEATHER_H

From 318355f1be3fa5f14abe34d39a3b76b063b5b9a3 Mon Sep 17 00:00:00 2001
From: Jason Hooks <jhooks1@mix.wvu.edu>
Date: Mon, 26 Mar 2012 21:35:20 -0400
Subject: [PATCH 03/20] Bouncy effect gone

---
 libs/openengine/bullet/pmove.cpp | 48 ++++++++++++++++++++++----------
 libs/openengine/bullet/trace.cpp |  4 +--
 2 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 8dd01ef19..d8880a49f 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -178,7 +178,7 @@ bool	PM_SlideMove( bool gravity )
 	float		into;
 	Ogre::Vector3		endVelocity;
 	Ogre::Vector3		endClipVelocity;
-	std::cout << "Slide move\n";
+	std::cout << "Slide move" << pm->ps.velocity << "\n";
 	numbumps = 4;
 
 	// primal_velocity = pm->ps->velocity
@@ -415,6 +415,7 @@ int PM_StepSlideMove( bool gravity )
 //	vec3_t		delta, delta2;
 	Ogre::Vector3		up, down;
 	float		stepSize;
+	std::cout << "Step Slide move" << pm->ps.velocity << "\n";
 
 	// start_o = pm->ps->origin
 	//VectorCopy (pm->ps->origin, start_o);
@@ -427,7 +428,7 @@ int PM_StepSlideMove( bool gravity )
 	if ( PM_SlideMove( gravity ) == false )
 		return 1;		// we got exactly where we wanted to go first try	
 
-	std::cout << "Step Slide move\n";
+	
 	// down = start_o - vec3(0, 0, STEPSIZE)
 	//VectorCopy(start_o, down);
 	down = start_o;
@@ -711,7 +712,7 @@ static void PM_WaterMove( playerMove* const pm )
 	Ogre::Vector3 wishdir;
 	float	scale;
 	float	vel;
-
+	std::cout << "Water moving";
 	/*if ( PM_CheckWaterJump() ) 
 	{
 		PM_WaterJumpMove();
@@ -837,7 +838,7 @@ static void PM_WalkMove( playerMove* const pmove )
 	playerMove::playercmd cmd;
 	float		accelerate;
 	float		vel;
-	std::cout << "Walking\n";
+	std::cout << "Walking"  << pm->ps.velocity << "\n";
 
 	if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) 
 		pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f)
@@ -927,6 +928,7 @@ static void PM_WalkMove( playerMove* const pmove )
 
 
 	PM_Friction ();
+	std::cout << "After friction" << pm->ps.velocity << "\n";
 
 	//bprintf("vel: (%f, %f, %f)\n", pm->ps.velocity.x, pm->ps.velocity.y, pm->ps.velocity.z);
 
@@ -945,20 +947,28 @@ static void PM_WalkMove( playerMove* const pmove )
 
 	//pml.right[2] = 0;
 	pml.right.z = 0;
+	//std::cout << "Further down" << pm->ps.velocity << "\n";
 
+	
 	// project the forward and right directions onto the ground plane
 	PM_ClipVelocity (pml.forward, pml.groundTrace.planenormal, pml.forward, OVERCLIP );
 	PM_ClipVelocity (pml.right, pml.groundTrace.planenormal, pml.right, OVERCLIP );
+	std::cout << "Clip velocity" << pm->ps.velocity << "\n";
 	//
-	//VectorNormalize (pml.forward);
-	pml.forward = pml.forward.normalise();
-	pml.right = pml.right.normalise();
+	
+	VectorNormalize (pml.forward);
+	VectorNormalize (pml.right);
+	//pml.forward = pml.forward.normalise();
+	//pml.right = pml.right.normalise();
+	std::cout << "forward2" << pml.forward << "\n";
+	std::cout << "right2" << pml.right << "\n";
 	
 
 	// wishvel = (pml.forward * fmove) + (pml.right * smove);
 	//for ( i = 0 ; i < 3 ; i++ ) 
 		//wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove;
 	wishvel = pml.forward * fmove + pml.right * smove;
+	std::cout << "WishVel" << wishvel << "\n";
 	//bprintf("f: (%f, %f, %f), s: (%f, %f, %f)\n", fmove, smove);
 
 
@@ -971,7 +981,9 @@ static void PM_WalkMove( playerMove* const pmove )
 	wishdir = wishvel;
 
 	wishspeed = VectorNormalize(wishdir);
+	std::cout << "Wishspeed: " << wishspeed << "\n";
 	wishspeed *= scale;
+	std::cout << "Wishspeed scaled:" << wishspeed << "\n";
 
 	// clamp the speed lower if ducking
 	if ( pm->cmd.ducking ) 
@@ -998,6 +1010,7 @@ static void PM_WalkMove( playerMove* const pmove )
 
 
 	PM_Accelerate (wishdir, wishspeed, accelerate);
+	std::cout << "Velocityafter: " << pm->ps.velocity << "\n";
 
 	//Com_Printf("velocity = %1.1f %1.1f %1.1f\n", pm->ps->velocity[0], pm->ps->velocity[1], pm->ps->velocity[2]);
 	//Com_Printf("velocity1 = %1.1f\n", VectorLength(pm->ps->velocity));
@@ -1012,15 +1025,18 @@ static void PM_WalkMove( playerMove* const pmove )
 
 	//vel = VectorLength(pm->ps->velocity);
 	vel = pm->ps.velocity.length();
+	std::cout << "The length" << vel << "\n";
 
 	// slide along the ground plane
 	PM_ClipVelocity (pm->ps.velocity, pml.groundTrace.planenormal, 
 		pm->ps.velocity, OVERCLIP );
+	std::cout << "Velocity clipped" << pm->ps.velocity << "\n";
 
 	// don't decrease velocity when going up or down a slope
-	//VectorNormalize(pm->ps->velocity);
-	pm->ps.velocity = pm->ps.velocity.normalise();
+	VectorNormalize(pm->ps.velocity);
+	//pm->ps.velocity = pm->ps.velocity.normalise();
 	
+	std::cout << "Final:" << pm->ps.velocity << "\n";
 	//VectorScale(pm->ps->velocity, vel, pm->ps->velocity);
 	pm->ps.velocity = pm->ps.velocity * vel;
 
@@ -1032,6 +1048,7 @@ static void PM_WalkMove( playerMove* const pmove )
 	PM_StepSlideMove( false );
 
 	//Com_Printf("velocity2 = %1.1f\n", VectorLength(pm->ps->velocity));
+	std::cout << "Walk2" << pm->ps.velocity << "\n";
 
 }
 
@@ -1361,7 +1378,7 @@ static void PM_CrashLand( void )
 
 static void PM_GroundTrace( void ) 
 {
-	std::cout << "Ground trace\n";
+	std::cout << "Ground trace" << pm->ps.velocity << "\n";
 	Ogre::Vector3		point;
 	traceResults		trace;
 
@@ -1467,13 +1484,13 @@ static void PM_GroundTrace( void )
 
 	// don't reset the z velocity for slopes
 //	pm->ps->velocity[2] = 0;
-
+	std::cout << "Ground trace2" << pm->ps.velocity << "\n";
 	//PM_AddTouchEnt( trace.entityNum );
 }
 
 static void PM_AirMove()
 {
-	std::cout << "Air move\n";
+	std::cout << "Air move " << pm->ps.velocity << "\n";
 	//int			i;
 	Ogre::Vector3		wishvel;
 	float		fmove, smove;
@@ -1495,9 +1512,9 @@ static void PM_AirMove()
 
 	// project moves down to flat plane
 	//pml.forward[2] = 0;
-	pml.forward.y = 0;             //Z or Y?
+	pml.forward.z = 0;             //Z or Y?
 	//pml.right[2] = 0;
-	pml.right.y = 0;
+	pml.right.z = 0;
 	//VectorNormalize (pml.forward);
 	pml.forward = Ogre::Vector3(pml.forward.normalise());
 	pml.right = Ogre::Vector3(pml.right.normalise());
@@ -1535,8 +1552,9 @@ static void PM_AirMove()
 	else
 		PM_SlideMove ( qtrue );
 #endif*/
-
+	
 	/*bprintf("%i ", */PM_StepSlideMove ( true )/* )*/;
+	std::cout << "Velocity 2 " << pm->ps.velocity << "\n"; 
 }
 
 static void PM_NoclipMove( void ) 
diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp
index 8f2423c24..18a668e55 100644
--- a/libs/openengine/bullet/trace.cpp
+++ b/libs/openengine/bullet/trace.cpp
@@ -32,7 +32,7 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr
 	//Ogre::Vector3 endReplace = startReplace;
 	//endReplace.z -= .25;
 	
-	const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0f, rotation), isInterior, enginePass);
+	const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, rotation, 0.0f), isInterior, enginePass);
 	if(hasHit)
 		std::cout << "Has hit\n";
 	if (out.fraction < 0.001f)
@@ -100,7 +100,7 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
 
 	const btVector3 btstart(start.x, start.y, start.z);
 	const btVector3 btend(end.x, end.y, end.z);
-	const btQuaternion btrot(rotation.y, rotation.x, rotation.z);
+	const btQuaternion btrot(rotation.y, rotation.x, rotation.z);   //y, x, z
 
 	const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));
 	const btTransform from(btrot, btstart);

From b9fabce9c4654f99c3b3bc8e296e64e35b13639d Mon Sep 17 00:00:00 2001
From: Jason Hooks <jhooks1@mix.wvu.edu>
Date: Tue, 27 Mar 2012 20:17:54 -0400
Subject: [PATCH 04/20] Awesome, working

---
 apps/openmw/mwclass/npc.cpp           |  4 +-
 apps/openmw/mwworld/physicssystem.cpp |  7 ++-
 libs/openengine/bullet/pmove.cpp      | 67 +++++++++++++--------------
 libs/openengine/bullet/pmove.h        |  2 +-
 libs/openengine/bullet/trace.cpp      |  8 ++--
 5 files changed, 44 insertions(+), 44 deletions(-)

diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp
index 522fce3a3..8bb394129 100644
--- a/apps/openmw/mwclass/npc.cpp
+++ b/apps/openmw/mwclass/npc.cpp
@@ -273,8 +273,8 @@ namespace MWClass
         vector.y = getMovementSettings (ptr).mForwardBackward * 127;
 		vector.z = getMovementSettings(ptr).mUpDown * 127;
 
-        if (getStance (ptr, Run, false))
-            vector *= 2;
+        //if (getStance (ptr, Run, false))
+        //    vector *= 2;
 
         return vector;
     }
diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp
index 15d2d3f9f..fdcee417f 100644
--- a/apps/openmw/mwworld/physicssystem.cpp
+++ b/apps/openmw/mwworld/physicssystem.cpp
@@ -116,7 +116,6 @@ namespace MWWorld
 				pm_ref.upmove = dir1.y;
 				
 				
-				
 				//std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n";
 				//playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
 				//std::cout << "Pitch: " << yawQuat.getPitch() << "Yaw:" << yawQuat.getYaw() << "Roll: " << yawQuat.getRoll() << "\n";
@@ -124,11 +123,15 @@ namespace MWWorld
             }
             else
             {
+				
                 Ogre::Quaternion quat = yawNode->getOrientation();
                 Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
+				
 				pm_ref.rightmove = -dir1.x;
 				pm_ref.forwardmove = dir1.z;
-				pm_ref.upmove = dir.y;
+				pm_ref.upmove = dir1.y;
+				
+				
 				
                 dir = 0.025*(quat*dir1);
             }
diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index d8880a49f..8fb72aa1f 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -93,6 +93,7 @@ static inline void PM_ClipVelocity(const Ogre::Vector3& in, const Ogre::Vector3&
 	{
 		change = normal[i]*backoff;
 		out[i] = in[i] - change;
+
 	}*/
 	float changex = normal.x * backoff;
 	out.x = in.x - changex;
@@ -178,7 +179,7 @@ bool	PM_SlideMove( bool gravity )
 	float		into;
 	Ogre::Vector3		endVelocity;
 	Ogre::Vector3		endClipVelocity;
-	std::cout << "Slide move" << pm->ps.velocity << "\n";
+	
 	numbumps = 4;
 
 	// primal_velocity = pm->ps->velocity
@@ -415,7 +416,7 @@ int PM_StepSlideMove( bool gravity )
 //	vec3_t		delta, delta2;
 	Ogre::Vector3		up, down;
 	float		stepSize;
-	std::cout << "Step Slide move" << pm->ps.velocity << "\n";
+	
 
 	// start_o = pm->ps->origin
 	//VectorCopy (pm->ps->origin, start_o);
@@ -543,7 +544,7 @@ int PM_StepSlideMove( bool gravity )
 
 void PM_Friction(void)
 {
-	std::cout << "Friction\n";
+	
 	Ogre::Vector3	vec;
 	float* vel;
 	float	speed, newspeed, control;
@@ -639,7 +640,6 @@ static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel
 {
 //	int			i;
 	float		addspeed, accelspeed, currentspeed;
-	std::cout << "Accelerate\n";
 
 	// currentspeed = pm->ps->velocity dot wishdir
 	//currentspeed = DotProduct (pm->ps->velocity, wishdir);
@@ -712,7 +712,7 @@ static void PM_WaterMove( playerMove* const pm )
 	Ogre::Vector3 wishdir;
 	float	scale;
 	float	vel;
-	std::cout << "Water moving";
+
 	/*if ( PM_CheckWaterJump() ) 
 	{
 		PM_WaterJumpMove();
@@ -838,7 +838,7 @@ static void PM_WalkMove( playerMove* const pmove )
 	playerMove::playercmd cmd;
 	float		accelerate;
 	float		vel;
-	std::cout << "Walking"  << pm->ps.velocity << "\n";
+	
 
 	if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) 
 		pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f)
@@ -851,6 +851,7 @@ static void PM_WalkMove( playerMove* const pmove )
 
 	if ( PM_CheckJump () ) 
 	{
+		
 		// jumped away
 		if ( pm->ps.waterlevel > 1 ) 
 			PM_WaterMove(pmove);
@@ -928,12 +929,13 @@ static void PM_WalkMove( playerMove* const pmove )
 
 
 	PM_Friction ();
-	std::cout << "After friction" << pm->ps.velocity << "\n";
+	
 
 	//bprintf("vel: (%f, %f, %f)\n", pm->ps.velocity.x, pm->ps.velocity.y, pm->ps.velocity.z);
 
 	fmove = pm->cmd.forwardmove;
 	smove = pm->cmd.rightmove;
+	
 
 	cmd = pm->cmd;
 	scale = PM_CmdScale( &cmd );
@@ -953,22 +955,23 @@ static void PM_WalkMove( playerMove* const pmove )
 	// project the forward and right directions onto the ground plane
 	PM_ClipVelocity (pml.forward, pml.groundTrace.planenormal, pml.forward, OVERCLIP );
 	PM_ClipVelocity (pml.right, pml.groundTrace.planenormal, pml.right, OVERCLIP );
-	std::cout << "Clip velocity" << pm->ps.velocity << "\n";
+	//std::cout << "Clip velocity" << pm->ps.velocity << "\n";
 	//
 	
 	VectorNormalize (pml.forward);
 	VectorNormalize (pml.right);
 	//pml.forward = pml.forward.normalise();
 	//pml.right = pml.right.normalise();
-	std::cout << "forward2" << pml.forward << "\n";
-	std::cout << "right2" << pml.right << "\n";
+	//std::cout << "forward2" << pml.forward << "\n";
+	//std::cout << "right2" << pml.right << "\n";
 	
 
 	// wishvel = (pml.forward * fmove) + (pml.right * smove);
 	//for ( i = 0 ; i < 3 ; i++ ) 
 		//wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove;
 	wishvel = pml.forward * fmove + pml.right * smove;
-	std::cout << "WishVel" << wishvel << "\n";
+	
+	
 	//bprintf("f: (%f, %f, %f), s: (%f, %f, %f)\n", fmove, smove);
 
 
@@ -981,9 +984,9 @@ static void PM_WalkMove( playerMove* const pmove )
 	wishdir = wishvel;
 
 	wishspeed = VectorNormalize(wishdir);
-	std::cout << "Wishspeed: " << wishspeed << "\n";
+	//std::cout << "Wishspeed: " << wishspeed << "\n";
 	wishspeed *= scale;
-	std::cout << "Wishspeed scaled:" << wishspeed << "\n";
+	//std::cout << "Wishspeed scaled:" << wishspeed << "\n";
 
 	// clamp the speed lower if ducking
 	if ( pm->cmd.ducking ) 
@@ -1010,7 +1013,7 @@ static void PM_WalkMove( playerMove* const pmove )
 
 
 	PM_Accelerate (wishdir, wishspeed, accelerate);
-	std::cout << "Velocityafter: " << pm->ps.velocity << "\n";
+	//std::cout << "Velocityafter: " << pm->ps.velocity << "\n";
 
 	//Com_Printf("velocity = %1.1f %1.1f %1.1f\n", pm->ps->velocity[0], pm->ps->velocity[1], pm->ps->velocity[2]);
 	//Com_Printf("velocity1 = %1.1f\n", VectorLength(pm->ps->velocity));
@@ -1025,18 +1028,18 @@ static void PM_WalkMove( playerMove* const pmove )
 
 	//vel = VectorLength(pm->ps->velocity);
 	vel = pm->ps.velocity.length();
-	std::cout << "The length" << vel << "\n";
+	//std::cout << "The length" << vel << "\n";
 
 	// slide along the ground plane
 	PM_ClipVelocity (pm->ps.velocity, pml.groundTrace.planenormal, 
 		pm->ps.velocity, OVERCLIP );
-	std::cout << "Velocity clipped" << pm->ps.velocity << "\n";
+	//std::cout << "Velocity clipped" << pm->ps.velocity << "\n";
 
 	// don't decrease velocity when going up or down a slope
 	VectorNormalize(pm->ps.velocity);
 	//pm->ps.velocity = pm->ps.velocity.normalise();
 	
-	std::cout << "Final:" << pm->ps.velocity << "\n";
+	//std::cout << "Final:" << pm->ps.velocity << "\n";
 	//VectorScale(pm->ps->velocity, vel, pm->ps->velocity);
 	pm->ps.velocity = pm->ps.velocity * vel;
 
@@ -1048,7 +1051,7 @@ static void PM_WalkMove( playerMove* const pmove )
 	PM_StepSlideMove( false );
 
 	//Com_Printf("velocity2 = %1.1f\n", VectorLength(pm->ps->velocity));
-	std::cout << "Walk2" << pm->ps.velocity << "\n";
+	
 
 }
 
@@ -1056,7 +1059,7 @@ void PM_UpdateViewAngles( playerMove::playerStruct* const ps, playerMove::player
 {
 	short		temp;
 	int		i;
-	std::cout << "Updating viewangles\n";
+	
 	//while(1);
 
 	//if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPINTERMISSION) 
@@ -1178,7 +1181,6 @@ static bool PM_CorrectAllSolid(traceResults* const trace)
 {
 	int			i, j, k;
 	Ogre::Vector3	point;
-	std::cout << "Correct all solid\n";
 
 	//if ( pm->debugLevel )
 		//Com_Printf("%i:allsolid\n", c_pmove);
@@ -1236,7 +1238,7 @@ static void PM_CrashLand( void )
 	float		vel, acc;
 	float		t;
 	float		a, b, c, den;
-	std::cout << "Crash land\n";
+
 	// decide which landing animation to use
 	/*if ( pm->ps->pm_flags & PMF_BACKWARDS_JUMP ) 
 		PM_ForceLegsAnim( LEGS_LANDB );
@@ -1378,7 +1380,6 @@ static void PM_CrashLand( void )
 
 static void PM_GroundTrace( void ) 
 {
-	std::cout << "Ground trace" << pm->ps.velocity << "\n";
 	Ogre::Vector3		point;
 	traceResults		trace;
 
@@ -1484,13 +1485,12 @@ static void PM_GroundTrace( void )
 
 	// don't reset the z velocity for slopes
 //	pm->ps->velocity[2] = 0;
-	std::cout << "Ground trace2" << pm->ps.velocity << "\n";
+	
 	//PM_AddTouchEnt( trace.entityNum );
 }
 
 static void PM_AirMove()
 {
-	std::cout << "Air move " << pm->ps.velocity << "\n";
 	//int			i;
 	Ogre::Vector3		wishvel;
 	float		fmove, smove;
@@ -1516,8 +1516,8 @@ static void PM_AirMove()
 	//pml.right[2] = 0;
 	pml.right.z = 0;
 	//VectorNormalize (pml.forward);
-	pml.forward = Ogre::Vector3(pml.forward.normalise());
-	pml.right = Ogre::Vector3(pml.right.normalise());
+	VectorNormalize(pml.forward);
+	VectorNormalize(pml.right);
 	//VectorNormalize (pml.right);
 
 	//for ( i = 0 ; i < 2 ; i++ )
@@ -1554,7 +1554,6 @@ static void PM_AirMove()
 #endif*/
 	
 	/*bprintf("%i ", */PM_StepSlideMove ( true )/* )*/;
-	std::cout << "Velocity 2 " << pm->ps.velocity << "\n"; 
 }
 
 static void PM_NoclipMove( void ) 
@@ -1602,9 +1601,7 @@ static void PM_NoclipMove( void )
 	
 	//for (i=0 ; i<3 ; i++)
 		//wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove;
-	std::cout << "Forward" << pml.forward << "\n";
-	std::cout << "Right" << pml.right << "\n";
-	std::cout << "Up" << pml.up << "\n";
+	
 	wishvel = pml.forward * fmove + pml.right * smove;
 	//wishvel[2] += pm->cmd.upmove;
 	wishvel.z += pm->cmd.upmove;
@@ -1614,6 +1611,7 @@ static void PM_NoclipMove( void )
 	wishspeed = VectorNormalize(wishdir);
 	wishspeed *= scale;
 
+
 	PM_Accelerate( wishdir, wishspeed, pm_accelerate );
 
 	// move
@@ -1747,6 +1745,7 @@ void PM_SetWaterLevel( playerMove* const pm )
 
 void PmoveSingle (playerMove* const pmove) 
 {
+	
 	//pm = pmove;
 
 	// Aedra doesn't support Q3-style VM traps D:	//while(1);
@@ -1898,7 +1897,7 @@ void PmoveSingle (playerMove* const pmove)
 
 	if ( pm->ps.move_type == PM_SPECTATOR ) 
 	{
-		std::cout << "SPECTATOR\n";
+		
 		//PM_CheckDuck ();
 		PM_FlyMove ();
 		PM_DropTimers ();
@@ -1907,20 +1906,19 @@ void PmoveSingle (playerMove* const pmove)
 
 	if ( pm->ps.move_type == PM_NOCLIP ) 
 	{
-		std::cout << "NOCLIP\n";
+		
 		PM_NoclipMove ();
 		PM_DropTimers ();
 		return;
 	}
 
 	if (pm->ps.move_type == PM_FREEZE){
-		std::cout << "FREEZE\n";
+		
 		return;		// no movement at all
 
 	}
 
 	if ( pm->ps.move_type == PM_INTERMISSION || pm->ps.move_type == PM_SPINTERMISSION){
-		std::cout << "INTERMISSION\n";
 		return;		// no movement at all
 	}
 
@@ -2006,6 +2004,7 @@ void Ext_UpdateViewAngles(playerMove* const pm)
 
 void Pmove (playerMove* const pmove) 
 {
+	int fmove = pmove->cmd.forwardmove;
 	pm = pmove;
 
 	int			finalTime;
diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h
index 5dfd18f6d..30572a92a 100644
--- a/libs/openengine/bullet/pmove.h
+++ b/libs/openengine/bullet/pmove.h
@@ -90,7 +90,7 @@ struct playerMove
 {
 	struct playerStruct
 	{
-		playerStruct() : gravity(50.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0)
+		playerStruct() : gravity(800.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0)
 		{
 			origin = Ogre::Vector3(733.164f,900.0f, 839.432f);
 			velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f);
diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp
index 18a668e55..ca68a5d5c 100644
--- a/libs/openengine/bullet/trace.cpp
+++ b/libs/openengine/bullet/trace.cpp
@@ -32,9 +32,8 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr
 	//Ogre::Vector3 endReplace = startReplace;
 	//endReplace.z -= .25;
 	
-	const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, rotation, 0.0f), isInterior, enginePass);
-	if(hasHit)
-		std::cout << "Has hit\n";
+	const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0, rotation), isInterior, enginePass);
+	
 	if (out.fraction < 0.001f)
 		results->startsolid = true;
 	else
@@ -180,8 +179,7 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
 
 	const bool hasHit = newTraceCallback.hasHit();
 
-	if(hasHit)
-		std::cout << "HIT\n";
+	
 
 	
 	return hasHit;

From c5f044eb0df83cb1b550bf3e3559d2f7621b7637 Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Wed, 28 Mar 2012 22:46:29 +0200
Subject: [PATCH 05/20] fixed compilation

---
 apps/openmw/mwworld/scene.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp
index 79e7d565d..205d66cd7 100644
--- a/apps/openmw/mwworld/scene.cpp
+++ b/apps/openmw/mwworld/scene.cpp
@@ -112,9 +112,12 @@ namespace MWWorld
             float worldsize = ESM::Land::REAL_SIZE;
 
             if (!(cell->cell->data.flags & ESM::Cell::Interior))
-                mPhysics->addHeightField (cell->land[1][1]->landData->heights,
+            {
+                ESM::Land* land = mWorld->getStore().lands.search(cell->cell->data.gridX,cell->cell->data.gridY);
+                mPhysics->addHeightField (land->landData->heights,
                     cell->cell->data.gridX, cell->cell->data.gridY,
                     0, ( worldsize/(verts-1) ), verts);
+            }
 
             mRendering.configureAmbient(*cell);
             mRendering.requestMap(cell);

From bc636f036ce6c10470625e33bc3e2e762989ab96 Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Sun, 8 Apr 2012 18:25:50 +0200
Subject: [PATCH 06/20] made it compile

---
 libs/openengine/bullet/pmove.cpp | 2 +-
 libs/openengine/bullet/trace.h   | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 8fb72aa1f..dcb2e9f9b 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -1489,7 +1489,7 @@ static void PM_GroundTrace( void )
 	//PM_AddTouchEnt( trace.entityNum );
 }
 
-static void PM_AirMove()
+void PM_AirMove()
 {
 	//int			i;
 	Ogre::Vector3		wishvel;
diff --git a/libs/openengine/bullet/trace.h b/libs/openengine/bullet/trace.h
index 025673ab7..fb666b6eb 100644
--- a/libs/openengine/bullet/trace.h
+++ b/libs/openengine/bullet/trace.h
@@ -53,10 +53,10 @@ struct traceResults
 
 template <const traceWorldType traceType>
 const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
-template const bool NewPhysicsTrace<collisionWorldTrace>(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
-template const bool NewPhysicsTrace<pickWorldTrace>(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
+//template const bool NewPhysicsTrace<collisionWorldTrace>(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
+//template const bool NewPhysicsTrace<pickWorldTrace>(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
 
 void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
 
 
-#endif
\ No newline at end of file
+#endif

From 5f9056c45d06fadd12a77be438c3eab930e25ecb Mon Sep 17 00:00:00 2001
From: Jason Hooks <jhooks1@mix.wvu.edu>
Date: Tue, 17 Apr 2012 20:31:36 -0400
Subject: [PATCH 07/20] Better no clip

---
 apps/openmw/mwworld/physicssystem.cpp | 7 ++++---
 libs/openengine/bullet/pmove.cpp      | 4 +++-
 libs/openengine/bullet/pmove.h        | 4 ++--
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp
index 29c65b411..98c15e338 100644
--- a/apps/openmw/mwworld/physicssystem.cpp
+++ b/apps/openmw/mwworld/physicssystem.cpp
@@ -127,11 +127,11 @@ namespace MWWorld
                 Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
 				Ogre::Quaternion both = yawQuat * pitchQuat;
 				
-				playerphysics->ps.viewangles.x = 0;
+				playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
 				playerphysics->ps.viewangles.z = 0;
-			playerphysics->ps.viewangles.y = both.getYaw().valueDegrees() *-1 + 90;
+			playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
 
-				//playerphysics->ps.viewangles.z = both.getPitch().valueDegrees();
+				
 				
 			
             if(mFreeFly)
@@ -259,6 +259,7 @@ namespace MWWorld
     {
 		if(playerphysics->ps.move_type==PM_NOCLIP)
 			playerphysics->ps.move_type=PM_NORMAL;
+
 		else
 			playerphysics->ps.move_type=PM_NOCLIP;
         for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 8fb72aa1f..86d069273 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -632,6 +632,8 @@ float PM_CmdScale(playerMove::playercmd* const cmd)
 	total = sqrtf( (const float)(cmd->forwardmove * cmd->forwardmove
 		+ cmd->rightmove * cmd->rightmove + cmd->upmove * cmd->upmove) );
 	scale = (float)pm->ps.speed * max / ( 127.0f * total );
+    if(pm->ps.move_type == PM_NOCLIP)
+        scale *= 2;
 
 	return scale;
 }
@@ -1125,7 +1127,7 @@ void AngleVectors( const Ogre::Vector3& angles, Ogre::Vector3* const forward, Og
 	{
 		right->x = (-1 * sr * sp * cy + -1 * cr * -sy);
 		right->y = (-1 * sr * sp * sy + -1 * cr * cy);
-		right->z = 0.0f;//-1 * sp * cp;
+		right->z = 0;
 	}
 	if (up)
 	{
diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h
index 30572a92a..304572b02 100644
--- a/libs/openengine/bullet/pmove.h
+++ b/libs/openengine/bullet/pmove.h
@@ -55,7 +55,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
 #define	CONTENTS_FOG			64
 static const float	pm_accelerate = 10.0f;
 static const float	pm_stopspeed = 100.0f;
-static const float	pm_friction = 6.0f;
+static const float	pm_friction = 12.0f;
 static const float  pm_flightfriction = 3.0f;
 static const float	pm_waterfriction = 1.0f;
 static const float	pm_airaccelerate = 1.0f;
@@ -90,7 +90,7 @@ struct playerMove
 {
 	struct playerStruct
 	{
-		playerStruct() : gravity(800.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0)
+		playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0)
 		{
 			origin = Ogre::Vector3(733.164f,900.0f, 839.432f);
 			velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f);

From 4d07ae7fe031dad3019b8c7d837fc4059a3ffee9 Mon Sep 17 00:00:00 2001
From: Jason Hooks <jhooks1@mix.wvu.edu>
Date: Wed, 18 Apr 2012 00:13:38 -0400
Subject: [PATCH 08/20] Swimming working

---
 apps/openmw/mwworld/physicssystem.cpp |  7 +++++++
 apps/openmw/mwworld/physicssystem.hpp |  2 ++
 apps/openmw/mwworld/scene.cpp         |  2 ++
 libs/openengine/bullet/pmove.cpp      | 10 +++++-----
 4 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp
index 98c15e338..d224385ae 100644
--- a/apps/openmw/mwworld/physicssystem.cpp
+++ b/apps/openmw/mwworld/physicssystem.cpp
@@ -67,6 +67,13 @@ namespace MWWorld
 
         return mEngine->rayTest2(from,to);
     }
+    void PhysicsSystem::setCurrentWater(bool hasWater, int waterHeight){
+        playerphysics->hasWater = hasWater;
+        if(hasWater){
+            playerphysics->waterHeight = waterHeight;
+        }
+        
+    }
 
     btVector3 PhysicsSystem::getRayPoint(float extent)
     {
diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp
index fb15a1486..2d73cab27 100644
--- a/apps/openmw/mwworld/physicssystem.hpp
+++ b/apps/openmw/mwworld/physicssystem.hpp
@@ -49,6 +49,8 @@ namespace MWWorld
             void insertActorPhysics(const MWWorld::Ptr&, std::string model);
 
             OEngine::Physic::PhysicEngine* getEngine();
+            
+            void setCurrentWater(bool hasWater, int waterHeight);
 
         private:
             OEngine::Render::OgreRenderer &mRender;
diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp
index 2123b4799..5244d53f8 100644
--- a/apps/openmw/mwworld/scene.cpp
+++ b/apps/openmw/mwworld/scene.cpp
@@ -117,6 +117,8 @@ namespace MWWorld
     void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
         bool adjustPlayerPos)
     {
+        bool hasWater = cell->cell->data.flags & cell->cell->HasWater;
+        mPhysics->setCurrentWater(hasWater, cell->cell->water);
         if (adjustPlayerPos)
             mWorld->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]);
 
diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 86d069273..214a7e598 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -1715,11 +1715,11 @@ void PM_SetWaterLevel( playerMove* const pm )
 	point[1] = pm->ps->origin[1];
 	point[2] = pm->ps->origin[2] + MINS_Z + 1;	*/
 	point.x = pm->ps.origin.x;
-	point.y = pm->ps.origin.y + MINS_Z + 1;
-	point.z = pm->ps.origin.z;
+	point.y = pm->ps.origin.y;
+	point.z = pm->ps.origin.z + MINS_Z + 1;
 
 	//cont = pm->pointcontents( point, pm->ps->clientNum );
-	bool checkWater = (pml.hasWater && pml.waterHeight > point.y);
+	bool checkWater = (pml.hasWater && pml.waterHeight > point.z);
 	//if ( cont & MASK_WATER ) 
 	if ( checkWater)
 	{
@@ -1729,14 +1729,14 @@ void PM_SetWaterLevel( playerMove* const pm )
 		pm->ps.watertype = CONTENTS_WATER;//cont;
 		pm->ps.waterlevel = WL_ANKLE;
 		//point[2] = pm->ps->origin[2] + MINS_Z + sample1;
-		point.y = pm->ps.origin.y + MINS_Z + sample1;
+		point.z = pm->ps.origin.z + MINS_Z + sample1;
 		//cont = pm->pointcontents (point, pm->ps->clientNum );
 		//if ( cont & MASK_WATER ) 
 		if (checkWater)
 		{
 			pm->ps.waterlevel = WL_WAIST;
 			//point[2] = pm->ps->origin[2] + MINS_Z + sample2;
-			point.y = pm->ps.origin.y + MINS_Z + sample2;
+			point.z = pm->ps.origin.z + MINS_Z + sample2;
 			//cont = pm->pointcontents (point, pm->ps->clientNum );
 			//if ( cont & MASK_WATER )
 			if (checkWater )

From 00260a24ce0c125582b48a1a2ca4d3457913cf5b Mon Sep 17 00:00:00 2001
From: Jason Hooks <jhooks1@mix.wvu.edu>
Date: Wed, 18 Apr 2012 21:28:25 -0400
Subject: [PATCH 09/20] Water corrections

---
 libs/openengine/bullet/pmove.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 214a7e598..7741d2f04 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -1730,6 +1730,7 @@ void PM_SetWaterLevel( playerMove* const pm )
 		pm->ps.waterlevel = WL_ANKLE;
 		//point[2] = pm->ps->origin[2] + MINS_Z + sample1;
 		point.z = pm->ps.origin.z + MINS_Z + sample1;
+        checkWater = (pml.hasWater && pml.waterHeight > point.z);
 		//cont = pm->pointcontents (point, pm->ps->clientNum );
 		//if ( cont & MASK_WATER ) 
 		if (checkWater)
@@ -1739,6 +1740,7 @@ void PM_SetWaterLevel( playerMove* const pm )
 			point.z = pm->ps.origin.z + MINS_Z + sample2;
 			//cont = pm->pointcontents (point, pm->ps->clientNum );
 			//if ( cont & MASK_WATER )
+            checkWater = (pml.hasWater && pml.waterHeight > point.z);
 			if (checkWater )
 				pm->ps.waterlevel = WL_UNDERWATER;
 		}

From 16855291a7c640d1b796448a529784299c1bd632 Mon Sep 17 00:00:00 2001
From: Jason Hooks <jhooks1@mix.wvu.edu>
Date: Sat, 21 Apr 2012 16:21:30 -0400
Subject: [PATCH 10/20] Implementing snapping

---
 apps/openmw/mwworld/physicssystem.cpp |  2 +
 libs/openengine/bullet/pmove.cpp      | 84 ++++++++++++++++-----------
 libs/openengine/bullet/pmove.h        |  7 ++-
 3 files changed, 58 insertions(+), 35 deletions(-)

diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp
index d224385ae..9af7a7285 100644
--- a/apps/openmw/mwworld/physicssystem.cpp
+++ b/apps/openmw/mwworld/physicssystem.cpp
@@ -27,6 +27,8 @@ namespace MWWorld
         NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
         mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
         playerphysics->mEngine = mEngine;
+        //playerphysics->ps.snappingImplemented = true;
+        
 		
     }
 
diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 7741d2f04..82f473085 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -417,7 +417,7 @@ int PM_StepSlideMove( bool gravity )
 	Ogre::Vector3		up, down;
 	float		stepSize;
 	
-
+    std::cout << "StepSlideMove\n";
 	// start_o = pm->ps->origin
 	//VectorCopy (pm->ps->origin, start_o);
 	start_o = pm->ps.origin;
@@ -516,6 +516,7 @@ int PM_StepSlideMove( bool gravity )
 		delta = pm->ps.origin.z - start_o.z;
 		if ( delta > 2 ) 
 		{
+            pm->ps.counter = 10;
 			if (gravity)
 				printf("g on: %f ", delta);
 			else
@@ -688,6 +689,7 @@ static bool PM_CheckJump(void)
 
 	pm->ps.groundEntityNum = ENTITYNUM_NONE;
 	pm->ps.velocity.z = JUMP_VELOCITY;
+    pm->ps.bSnap = false;
 	//PM_AddEvent( EV_JUMP );
 
 	/*if ( pm->cmd.forwardmove >= 0 ) 
@@ -840,7 +842,7 @@ static void PM_WalkMove( playerMove* const pmove )
 	playerMove::playercmd cmd;
 	float		accelerate;
 	float		vel;
-	
+	//pm->ps.gravity = 4000;
 
 	if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) 
 		pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f)
@@ -1142,9 +1144,7 @@ void PM_GroundTraceMissed()
 {
 	traceResults		trace;
 	Ogre::Vector3		point;
-
-	if ( pm->ps.groundEntityNum != ENTITYNUM_NONE ) 
-	{
+    std::cout << "Ground trace missed\n";
 		// we just transitioned into freefall
 		//if ( pm->debugLevel )
 			//Com_Printf("%i:lift\n", c_pmove);
@@ -1154,29 +1154,28 @@ void PM_GroundTraceMissed()
 		//VectorCopy( pm->ps->origin, point );
 		point = pm->ps.origin;
 		//point[2] -= 64;
-		point.z -= 64;
+		point.z -= 32;
 
 		//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
 		//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -64.0f, 0.0f), 0, pml.traceObj);
 		newtrace(&trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
-		if ( trace.fraction == 1.0 ) 
+		//It hit the ground below
+        if ( trace.fraction < 1.0 && pm->ps.origin.z > trace.endpos.z) 
 		{
-			if ( pm->cmd.forwardmove >= 0 ) 
-			{
-				//PM_ForceLegsAnim( LEGS_JUMP );
-				//pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP;
-			} 
-			else 
-			{
-				//PM_ForceLegsAnim( LEGS_JUMPB );
-				//pm->ps->pm_flags |= PMF_BACKWARDS_JUMP;
-			}
+			   pm->ps.origin = trace.endpos;
+               pml.walking = true;
+               pml.groundPlane = true;
+                pm->ps.groundEntityNum = trace.entityNum;
+           
 		}
-	}
+        else{
+        pm->ps.groundEntityNum = ENTITYNUM_NONE;
+	    pml.groundPlane = false;
+	    pml.walking = false;
+        pm->ps.bSnap = false;
+	    }
 
-	pm->ps.groundEntityNum = ENTITYNUM_NONE;
-	pml.groundPlane = false;
-	pml.walking = false;
+	
 }
 
 static bool PM_CorrectAllSolid(traceResults* const trace)
@@ -1404,19 +1403,26 @@ static void PM_GroundTrace( void )
 			return;
 		}
 	}
-
-	// if the trace didn't hit anything, we are in free fall
-	if ( trace.fraction == 1.0 ) 
+    // if the trace didn't hit anything, we are in free fall
+	if ( trace.fraction == 1.0) 
 	{
-		PM_GroundTraceMissed();
-		pml.groundPlane = false;
-		pml.walking = false;
+        if(pm->ps.snappingImplemented){
+            if(pm->ps.bSnap && pm->ps.counter <= 0)
+		        PM_GroundTraceMissed();
+        }
+            
+
 		return;
 	}
+    else
+    {
+        //It hit something, so we are on the ground
+        pm->ps.bSnap = true;
 
-	// check if getting thrown off the ground
+    }
+    // check if getting thrown off the ground
 	//if ( pm->ps->velocity[2] > 0 && DotProduct( pm->ps->velocity, trace.plane.normal ) > 10 ) 
-	if (pm->ps.velocity.z > 0 && pm->ps.velocity.dotProduct(trace.planenormal) > 10.0f)
+	if (pm->ps.velocity.z > 0 && pm->ps.velocity.dotProduct(trace.planenormal) > 10.0f )
 	{
 		//if ( pm->debugLevel ) 
 			//Com_Printf("%i:kickoff\n", c_pmove);
@@ -1432,13 +1438,22 @@ static void PM_GroundTrace( void )
 			PM_ForceLegsAnim( LEGS_JUMPB );
 			pm->ps->pm_flags |= PMF_BACKWARDS_JUMP;
 		}*/
-
+        if(!pm->ps.bSnap){
 		pm->ps.groundEntityNum = ENTITYNUM_NONE;
 		pml.groundPlane = false;
 		pml.walking = false;
+        }
+        else
+        {
+            pml.groundPlane = true;
+		    pml.walking = true;
+        }
 		return;
 	}
 	
+
+	
+	
 	// slopes that are too steep will not be considered onground
 	//if ( trace.plane.normal[2] < MIN_WALK_NORMAL ) 
 	if (trace.planenormal.z < MIN_WALK_NORMAL)
@@ -1500,7 +1515,7 @@ static void PM_AirMove()
 	float		wishspeed;
 	float		scale;
 	playerMove::playercmd	cmd;
-
+    //pm->ps.gravity = 800;
 	PM_Friction();
 
 	fmove = pm->cmd.forwardmove;
@@ -1508,7 +1523,6 @@ static void PM_AirMove()
 
 	cmd = pm->cmd;
 	scale = PM_CmdScale( &cmd );
-
 	// set the movementDir so clients can rotate the legs for strafing
 	//PM_SetMovementDir();
 
@@ -1749,7 +1763,7 @@ void PM_SetWaterLevel( playerMove* const pm )
 
 void PmoveSingle (playerMove* const pmove) 
 {
-	
+    pmove->ps.counter--;
 	//pm = pmove;
 
 	// Aedra doesn't support Q3-style VM traps D:	//while(1);
@@ -1763,6 +1777,10 @@ void PmoveSingle (playerMove* const pmove)
 	pm->ps.watertype = 0;
 	pm->ps.waterlevel = WL_DRYLAND;
 
+    if(pml.walking)
+        std::cout << "Walking\n";
+    else
+        std::cout << "Not Walking\n";
 	//if ( pm->ps->stats[STAT_HEALTH] <= 0 )
 		//pm->tracemask &= ~CONTENTS_BODY;	// corpses can fly through bodies
 		
diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h
index 304572b02..a14a1e660 100644
--- a/libs/openengine/bullet/pmove.h
+++ b/libs/openengine/bullet/pmove.h
@@ -42,7 +42,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
 #define	ENTITYNUM_NONE (MAX_GENTITIES - 1)
 #define ENTITYNUM_WORLD (MAX_GENTITIES - 2)
 #define	MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes
-#define	JUMP_VELOCITY (270 * 1)
+#define	JUMP_VELOCITY (270)
 #define PS_PMOVEFRAMECOUNTBITS 6
 #define	MINS_Z -24
 #define	DEFAULT_VIEWHEIGHT 26
@@ -90,7 +90,7 @@ struct playerMove
 {
 	struct playerStruct
 	{
-		playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0)
+		playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1)
 		{
 			origin = Ogre::Vector3(733.164f,900.0f, 839.432f);
 			velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f);
@@ -117,6 +117,9 @@ struct playerMove
 
 		Ogre::Vector3 velocity;
 		Ogre::Vector3 origin;
+        bool bSnap;
+        bool snappingImplemented;
+        int counter;
 		float gravity; // default = 800
 		float speed; // default = 320
 

From 8ebae0b7061ee3ef4056c5cbbd123c3917427725 Mon Sep 17 00:00:00 2001
From: Jason Hooks <jhooks1@mix.wvu.edu>
Date: Sat, 21 Apr 2012 16:57:46 -0400
Subject: [PATCH 11/20] Solid trace

---
 apps/openmw/mwworld/physicssystem.cpp | 2 +-
 libs/openengine/bullet/pmove.cpp      | 4 ----
 libs/openengine/bullet/trace.cpp      | 2 +-
 3 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp
index 9af7a7285..63bf8dda3 100644
--- a/apps/openmw/mwworld/physicssystem.cpp
+++ b/apps/openmw/mwworld/physicssystem.cpp
@@ -27,7 +27,7 @@ namespace MWWorld
         NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
         mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
         playerphysics->mEngine = mEngine;
-        //playerphysics->ps.snappingImplemented = true;
+      
         
 		
     }
diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 82f473085..922fd844c 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -1777,10 +1777,6 @@ void PmoveSingle (playerMove* const pmove)
 	pm->ps.watertype = 0;
 	pm->ps.waterlevel = WL_DRYLAND;
 
-    if(pml.walking)
-        std::cout << "Walking\n";
-    else
-        std::cout << "Not Walking\n";
 	//if ( pm->ps->stats[STAT_HEALTH] <= 0 )
 		//pm->tracemask &= ~CONTENTS_BODY;	// corpses can fly through bodies
 		
diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp
index ca68a5d5c..81c064c2d 100644
--- a/libs/openengine/bullet/trace.cpp
+++ b/libs/openengine/bullet/trace.cpp
@@ -172,7 +172,7 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
 			if (!TestPointAgainstAabb2(aabbMin, aabbMax, *(const btVector3* const)&(start) ) )
 			{
 				//We're solid
-				out->startSolid = false;
+				out->startSolid = true;
 			}
 		}
 	}

From 86b6184f438ad45b15c849a512b138910c70814c Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Mon, 30 Apr 2012 23:55:22 +0200
Subject: [PATCH 12/20] pMove in a seperate loop with fixed timestep to prevent
 frame-dependent movement

---
 apps/openmw/mwworld/physicssystem.cpp | 103 +++++++++++++-------------
 apps/openmw/mwworld/physicssystem.hpp |  10 ++-
 apps/openmw/mwworld/world.cpp         |  53 +++++++++----
 apps/openmw/mwworld/world.hpp         |   8 +-
 libs/openengine/bullet/physic.cpp     |   2 +-
 5 files changed, 102 insertions(+), 74 deletions(-)

diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp
index 7fe83eeab..fb13e37c6 100644
--- a/apps/openmw/mwworld/physicssystem.cpp
+++ b/apps/openmw/mwworld/physicssystem.cpp
@@ -21,27 +21,24 @@ namespace MWWorld
     PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
         mRender(_rend), mEngine(0), mFreeFly (true)
     {
-		
+
         playerphysics = new playerMove;
         // Create physics. shapeLoader is deleted by the physic engine
         NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
         mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
         playerphysics->mEngine = mEngine;
-      
-        
-		
     }
 
     PhysicsSystem::~PhysicsSystem()
     {
         delete mEngine;
-    
+
     }
     OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine()
     {
         return mEngine;
     }
-    
+
 	std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
 	{
 		std::string handle = "";
@@ -74,7 +71,7 @@ namespace MWWorld
         if(hasWater){
             playerphysics->waterHeight = waterHeight;
         }
-        
+
     }
 
     btVector3 PhysicsSystem::getRayPoint(float extent)
@@ -86,26 +83,23 @@ namespace MWWorld
         btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y);
         return result;
     }
-    
+
     bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to)
     {
         btVector3 _from, _to;
         _from = btVector3(from.x, from.y, from.z);
         _to = btVector3(to.x, to.y, to.z);
-        
+
         std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
-        
+
         return !(result.first == "");
     }
 
-
-    std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysics (float duration,
-        const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
+    void PhysicsSystem::doPhysics(float dt, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
     {
         //set the DebugRenderingMode. To disable it,set it to 0
         //eng->setDebugRenderingMode(1);
-		
-		
+
         //set the walkdirection to 0 (no movement) for every actor)
         for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
         {
@@ -117,8 +111,7 @@ namespace MWWorld
         pm_ref.rightmove = 0;
         pm_ref.forwardmove = 0;
         pm_ref.upmove = 0;
-		
-		
+
 		//playerphysics->ps.move_type = PM_NOCLIP;
         for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
             iter!=actors.end(); ++iter)
@@ -133,29 +126,24 @@ namespace MWWorld
             Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
             Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
 			Ogre::Quaternion yawQuat = yawNode->getOrientation();
-                Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
+            Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
 
-                // unused
-				//Ogre::Quaternion both = yawQuat * pitchQuat;
-				
-				playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
-				playerphysics->ps.viewangles.z = 0;
+            // unused
+            //Ogre::Quaternion both = yawQuat * pitchQuat;
+
+            playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
+            playerphysics->ps.viewangles.z = 0;
 			playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
 
-				
-				
-			
             if(mFreeFly)
             {
-                
                 Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
 
 				pm_ref.rightmove = -dir1.x;
 				pm_ref.forwardmove = dir1.z;
 				pm_ref.upmove = dir1.y;
 
-				
-				
+
 				//std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n";
 				//playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
 				//std::cout << "Pitch: " << yawQuat.getPitch() << "Yaw:" << yawQuat.getYaw() << "Roll: " << yawQuat.getRoll() << "\n";
@@ -163,46 +151,50 @@ namespace MWWorld
             }
             else
             {
-				
+
                 Ogre::Quaternion quat = yawNode->getOrientation();
                 Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
-				
+
 				pm_ref.rightmove = -dir1.x;
 				pm_ref.forwardmove = dir1.z;
 				pm_ref.upmove = dir1.y;
-				
-				
-				
+
+
+
                 dir = 0.025*(quat*dir1);
             }
-			
+
 
             //set the walk direction
             act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
         }
-        mEngine->stepSimulation(duration);
-		Pmove(playerphysics);
+        mEngine->stepSimulation(dt);
+    }
+
+    std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysicsFixed (
+        const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
+    {
+        Pmove(playerphysics);
 
-		
         std::vector< std::pair<std::string, Ogre::Vector3> > response;
         for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
         {
             btVector3 newPos = it->second->getPosition();
-			
-            Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z());
-			if(it->first == "player"){
-				
-				coord = playerphysics->ps.origin;
-				//std::cout << "ZCoord: " << coord.z << "\n";
-				//std::cout << "Coord" << coord << "\n";
-				//coord = Ogre::Vector3(coord.x, coord.z, coord.y);   //x, z, -y
-				
-			}
 
-			
+            Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z());
+            if(it->first == "player"){
+
+                coord = playerphysics->ps.origin;
+                //std::cout << "ZCoord: " << coord.z << "\n";
+                //std::cout << "Coord" << coord << "\n";
+                //coord = Ogre::Vector3(coord.x, coord.z, coord.y);   //x, z, -y
+
+            }
+
+
             response.push_back(std::pair<std::string, Ogre::Vector3>(it->first, coord));
         }
-		
+
         return response;
     }
 
@@ -260,7 +252,14 @@ namespace MWWorld
         {
             // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
             // start positions others than 0, 0, 0
-            act->setPosition(btVector3(position.x,position.y,position.z));
+            if (handle == "player")
+            {
+                playerphysics->ps.origin = position;
+            }
+            else
+            {
+                act->setPosition(btVector3(position.x,position.y,position.z));
+            }
         }
     }
 
@@ -316,7 +315,7 @@ namespace MWWorld
     }
 
      void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){
-		 
+
            Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
 
            // unused
diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp
index cb559f000..1af6bcca2 100644
--- a/apps/openmw/mwworld/physicssystem.hpp
+++ b/apps/openmw/mwworld/physicssystem.hpp
@@ -16,8 +16,11 @@ namespace MWWorld
             PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
             ~PhysicsSystem ();
 
-            std::vector< std::pair<std::string, Ogre::Vector3> > doPhysics (float duration,
-                const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
+            void doPhysics(float duration, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
+            ///< do physics with dt - Usage: first call doPhysics with frame dt, then call doPhysicsFixed as often as time steps have passed
+
+            std::vector< std::pair<std::string, Ogre::Vector3> > doPhysicsFixed (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
+            ///< do physics with fixed timestep - Usage: first call doPhysics with frame dt, then call doPhysicsFixed as often as time steps have passed
 
             void addObject (const std::string& handle, const std::string& mesh,
                 const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position);
@@ -55,7 +58,7 @@ namespace MWWorld
             void insertActorPhysics(const MWWorld::Ptr&, std::string model);
 
             OEngine::Physic::PhysicEngine* getEngine();
-            
+
             void setCurrentWater(bool hasWater, int waterHeight);
 
         private:
@@ -64,7 +67,6 @@ namespace MWWorld
             bool mFreeFly;
             playerMove* playerphysics;
 
-
             PhysicsSystem (const PhysicsSystem&);
             PhysicsSystem& operator= (const PhysicsSystem&);
     };
diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp
index 04bc999a0..adbdaece6 100644
--- a/apps/openmw/mwworld/world.cpp
+++ b/apps/openmw/mwworld/world.cpp
@@ -215,6 +215,7 @@ namespace MWWorld
 
         setFallbackValues(fallbackMap);
 
+        lastTick = mTimer.getMilliseconds();
     }
 
 
@@ -559,8 +560,9 @@ namespace MWWorld
         }
     }
 
-    void World::moveObjectImp (Ptr ptr, float x, float y, float z)
+    bool World::moveObjectImp (Ptr ptr, float x, float y, float z)
     {
+        bool ret = false;
         ptr.getRefData().getPosition().pos[0] = x;
         ptr.getRefData().getPosition().pos[1] = y;
         ptr.getRefData().getPosition().pos[2] = z;
@@ -582,6 +584,7 @@ namespace MWWorld
                     if (currentCell->cell->data.gridX!=cellX || currentCell->cell->data.gridY!=cellY)
                     {
                         mWorldScene->changeCell (cellX, cellY, mPlayer->getPlayer().getRefData().getPosition(), false);
+                        ret = true;
                     }
 
                 }
@@ -591,6 +594,8 @@ namespace MWWorld
         /// \todo cell change for non-player ref
 
         mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z));
+
+        return ret;
     }
 
     void World::moveObject (Ptr ptr, float x, float y, float z)
@@ -632,29 +637,45 @@ namespace MWWorld
     void World::doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
         float duration)
     {
-        std::vector< std::pair<std::string, Ogre::Vector3> > vectors = mPhysics->doPhysics (duration, actors);
+        mPhysics->doPhysics(duration, actors);
 
-        std::vector< std::pair<std::string, Ogre::Vector3> >::iterator player = vectors.end();
+        const int tick = 16; // 16 ms ^= 60 Hz
 
-        for (std::vector< std::pair<std::string, Ogre::Vector3> >::iterator it = vectors.begin();
-            it!= vectors.end(); ++it)
+        // Game clock part of the loop, contains everything that has to be executed in a fixed timestep
+        long long dt = mTimer.getMilliseconds() - lastTick;
+        if (dt >= 100) dt = 100; 	//  throw away wall clock time if necessary to keep the framerate above the minimum of 10 fps
+        while (dt >= tick)
         {
-            if (it->first=="player")
+            dt -= tick;
+            lastTick += tick;
+
+            std::vector< std::pair<std::string, Ogre::Vector3> > vectors = mPhysics->doPhysicsFixed (actors);
+
+            std::vector< std::pair<std::string, Ogre::Vector3> >::iterator player = vectors.end();
+
+            for (std::vector< std::pair<std::string, Ogre::Vector3> >::iterator it = vectors.begin();
+                it!= vectors.end(); ++it)
             {
-                player = it;
+                if (it->first=="player")
+                {
+                    player = it;
+                }
+                else
+                {
+                    MWWorld::Ptr ptr = getPtrViaHandle (it->first);
+                    moveObjectImp (ptr, it->second.x, it->second.y, it->second.z);
+                }
             }
-            else
+
+            // Make sure player is moved last (otherwise the cell might change in the middle of an update
+            // loop)
+            if (player!=vectors.end())
             {
-                MWWorld::Ptr ptr = getPtrViaHandle (it->first);
-                moveObjectImp (ptr, it->second.x, it->second.y, it->second.z);
+                if (moveObjectImp (getPtrViaHandle (player->first),
+                    player->second.x, player->second.y, player->second.z) == true)
+                    return; // abort the current loop if the cell has changed
             }
         }
-
-        // Make sure player is moved last (otherwise the cell might change in the middle of an update
-        // loop)
-        if (player!=vectors.end())
-            moveObjectImp (getPtrViaHandle (player->first),
-                player->second.x, player->second.y, player->second.z);
     }
 
     bool World::toggleCollisionMode()
diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp
index 77e5bcef6..7359f8b90 100644
--- a/apps/openmw/mwworld/world.hpp
+++ b/apps/openmw/mwworld/world.hpp
@@ -22,6 +22,8 @@
 #include <openengine/bullet/physic.hpp>
 #include <openengine/ogre/fader.hpp>
 
+#include <OgreTimer.h>
+
 namespace Ogre
 {
     class Vector3;
@@ -100,9 +102,13 @@ namespace MWWorld
             int mNumFacing;
             std::map<std::string,std::string> mFallback;
 
+            unsigned long lastTick;
+            Ogre::Timer mTimer;
+
             int getDaysPerMonth (int month) const;
 
-            void moveObjectImp (Ptr ptr, float x, float y, float z);
+            bool moveObjectImp (Ptr ptr, float x, float y, float z);
+            ///< @return true if the active cell (cell player is in) changed
 
         public:
 
diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp
index 3d507d4ee..42853d8cf 100644
--- a/libs/openengine/bullet/physic.cpp
+++ b/libs/openengine/bullet/physic.cpp
@@ -393,7 +393,7 @@ namespace Physic
 
     void PhysicEngine::stepSimulation(double deltaT)
     {
-        dynamicsWorld->stepSimulation(deltaT,10);
+        dynamicsWorld->stepSimulation(deltaT,10, 1/60.0);
         if(isDebugCreated)
         {
             mDebugDrawer->step();

From 6acb777c5a3f085f19314b0e599dec37e9958ceb Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Tue, 1 May 2012 20:51:32 +0200
Subject: [PATCH 13/20] minimum framerate fix

---
 apps/openmw/mwworld/world.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp
index adbdaece6..4adaf7918 100644
--- a/apps/openmw/mwworld/world.cpp
+++ b/apps/openmw/mwworld/world.cpp
@@ -643,7 +643,12 @@ namespace MWWorld
 
         // Game clock part of the loop, contains everything that has to be executed in a fixed timestep
         long long dt = mTimer.getMilliseconds() - lastTick;
-        if (dt >= 100) dt = 100; 	//  throw away wall clock time if necessary to keep the framerate above the minimum of 10 fps
+        if (dt >= 100)
+        {
+            //  throw away wall clock time if necessary to keep the framerate above the minimum of 10 fps
+            lastTick += (dt - 100);
+            dt = 100;
+        }
         while (dt >= tick)
         {
             dt -= tick;

From 7f15385dc5afa870723a0cf84079740a55ab2a2e Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Tue, 1 May 2012 20:58:09 +0200
Subject: [PATCH 14/20] unrelated cleanup

---
 apps/openmw/engine.cpp | 2 --
 apps/openmw/engine.hpp | 1 -
 2 files changed, 3 deletions(-)

diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp
index 539afe1c8..12a5956a9 100644
--- a/apps/openmw/engine.cpp
+++ b/apps/openmw/engine.cpp
@@ -148,7 +148,6 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
   , mNewGame (false)
   , mUseSound (true)
   , mCompileAll (false)
-  , mFocusTDiff (0)
   , mScriptContext (0)
   , mFSStrict (false)
   , mCfgMgr(configurationManager)
@@ -263,7 +262,6 @@ void OMW::Engine::setNewGame(bool newGame)
 
 void OMW::Engine::go()
 {
-    mFocusTDiff = 0;
     assert (!mCellName.empty());
     assert (!mMaster.empty());
     assert (!mOgre);
diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp
index c834ee438..09d6bc820 100644
--- a/apps/openmw/engine.hpp
+++ b/apps/openmw/engine.hpp
@@ -74,7 +74,6 @@ namespace OMW
             bool mNewGame;
             bool mUseSound;
             bool mCompileAll;
-            float mFocusTDiff;
             std::string mFocusName;
             std::map<std::string,std::string> mFallbackMap;
 

From a13f5423965871737c2fbf08e43de5116c4f1d86 Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Tue, 1 May 2012 21:01:18 +0200
Subject: [PATCH 15/20] disable snapping underwater

---
 libs/openengine/bullet/pmove.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index e215d8ff6..210f7eb70 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -717,6 +717,8 @@ static void PM_WaterMove( playerMove* const pm )
 	float	scale;
 	float	vel;
 
+    pm->ps.bSnap = false;
+
 	/*if ( PM_CheckWaterJump() ) 
 	{
 		PM_WaterJumpMove();

From 6850f3945c9ee82cd00d699e653582ce70ba93ef Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Tue, 1 May 2012 21:13:41 +0200
Subject: [PATCH 16/20] disable those physics debug prints

---
 libs/openengine/bullet/pmove.cpp | 16 +++++++++-------
 libs/openengine/bullet/pmove.h   |  4 ++--
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 210f7eb70..35bbd9c03 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -372,7 +372,7 @@ bool	PM_SlideMove( bool gravity )
 
 					// stop dead at a tripple plane interaction
 					//VectorClear( pm->ps->velocity );
-					printf("Stop dead at a triple plane interaction\n");
+					//printf("Stop dead at a triple plane interaction\n");
 					pm->ps.velocity = Ogre::Vector3(0,0,0);
 					return true;
 				}
@@ -417,7 +417,7 @@ int PM_StepSlideMove( bool gravity )
 	Ogre::Vector3		up, down;
 	float		stepSize;
 	
-    std::cout << "StepSlideMove\n";
+    //std::cout << "StepSlideMove\n";
 	// start_o = pm->ps->origin
 	//VectorCopy (pm->ps->origin, start_o);
 	start_o = pm->ps.origin;
@@ -517,6 +517,8 @@ int PM_StepSlideMove( bool gravity )
 		if ( delta > 2 ) 
 		{
             pm->ps.counter = 10;
+
+            /*
 			if (gravity)
 				printf("g on: %f ", delta);
 			else
@@ -534,7 +536,7 @@ int PM_StepSlideMove( bool gravity )
 			else 
 				printf("stepped 15+\n");
 				//PM_AddEvent( EV_STEP_16 );
-				
+            */
 		}
 		/*if ( pm->debugLevel )
 			Com_Printf("%i:stepped\n", c_pmove);*/
@@ -863,7 +865,7 @@ static void PM_WalkMove( playerMove* const pmove )
 			PM_WaterMove(pmove);
 		else
 			PM_AirMove();
-		printf("Jumped away\n");
+		//printf("Jumped away\n");
 		return;
 	}
 
@@ -1146,7 +1148,7 @@ void PM_GroundTraceMissed()
 {
 	traceResults		trace;
 	Ogre::Vector3		point;
-    std::cout << "Ground trace missed\n";
+    //std::cout << "Ground trace missed\n";
 		// we just transitioned into freefall
 		//if ( pm->debugLevel )
 			//Com_Printf("%i:lift\n", c_pmove);
@@ -1292,14 +1294,14 @@ static void PM_CrashLand( void )
 
 	if ( delta < 1 ) 
 		return;
-
+/*
 	if (delta > 60)
 		printf("Far crashland: %f\n", delta);
 	else if (delta > 40)
 		printf("Medium crashland: %f\n", delta);
 	else if (delta > 4)
 		printf("Short crashland: %f\n", delta);
-
+*/
 	if (delta > 60)
 	{
 		/*
diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h
index 2c61b3e7d..e46eb9d2e 100644
--- a/libs/openengine/bullet/pmove.h
+++ b/libs/openengine/bullet/pmove.h
@@ -105,13 +105,13 @@ struct playerMove
 
 		inline void SpeedUp(void)
 		{
-			printf("speed up to: %f\n", speed);
+			//printf("speed up to: %f\n", speed);
 			speed *= 1.25f;
 		}
 
 		inline void SpeedDown(void)
 		{
-			printf("speed down to %f\n", speed);
+			//printf("speed down to %f\n", speed);
 			speed /= 1.25f;
 		}
 

From 04ead5eb42e67b1346f8e5055d16d37d8fa06741 Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Tue, 1 May 2012 21:22:15 +0200
Subject: [PATCH 17/20] make the no-clip mode move much faster

---
 libs/openengine/bullet/pmove.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp
index 35bbd9c03..591f1869f 100644
--- a/libs/openengine/bullet/pmove.cpp
+++ b/libs/openengine/bullet/pmove.cpp
@@ -636,7 +636,7 @@ float PM_CmdScale(playerMove::playercmd* const cmd)
 		+ cmd->rightmove * cmd->rightmove + cmd->upmove * cmd->upmove) );
 	scale = (float)pm->ps.speed * max / ( 127.0f * total );
     if(pm->ps.move_type == PM_NOCLIP)
-        scale *= 2;
+        scale *= 10;
 
 	return scale;
 }

From c4b63bdb2fdb98afc809778c1c06a87119c02ffc Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Wed, 2 May 2012 23:27:56 +0200
Subject: [PATCH 18/20] .gitmodules

---
 libs/openengine/.gitmodules | 3 ---
 1 file changed, 3 deletions(-)
 delete mode 100644 libs/openengine/.gitmodules

diff --git a/libs/openengine/.gitmodules b/libs/openengine/.gitmodules
deleted file mode 100644
index 0a9a9121f..000000000
--- a/libs/openengine/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "mangle"]
-	path = mangle
-	url = git://github.com/korslund/mangle

From dc378fc6cfc5e0ad01a7cf6d8e636ed7b32f06fb Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Thu, 3 May 2012 06:07:41 +0200
Subject: [PATCH 19/20] allow talking with creatures

---
 apps/openmw/mwdialogue/dialoguemanager.cpp | 48 ++++++++++++++++++----
 1 file changed, 40 insertions(+), 8 deletions(-)

diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp
index ac41244d1..282fba354 100644
--- a/apps/openmw/mwdialogue/dialoguemanager.cpp
+++ b/apps/openmw/mwdialogue/dialoguemanager.cpp
@@ -161,6 +161,8 @@ namespace MWDialogue
 
     bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice)
     {
+        bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
+
         for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.selects.begin());
             iter != info.selects.end(); ++iter)
         {
@@ -195,6 +197,9 @@ namespace MWDialogue
 
                 case 46://Same faction
                     {
+                    if (isCreature)
+                        return false;
+
                     MWMechanics::NpcStats PCstats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
                     MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor);
                     int sameFaction = 0;
@@ -283,6 +288,8 @@ namespace MWDialogue
     bool DialogueManager::isMatching (const MWWorld::Ptr& actor,
         const ESM::DialInfo::SelectStruct& select) const
     {
+        bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
+
         char type = select.selectRule[1];
 
         if (type!='0')
@@ -380,6 +387,9 @@ namespace MWDialogue
                 return true;
 
             case '8':// not faction
+                if (isCreature)
+                    return false;
+
                 if(select.type==ESM::VT_Int)
                 {
                     ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
@@ -394,6 +404,9 @@ namespace MWDialogue
                 return true;
 
             case '9':// not class
+                if (isCreature)
+                    return false;
+
                 if(select.type==ESM::VT_Int)
                 {
                     ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
@@ -408,6 +421,9 @@ namespace MWDialogue
                 return true;
 
             case 'A'://not Race
+                if (isCreature)
+                    return false;
+
                 if(select.type==ESM::VT_Int)
                 {
                     ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
@@ -464,6 +480,8 @@ namespace MWDialogue
 
     bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const
     {
+        bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
+
         // actor id
         if (!info.actor.empty())
             if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor))
@@ -472,6 +490,9 @@ namespace MWDialogue
         //NPC race
         if (!info.race.empty())
         {
+            if (isCreature)
+                return false;
+
             ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
 
             if (!cellRef)
@@ -484,6 +505,9 @@ namespace MWDialogue
         //NPC class
         if (!info.clas.empty())
         {
+            if (isCreature)
+                return false;
+
             ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
 
             if (!cellRef)
@@ -496,6 +520,9 @@ namespace MWDialogue
         //NPC faction
         if (!info.npcFaction.empty())
         {
+            if (isCreature)
+                return false;
+
             //MWWorld::Class npcClass = MWWorld::Class::get(actor);
             MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor);
             std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.npcFaction);
@@ -529,16 +556,18 @@ namespace MWDialogue
         }
 
         //check gender
-        ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
-        if(npc->base->flags&npc->base->Female)
+        if (!isCreature)
         {
-            if(static_cast<int> (info.data.gender)==0)  return false;
+            ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
+            if(npc->base->flags&npc->base->Female)
+            {
+                if(static_cast<int> (info.data.gender)==0)  return false;
+            }
+            else
+            {
+                if(static_cast<int> (info.data.gender)==1)  return false;
+            }
         }
-        else
-        {
-            if(static_cast<int> (info.data.gender)==1)  return false;
-        }
-
 
         // check cell
         if (!info.cell.empty())
@@ -839,6 +868,9 @@ namespace MWDialogue
 
     std::string DialogueManager::getFaction()
     {
+        if (mActor.getTypeName() != typeid(ESM::NPC).name())
+            return "";
+
         std::string factionID("");
         MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
         if(stats.mFactionRank.empty())

From b653f047acfbe61f0d7b4b21f8548e1ee3202c5a Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Thu, 3 May 2012 09:15:56 +0200
Subject: [PATCH 20/20] removed a file that wasn't supposed to be there

---
 apps/openmw/physicssystem.cpp | 225 ----------------------------------
 1 file changed, 225 deletions(-)
 delete mode 100644 apps/openmw/physicssystem.cpp

diff --git a/apps/openmw/physicssystem.cpp b/apps/openmw/physicssystem.cpp
deleted file mode 100644
index a07358f8e..000000000
--- a/apps/openmw/physicssystem.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-#include <stdexcept>
-
-#include "physicssystem.hpp"
-#include "../mwworld/ptr.hpp"
-#include "../mwworld/world.hpp" // FIXME
-#include <components/nifbullet/bullet_nif_loader.hpp>
-
-#include "OgreRoot.h"
-#include "OgreRenderWindow.h"
-#include "OgreSceneManager.h"
-#include "OgreViewport.h"
-#include "OgreCamera.h"
-#include "OgreTextureManager.h"
-
-
-using namespace Ogre;
-namespace MWWorld
-{
-
-    PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
-        mRender(_rend), mEngine(0), mFreeFly (true)
-    {
-        // Create physics. shapeLoader is deleted by the physic engine
-        NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
-        mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
-    }
-
-    PhysicsSystem::~PhysicsSystem()
-    {
-        delete mEngine;
-    
-    }
-    OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine()
-    {
-        return mEngine;
-    }
-    
-	std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
-	{
-		std::string handle = "";
-
-        //get a ray pointing to the center of the viewport
-        Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
-        mRender.getViewport()->getWidth()/2,
-        mRender.getViewport()->getHeight()/2);
-        //let's avoid the capsule shape of the player.
-        centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection());
-        btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y);
-        btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y);
-
-        return mEngine->rayTest(from,to);
-    }
-    
-    bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to)
-    {
-        btVector3 _from, _to;
-        _from = btVector3(from.x, from.y, from.z);
-        _to = btVector3(to.x, to.y, to.z);
-        
-        std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
-        
-        return !(result.first == "");
-    }
-
-
-    std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysics (float duration,
-        const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
-    {
-        //set the DebugRenderingMode. To disable it,set it to 0
-        //eng->setDebugRenderingMode(1);
-
-        //set the walkdirection to 0 (no movement) for every actor)
-        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
-        {
-            OEngine::Physic::PhysicActor* act = it->second;
-            act->setWalkDirection(btVector3(0,0,0));
-        }
-
-        for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
-            iter!=actors.end(); ++iter)
-        {
-            OEngine::Physic::PhysicActor* act = mEngine->getCharacter(iter->first);
-
-            //dirty stuff to get the camera orientation. Must be changed!
-
-            Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first);
-            Ogre::Vector3 dir;
-            Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
-            Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
-            if(mFreeFly)
-            {
-                Ogre::Quaternion yawQuat = yawNode->getOrientation();
-                Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
-                Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
-                dir = 0.07*(yawQuat*pitchQuat*dir1);
-            }
-            else
-            {
-                Ogre::Quaternion quat = yawNode->getOrientation();
-                Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
-                dir = 0.025*(quat*dir1);
-            }
-
-            //set the walk direction
-            act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
-        }
-        mEngine->stepSimulation(duration);
-
-        std::vector< std::pair<std::string, Ogre::Vector3> > response;
-        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
-        {
-            btVector3 newPos = it->second->getPosition();
-            Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z());
-
-            response.push_back(std::pair<std::string, Ogre::Vector3>(it->first, coord));
-        }
-        return response;
-    }
-
-    void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh,
-        const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
-    {
-        OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale);
-        mEngine->addRigidBody(body);
-        btTransform tr;
-        tr.setOrigin(btVector3(position.x,position.y,position.z));
-		std::cout << "Position object:" << position << "\n";
-        tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w));
-        body->setWorldTransform(tr);
-    }
-
-    void PhysicsSystem::addActor (const std::string& handle, const std::string& mesh,
-        const Ogre::Vector3& position)
-    {
-        //TODO:optimize this. Searching the std::map isn't very efficient i think.
-        mEngine->addCharacter(handle);
-        OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle);
-        act->setPosition(btVector3(position.x,position.y,position.z));
-    }
-
-    void PhysicsSystem::removeObject (const std::string& handle)
-    {
-        //TODO:check if actor???
-        mEngine->removeCharacter(handle);
-        mEngine->removeRigidBody(handle);
-        mEngine->deleteRigidBody(handle);
-    }
-
-    void PhysicsSystem::moveObject (const std::string& handle, const Ogre::Vector3& position)
-    {
-        if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
-        {
-            // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
-            // start positions others than 0, 0, 0
-            btTransform tr = body->getWorldTransform();
-            tr.setOrigin(btVector3(position.x,position.y,position.z));
-            body->setWorldTransform(tr);
-        }
-        if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
-        {
-            // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
-            // start positions others than 0, 0, 0
-            act->setPosition(btVector3(position.x,position.y,position.z));
-        }
-    }
-
-    void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation)
-    {
-         if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
-        {
-            // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
-            // start positions others than 0, 0, 0
-            act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
-        }
-    }
-
-    void PhysicsSystem::scaleObject (const std::string& handle, float scale)
-    {
-
-    }
-
-    bool PhysicsSystem::toggleCollisionMode()
-    {
-        for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
-        {
-            if (it->first=="player")
-            {
-                OEngine::Physic::PhysicActor* act = it->second;
-
-                bool cmode = act->getCollisionMode();
-                if(cmode)
-                {
-                    act->enableCollisions(false);
-                    act->setGravity(0.);
-                    act->setVerticalVelocity(0);
-                    mFreeFly = true;
-                    return false;
-                }
-                else
-                {
-                    mFreeFly = false;
-                    act->enableCollisions(true);
-                    act->setGravity(4.);
-                    act->setVerticalVelocity(0);
-                    return true;
-                }
-            }
-        }
-
-        throw std::logic_error ("can't find player");
-    }
-
-     void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){
-           Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
-         addObject (node->getName(), model, node->getOrientation(),
-            node->getScale().x, node->getPosition());
-     }
-
-     void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){
-           Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
-            // std::cout << "Adding node with name" << node->getName();
-         addActor (node->getName(), model, node->getPosition());
-     }
-
-}