diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index 22ee2371e8ce753901030c4f17ded590a198d025..0289ec42d748ad0e56409043cae02af302d12ddb 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -166,28 +166,18 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
 	
 	// result = true if animation has to be continued, false if animation stops
 	// maybe there are events for us in the queue !
-	if (frame)
+	
+	for (vector<CValue*>::iterator i=m_events.end(); !(i==m_events.begin());)
 	{
-		for (vector<CValue*>::iterator i=m_events.end(); !(i==m_events.begin());)
-		{
-			i--;
-			if ((*i)->GetNumber() == 0.0f)
-				bNegativeEvent = true;
-			else
-				bPositiveEvent= true;
-			(*i)->Release();
-			m_events.pop_back();
-		}
-		
-		if (bPositiveEvent)
-			m_flag |= ACT_FLAG_ACTIVE;
-		
-		if (bNegativeEvent)
+		i--;
+		if ((*i)->GetNumber() == 0.0f)
 		{
-			if (!(m_flag & ACT_FLAG_ACTIVE))
-				return false;
-			m_flag &= ~ACT_FLAG_ACTIVE;
+			bNegativeEvent = true;
 		}
+		else
+			bPositiveEvent= true;
+		(*i)->Release();
+		m_events.pop_back();
 	}
 	
 	/*	We know that action actuators have been discarded from all non armature objects:
@@ -246,7 +236,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
 			if (!(m_flag & ACT_FLAG_LOCKINPUT)){
 				m_flag &= ~ACT_FLAG_REVERSE;
 				m_flag |= ACT_FLAG_LOCKINPUT;
-				SetStartTime(curtime);
+				m_starttime = curtime;
 			}
 		}
 		else if (bNegativeEvent){
@@ -334,7 +324,6 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
 				m_localtime = m_endframe;
 				m_flag &= ~ACT_FLAG_LOCKINPUT;
 			}
-			SetStartTime(curtime);
 		}
 		break;
 	case ACT_ACTION_PLAY:
diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h
index 1c3f57e965a51b05e85d45a1e506c1c5afaa91aa..0c1eb780bcbea2efa2e4cff57ca3b4ef2e427292 100644
--- a/source/gameengine/Converter/BL_ActionActuator.h
+++ b/source/gameengine/Converter/BL_ActionActuator.h
@@ -52,22 +52,22 @@ public:
 						PyTypeObject* T=&Type) 
 		: SCA_IActuator(gameobj,T),
 		
-		m_lastpos(0, 0, 0),
 		m_blendframe(0),
+		m_lastpos(0, 0, 0),
 		m_flag(0),
 		m_startframe (starttime),
 		m_endframe(endtime) ,
 		m_localtime(starttime),
 		m_lastUpdate(-1),
-		m_blendin(blendin),
-		m_stridelength(stride),
 		m_playtype(playtype),
+		m_blendin(blendin),
 		m_priority(priority),
+		m_stridelength(stride),
 		m_pose(NULL),
 		m_blendpose(NULL),
 		m_userpose(NULL),
-		m_action(action),
-		m_propname(propname)
+		m_propname(propname), 
+		m_action(action)
 	{
 	};
 	virtual ~BL_ActionActuator();
@@ -115,8 +115,8 @@ protected:
 	void SetLocalTime(float curtime);
 	bool ClampLocalTime();
 
-	MT_Point3	m_lastpos;
 	float	m_blendframe;
+	MT_Point3	m_lastpos;
 	int		m_flag;
 	/** The frame this action starts */
 	float	m_startframe;
@@ -128,23 +128,23 @@ protected:
 	float	m_localtime;
 	
 	float	m_lastUpdate;
+	short	m_playtype;
 	float	m_blendin;
 	float	m_blendstart;
-	float	m_stridelength;
-	short	m_playtype;
 	short	m_priority;
+	float	m_stridelength;
 	struct bPose* m_pose;
 	struct bPose* m_blendpose;
 	struct bPose* m_userpose;
-	struct bAction *m_action;
 	STR_String	m_propname;
+	struct bAction *m_action;
+
 };
 
 enum {
 	ACT_FLAG_REVERSE	= 0x00000001,
 	ACT_FLAG_LOCKINPUT	= 0x00000002,
-	ACT_FLAG_KEYUP		= 0x00000004,
-	ACT_FLAG_ACTIVE		= 0x00000008
+	ACT_FLAG_KEYUP		= 0x00000004
 };
 
 #endif
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp
index df4a5047ef134492e69ae6f0d1723423c7a41196..ea9fe8554ccf178cc0a01157b1fae9e4f6af6b79 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.cpp
+++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp
@@ -112,13 +112,14 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
 	m_endframe(endtime),
 	m_recurse(recurse),
 	m_localtime(starttime),
+	m_starttime(-1.0),
 	m_direction(1),
 	m_propname(propname),
 	m_ipo_as_force(ipo_as_force),
 	m_force_ipo_local(force_ipo_local),
 	m_type((IpoActType)acttype)
 {
-	m_starttime = -2.0*fabs(m_endframe - m_startframe) - 1.0;
+	// intentionally empty
 }
 
 void KX_IpoActuator::SetStart(float starttime) 
@@ -188,11 +189,10 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
 	// result = true if animation has to be continued, false if animation stops
 	// maybe there are events for us in the queue !
 	bool bNegativeEvent = false;
-	int numevents = 0;
+	int numevents = m_events.size();
 
 	if (frame)
 	{
-		numevents = m_events.size();
 		for (vector<CValue*>::iterator i=m_events.end(); !(i==m_events.begin());)
 		{
 			--i;
@@ -204,13 +204,15 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
 		m_events.clear();
 	
 		if (bNegativeEvent)
+		{
 			RemoveAllEvents();
+		}
 	}
 	
 	double  start_smaller_then_end = ( m_startframe < m_endframe ? 1.0 : -1.0);
 
 	bool result=true;
-	if (m_starttime < -2.0*start_smaller_then_end*(m_endframe - m_startframe))
+	if (m_starttime < 0.0)
 		m_starttime = curtime;
 	
 	switch (m_type)
@@ -271,7 +273,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
 	}
 	case KX_ACT_IPO_FLIPPER:
 	{
-		result = !(bNegativeEvent && (m_localtime == m_startframe));
+		result = true;
 		if (numevents)
 		{
 			if (bNegativeEvent)
@@ -367,7 +369,20 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
 		CValue* propval = GetParent()->GetProperty(m_propname);
 		if (propval)
 		{
-			m_localtime = propval->GetNumber(); 
+			float target = propval->GetNumber(); 
+			float delta_time = (curtime - m_starttime)*KX_FIXED_FRAME_PER_SEC;
+			if (target > m_localtime)
+			{
+				m_localtime += delta_time;
+				if (m_localtime > target)
+					m_localtime = target;
+			}
+			else
+			{
+				m_localtime -= delta_time;
+				if (m_localtime < target)
+					m_localtime = target;
+			}
 	
 			CIpoAction ipoaction(
 				(KX_GameObject*) GetParent(),
@@ -389,7 +404,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
 	}
 	
 	if (!result && m_type != KX_ACT_IPO_LOOPSTOP)
-		m_starttime = -2.0*start_smaller_then_end*(m_endframe - m_startframe) - 1.0;
+		m_starttime = -1.0;
 
 	return result;
 }
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index af75e3493c18f6fe3911b1d167469ab6784156f3..f74cdc31fcdaa76cebe5f60c68fb5357f34fb152 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -83,7 +83,7 @@
 // not valid, skip rendering this frame.
 //#define NZC_GUARDED_OUTPUT
 #define DEFAULT_LOGIC_TIC_RATE 30.0
-#define DEFAULT_PHYSICS_TIC_RATE 90.0
+#define DEFAULT_PHYSICS_TIC_RATE 60.0
 
 const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = {
 	"Physics:",		// tc_physics
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 09e4ae7bbb17f98d42206fbadc8eb002153694d5..26825fe5e1f372b7278cd3de41f2d23177616276 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -600,23 +600,21 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
 
 	MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
 	replica->NodeSetLocalOrientation(newori);
-	
-	// get the rootnode's scale
-	MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
-
-	// set the replica's relative scale with the rootnode's scale
-	replica->NodeSetRelativeScale(newscale);
 
 	if (replica->GetPhysicsController())
 	{
 		replica->GetPhysicsController()->setPosition(newpos);
 		replica->GetPhysicsController()->setOrientation(newori.getRotation());
-		replica->GetPhysicsController()->setScaling(newscale);
 	}
 
 	// here we want to set the relative scale: the rootnode's scale will override all other
 	// scalings, so lets better prepare for it
 
+	// get the rootnode's scale
+	MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
+
+	// set the replica's relative scale with the rootnode's scale
+	replica->NodeSetRelativeScale(newscale);
 
 	replica->GetSGNode()->UpdateWorldData(0);
 	replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h
index 08e29265d0c0ee956820f6a31f5aab2bc801abde..b0e0717cf8cf8b1e16513d593b50812ef9178062 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h
@@ -61,7 +61,6 @@ public:
 	void integrateBackward(MT_Scalar timeStep, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel);
 	void integrateForward(MT_Scalar timeStep, const SM_MotionState &prev_state);
 	
-	void lerp(const SM_MotionState &prev, const SM_MotionState &next);
 	void lerp(MT_Scalar t, const SM_MotionState &other);
 	
 	virtual MT_Transform getTransform() const {
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
index 07eb5a7637fa8bc3d6e461324400681a4f803e50..b37e1a5466b0d4848ed7572c933d614176272331 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
@@ -81,8 +81,7 @@ public:
  * It encapsulates an object in the physics scene, and is responsible
  * for calculating the collision response of objects.
  */
-class SM_Object 
-{
+class SM_Object : public SM_MotionState {
 public:
 	SM_Object() ;
 	SM_Object(
@@ -267,29 +266,7 @@ public:
 	
 	void relax();
 	
-	SM_MotionState &getCurrentFrame();
-	SM_MotionState &getPreviousFrame();
-	SM_MotionState &getNextFrame();
-	
-	const SM_MotionState &getCurrentFrame()   const;
-	const SM_MotionState &getPreviousFrame()  const;
-	const SM_MotionState &getNextFrame()      const;
-
-	// Motion state functions	
-	const MT_Point3&     getPosition()        const;
-	const MT_Quaternion& getOrientation()     const;
-	const MT_Vector3&    getLinearVelocity()  const;
-	const MT_Vector3&    getAngularVelocity() const;
-	
-	MT_Scalar            getTime()            const;
-	
-	void setTime(MT_Scalar time);
-	
-	void interpolate(MT_Scalar timeStep);
-	void endFrame();
-	
 private:
-	friend class Contact;
 	// Tweak parameters
 	static MT_Scalar ImpulseThreshold;
 
@@ -347,12 +324,14 @@ private:
 	MT_Vector3              m_reaction_impulse;      // The accumulated impulse resulting from collisions
 	MT_Vector3              m_reaction_force;        // The reaction force derived from the reaction impulse   
 
+	unsigned int            m_kinematic      : 1;    // Have I been displaced (translated, rotated, scaled) in this frame? 
+	unsigned int            m_prev_kinematic : 1;    // Have I been displaced (translated, rotated, scaled) in the previous frame? 
+	unsigned int            m_is_rigid_body  : 1;    // Should friction give me a change in angular momentum?
+
 	MT_Vector3              m_lin_mom;               // Linear momentum (linear velocity times mass)
 	MT_Vector3              m_ang_mom;               // Angular momentum (angualr velocity times inertia)
 	MT_Vector3              m_force;                 // Force on center of mass (afffects linear momentum)
-	MT_Vector3              m_torque;                // Torque around center of mass (affects angular momentum)
-	
-	SM_MotionState          m_frames[3];             
+	MT_Vector3              m_torque;                // Torque around center of mass (affects angualr momentum)
 	
 	MT_Vector3              m_error;                 // Error in position:- amount object must be moved to prevent intersection with scene
 
@@ -376,12 +355,6 @@ private:
 	MT_Scalar               m_inv_mass;              // 1/mass
 	MT_Vector3              m_inv_inertia;           // [1/inertia_x, 1/inertia_y, 1/inertia_z]
 	MT_Matrix3x3            m_inv_inertia_tensor;    // Inverse Inertia Tensor
-	
-	bool                    m_kinematic;             // Have I been displaced (translated, rotated, scaled) in this frame? 
-	bool                    m_prev_kinematic;        // Have I been displaced (translated, rotated, scaled) in the previous frame? 
-	bool                    m_is_rigid_body;         // Should friction give me a change in angular momentum?
-	int                     m_static;                // temporarily static.
-
 };
 
 #endif
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
index a0d5c983031dbcb964603aeee6605e6a962d992f..80e8c635cbb0fdd11e5f99f36f2b927d4b40bac4 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
@@ -104,7 +104,6 @@ public:
 	// 'subSampling' can be used to control aliasing effects
 	// (fast moving objects traversing through walls and such). 
 	bool proceed(MT_Scalar curtime, MT_Scalar ticrate);
-	void proceed(MT_Scalar subStep);
 
 	/**
 	 * Test whether any objects lie on the line defined by from and
@@ -168,7 +167,7 @@ private:
 	 * collision tests. */
 	T_ObjectList        m_objectList;
 	
-	unsigned int        m_frames;
+	MT_Scalar           m_lastTime;
 };
 
 #endif
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp
index 1fadbdadfa02f2ca46942c119fd40eb999253e29..a3285b191165f6a95fa28720c8be9dccc001b989 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp
@@ -29,7 +29,7 @@
  *
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
  */
-#include <MT_Scalar.h>
+
 #include <MT_Vector3.h>
 #include <MT_Quaternion.h>
  
@@ -56,47 +56,15 @@ void SM_MotionState::integrateForward(MT_Scalar timeStep, const SM_MotionState &
 	m_orn.normalize();
 }
 
-/*
-// Newtonian lerp: interpolate based on Newtonian motion
-void SM_MotionState::nlerp(const SM_MotionState &prev, const SM_MotionState &next)
-{
-	MT_Scalar dt = next.getTime() - prev.getTime();
-	MT_Scalar t = getTime() - prev.getTime();
-	MT_Vector3 dx = next.getPosition() - prev.getPosition();
-	MT_Vector3 a = dx/(dt*dt) - prev.getLinearVelocity()/dt;
-	
-	m_pos = prev.getPosition() + prev.getLinearVelocity()*t + a*t*t;
-}
-*/
-
-void SM_MotionState::lerp(const SM_MotionState &prev, const SM_MotionState &next)
-{
-	MT_Scalar dt = next.getTime() - prev.getTime();
-	if (MT_fuzzyZero(dt))
-	{
-		*this = next;
-		return;
-	}
-	
-	MT_Scalar x = (getTime() - prev.getTime())/dt;
-	
-	m_pos = x*next.getPosition() + (1-x)*prev.getPosition();
-	
-	m_orn = prev.getOrientation().slerp(next.getOrientation(), 1-x);
-	
-	m_lin_vel = x*next.getLinearVelocity() + (1-x)*prev.getLinearVelocity();
-	m_ang_vel = x*next.getAngularVelocity() + (1-x)*prev.getAngularVelocity();
-}
-
 void SM_MotionState::lerp(MT_Scalar t, const SM_MotionState &other)
 {
 	MT_Scalar x = (t - getTime())/(other.getTime() - getTime());
-	m_pos = (1-x)*m_pos + x*other.getPosition();
+	m_pos = x*m_pos + (1-x)*other.getPosition();
 	
-	m_orn =  other.getOrientation().slerp(m_orn, x);
+	m_orn = m_orn.slerp(other.getOrientation(), x);
 	
-	m_lin_vel = (1-x)*m_lin_vel + x*other.getLinearVelocity();
-	m_ang_vel = (1-x)*m_ang_vel + x*other.getAngularVelocity();
+	m_lin_vel = x*m_lin_vel + (1-x)*other.getLinearVelocity();
+	m_ang_vel = x*m_ang_vel + (1-x)*other.getAngularVelocity();
 	
 	m_time = t;
 }
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
index 26687663006f69a49b6005b5a688475c69f94048..ed5171a87a27589b66e20eabbd8500b76801674a 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
@@ -49,95 +49,7 @@
 
 #include "MT_MinMax.h"
 
-MT_Scalar SM_Object::ImpulseThreshold = -1.0;
-
-struct Contact
-{
-	SM_Object *obj1;
-	SM_Object *obj2;
-	MT_Vector3 normal;
-	MT_Point3 pos;
-	
-	// Sort objects by height
-	bool operator()(const Contact *a, const Contact *b)
-	{
-		return a->pos[2] < b->pos[2];
-	}
-	
-	Contact(SM_Object *o1, SM_Object *o2, const MT_Vector3 nor, const MT_Point3 p)
-		: obj1(o1),
-		  obj2(o2),
-		  normal(nor),
-		  pos(p)
-	{
-	}
-	
-	Contact()
-	{
-	}
-	
-	void resolve()
-	{
-		if (obj1->m_static || obj2->m_static)
-		{
-			if (obj1->isDynamic())
-			{
-				if (obj1->m_static && obj2->m_static)
-				{
-					if (obj1->m_static < obj2->m_static)
-					{
-						obj2->m_error -= normal;
-						obj2->m_static = obj1->m_static + 1;
-					}
-					else
-					{
-						obj1->m_error += normal;
-						obj1->m_static = obj2->m_static + 1;
-					}
-				}
-				else
-				{
-					if (obj1->m_static)
-					{
-						obj2->m_error -= normal;
-						obj2->m_static = obj1->m_static + 1;
-					}
-					else
-					{
-						obj1->m_error += normal;
-						obj1->m_static = obj2->m_static + 1;
-					}
-				}
-			}
-			else
-			{
-				obj2->m_error -= normal;
-				obj2->m_static = 1;
-			}
-		}
-		else
-		{
-			// This distinction between dynamic and non-dynamic objects should not be 
-			// necessary. Non-dynamic objects are assumed to have infinite mass.
-			if (obj1->isDynamic()) {
-				MT_Vector3 error = normal * 0.5f;
-				obj1->m_error += error;
-				obj2->m_error -= error;
-			}
-			else {
-				// Same again but now obj1 is non-dynamic
-				obj2->m_error -= normal;
-				obj2->m_static = obj1->m_static + 1;
-			}
-		}
-	
-	}
-		
-	
-	typedef std::set<Contact*, Contact> Set;
-};
-
-static Contact::Set contacts;
+MT_Scalar SM_Object::ImpulseThreshold = -10.;
 
 SM_Object::SM_Object(
 	DT_ShapeHandle shape, 
@@ -157,6 +69,9 @@ SM_Object::SM_Object(
 	m_scaling(1.0, 1.0, 1.0),
 	m_reaction_impulse(0.0, 0.0, 0.0),
 	m_reaction_force(0.0, 0.0, 0.0),
+	m_kinematic(false),
+	m_prev_kinematic(false),
+	m_is_rigid_body(false),
 	m_lin_mom(0.0, 0.0, 0.0),
 	m_ang_mom(0.0, 0.0, 0.0),
 	m_force(0.0, 0.0, 0.0),
@@ -166,11 +81,7 @@ SM_Object::SM_Object(
 	m_combined_ang_vel (0.0, 0.0, 0.0),
 	m_fh_object(0),
 	m_inv_mass(0.0),
-	m_inv_inertia(0., 0., 0.),
-	m_kinematic(false),
-	m_prev_kinematic(false),
-	m_is_rigid_body(false),
-	m_static(0)
+	m_inv_inertia(0., 0., 0.)
 {
 	m_object = DT_CreateObject(this, shape);
 	m_xform.setIdentity();
@@ -197,7 +108,7 @@ integrateForces(
 	MT_Scalar timeStep
 ){
 	if (!m_suspended) {
-		m_prev_state = getNextFrame();
+		m_prev_state = *this;
 		m_prev_state.setLinearVelocity(actualLinVelocity());
 		m_prev_state.setAngularVelocity(actualAngVelocity());
 		if (isDynamic()) {
@@ -208,8 +119,8 @@ integrateForces(
 			m_lin_mom *= pow(m_shapeProps->m_lin_drag, timeStep);
 			m_ang_mom *= pow(m_shapeProps->m_ang_drag, timeStep);
 			// Set velocities according momentum
-			getNextFrame().setLinearVelocity(m_lin_mom * m_inv_mass);
-			getNextFrame().setAngularVelocity(m_inv_inertia_tensor * m_ang_mom);
+			m_lin_vel = m_lin_mom * m_inv_mass;
+			m_ang_vel = m_inv_inertia_tensor * m_ang_mom;
 		}
 	}	
 
@@ -235,13 +146,13 @@ integrateMomentum(
 //#define BACKWARD
 #ifdef  MIDPOINT
 // Midpoint rule
-		getNextFrame().integrateMidpoint(timeStep, m_prev_state, actualLinVelocity(), actualAngVelocity());
+		integrateMidpoint(timeStep, m_prev_state, actualLinVelocity(), actualAngVelocity());
 #elif defined BACKWARD
 // Backward Euler
-		getNextFrame().integrateBackward(timeStep, actualLinVelocity(), actualAngVelocity());
+		integrateBackward(timeStep, actualLinVelocity(), actualAngVelocity());
 #else 
 // Forward Euler
-		getNextFrame().integrateForward(timeStep, m_prev_state);
+		integrateForward(timeStep, m_prev_state);
 #endif
 
 		calcXform();
@@ -278,11 +189,11 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2,
 	/**
 	 * if rel_vel_normal > 0, the objects are moving apart! 
 	 */
-	if (rel_vel_normal < -MT_EPSILON) {
+	if (rel_vel_normal < 0.) {
 		/**
 		 * if rel_vel_normal < ImpulseThreshold, scale the restitution down.
 		 * This should improve the simulation where the object is stacked.
-		 */	
+		 */
 		restitution *= MT_min(MT_Scalar(1.0), rel_vel_normal/ImpulseThreshold);
 				
 		MT_Scalar impulse = -(1.0 + restitution) * rel_vel_normal;
@@ -296,7 +207,7 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2,
 			 * Apply impulse at the collision point.
 			 * Take rotational inertia into account.
 			 */
-			applyImpulse(local2 + getNextFrame().getPosition(), impulse * normal);
+			applyImpulse(local2 + getPosition(), impulse * normal);
 		} else {
 			/**
 			 * Apply impulse through object centre. (no rotation.)
@@ -333,7 +244,7 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2,
 			 * local coordinates.
 			 */
 
-			MT_Matrix3x3 lcs(getNextFrame().getOrientation());
+			MT_Matrix3x3 lcs(m_orn);
 			
 			/**
 			 * We cannot use m_xform.getBasis() for the matrix, since 
@@ -407,7 +318,7 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2,
 					(invMass + lateral.dot(temp.cross(local2)));
 
 				MT_Scalar friction = MT_min(impulse_lateral, max_friction);
-				applyImpulse(local2 + getNextFrame().getPosition(), -lateral * friction);
+				applyImpulse(local2 + getPosition(), -lateral * friction);
 			}
 			else {
 				MT_Scalar impulse_lateral = rel_vel_lateral / invMass;
@@ -488,8 +399,8 @@ DT_Bool SM_Object::boing(
 	    (obj2->getClientObject() && obj2->getClientObject()->hasCollisionCallback()))
 		scene->notifyCollision(obj1, obj2);
 	
-	local1 -= obj1->getNextFrame().getPosition();
-	local2 -= obj2->getNextFrame().getPosition();
+	local1 -= obj1->getPosition();
+	local2 -= obj2->getPosition();
 	
 	// Calculate collision parameters
 	MT_Vector3 rel_vel        = obj1->getVelocity(local1) - obj2->getVelocity(local2);
@@ -511,11 +422,7 @@ DT_Bool SM_Object::boing(
 		obj1->dynamicCollision(local1, normal, dist, rel_vel, restitution, friction_factor, invMass);
 		
 	if (obj2->isDynamic())
-	{
 		obj2->dynamicCollision(local2, -normal, dist, -rel_vel, restitution, friction_factor, invMass);
-		if (!obj1->isDynamic() || obj1->m_static)
-			obj2->m_static = obj1->m_static + 1;
-	}
 	
 	return DT_CONTINUE;
 }
@@ -559,38 +466,31 @@ DT_Bool SM_Object::fix(
 	if (dist < MT_EPSILON || dist > obj2->m_shapeProps->m_radius*obj2->m_shapeProps->m_radius)
 		return DT_CONTINUE;
 		
-		
-	if ((obj1->m_static || !obj1->isDynamic()) && obj1->m_static < obj2->m_static)
-	{
-		obj2->m_static = obj1->m_static + 1;
-	} else if (obj2->m_static && obj2->m_static < obj1->m_static)
-	{
-		obj1->m_static = obj2->m_static + 1;
+	// This distinction between dynamic and non-dynamic objects should not be 
+	// necessary. Non-dynamic objects are assumed to have infinite mass.
+	if (obj1->isDynamic()) {
+		MT_Vector3 error = normal * 0.5f;
+		obj1->m_error += error;
+		obj2->m_error -= error;
+	}
+	else {
+		// Same again but now obj1 is non-dynamic
+		obj2->m_error -= normal;
 	}
-	
-	contacts.insert(new Contact(obj1, obj2, normal, MT_Point3(local1 + 0.5*(local2 - local1))));
-	
 	
 	return DT_CONTINUE;
 }
 
 void SM_Object::relax(void)
-{
-	for (Contact::Set::iterator csit = contacts.begin() ; csit != contacts.end(); ++csit)
-	{
-		(*csit)->resolve();
-		delete (*csit);
-	}
-		
-	contacts.clear();
+{ 
 	if (m_error.fuzzyZero())
 		return;
 	//std::cout << "SM_Object::relax: { " << m_error << " }" << std::endl;
 	
-	getNextFrame().setPosition(getNextFrame().getPosition() + m_error); 
+	setPosition(getPosition() + m_error); 
 	m_error.setValue(0., 0., 0.); 
-	//calcXform();
-	//notifyClient();
+	calcXform();
+	notifyClient();
 }
 	
 SM_Object::SM_Object() :
@@ -607,6 +507,9 @@ SM_Object::SM_Object() :
 	m_scaling(1.0, 1.0, 1.0),
 	m_reaction_impulse(0.0, 0.0, 0.0),
 	m_reaction_force(0.0, 0.0, 0.0),
+	m_kinematic(false),
+	m_prev_kinematic(false),
+	m_is_rigid_body(false),
 	m_lin_mom(0.0, 0.0, 0.0),
 	m_ang_mom(0.0, 0.0, 0.0),
 	m_force(0.0, 0.0, 0.0),
@@ -614,10 +517,7 @@ SM_Object::SM_Object() :
 	m_error(0.0, 0.0, 0.0),
 	m_combined_lin_vel (0.0, 0.0, 0.0),
 	m_combined_ang_vel (0.0, 0.0, 0.0),
-	m_fh_object(0),
-	m_kinematic(false),
-	m_prev_kinematic(false),
-	m_is_rigid_body(false)
+	m_fh_object(0) 
 {
 	// warning no initialization of variables done by moto.
 }
@@ -736,15 +636,15 @@ calcXform() {
 	printf("                 m_scaling = { %-0.5f, %-0.5f, %-0.5f }\n",
 		m_scaling[0], m_scaling[1], m_scaling[2]);
 #endif
-	m_xform.setOrigin(getNextFrame().getPosition());
-	m_xform.setBasis(MT_Matrix3x3(getNextFrame().getOrientation(), m_scaling));
+	m_xform.setOrigin(getPosition());
+	m_xform.setBasis(MT_Matrix3x3(getOrientation(), m_scaling));
 	m_xform.getValue(m_ogl_matrix);
 	
 	/* Blender has been known to crash here.
 	   This usually means SM_Object *this has been deleted more than once. */
 	DT_SetMatrixd(m_object, m_ogl_matrix);
 	if (m_fh_object) {
-		m_fh_object->setPosition(getNextFrame().getPosition());
+		m_fh_object->setPosition(getPosition());
 		m_fh_object->calcXform();
 	}
 	updateInvInertiaTensor();
@@ -860,8 +760,7 @@ setPosition(
 	const MT_Point3& pos
 ){
 	m_kinematic = true;
-	getNextFrame().setPosition(pos);
-	endFrame();
+	SM_MotionState::setPosition(pos);
 }
 	
 	void 
@@ -871,8 +770,7 @@ setOrientation(
 ){
 	assert(!orn.fuzzyZero());
 	m_kinematic = true;
-	getNextFrame().setOrientation(orn);
-	endFrame();
+	SM_MotionState::setOrientation(orn);
 }
 
 	void 
@@ -909,7 +807,10 @@ SM_Object::
 addLinearVelocity(
 	const MT_Vector3& lin_vel
 ){
-	setLinearVelocity(getNextFrame().getLinearVelocity() + lin_vel);
+	m_lin_vel += lin_vel;
+	if (m_shapeProps) {
+		m_lin_mom = m_lin_vel * m_shapeProps->m_mass;
+	}
 }
 
 	void 
@@ -917,9 +818,9 @@ SM_Object::
 setLinearVelocity(
 	const MT_Vector3& lin_vel
 ){
-	getNextFrame().setLinearVelocity(lin_vel);
+	m_lin_vel = lin_vel;
 	if (m_shapeProps) {
-		m_lin_mom = getNextFrame().getLinearVelocity() * m_shapeProps->m_mass;
+		m_lin_mom = m_lin_vel * m_shapeProps->m_mass;
 	}
 }
 
@@ -948,9 +849,9 @@ SM_Object::
 setAngularVelocity(
 	const MT_Vector3& ang_vel
 ) {
-	getNextFrame().setAngularVelocity(ang_vel);
+	m_ang_vel = ang_vel;
 	if (m_shapeProps) {
-		m_ang_mom = getNextFrame().getAngularVelocity() * m_shapeProps->m_inertia;
+		m_ang_mom = m_ang_vel * m_shapeProps->m_inertia;
 	}
 }
 
@@ -959,7 +860,10 @@ SM_Object::
 addAngularVelocity(
 	const MT_Vector3& ang_vel
 ) {
-	setAngularVelocity(getNextFrame().getAngularVelocity() + ang_vel);
+	m_ang_vel += ang_vel;
+	if (m_shapeProps) {
+		m_ang_mom = m_ang_vel * m_shapeProps->m_inertia;
+	}
 }
 
 
@@ -992,18 +896,18 @@ resolveCombinedVelocities(
 	if (isDynamic()) {		
 
 #if 1
-		getNextFrame().setLinearVelocity(getNextFrame().getLinearVelocity() + lin_vel);
-		getNextFrame().setAngularVelocity(getNextFrame().getAngularVelocity() + ang_vel);
+		m_lin_vel += lin_vel;
+		m_ang_vel += ang_vel;
 #else
 
 		//compute the component of the physics velocity in the 
 		// direction of the set velocity and set it to zero.
 		MT_Vector3 lin_vel_norm = lin_vel.normalized();
 
-		setLinearVelocity(getNextFrame().getLinearVelocity() - (getNextFrame().getLinearVelocity().dot(lin_vel_norm) * lin_vel_norm));
+		m_lin_vel -= (m_lin_vel.dot(lin_vel_norm) * lin_vel_norm);
 #endif
-		m_lin_mom = getNextFrame().getLinearVelocity() * m_shapeProps->m_mass;
-		m_ang_mom = getNextFrame().getAngularVelocity() * m_shapeProps->m_inertia;
+		m_lin_mom = m_lin_vel * m_shapeProps->m_mass;
+		m_ang_mom = m_ang_vel * m_shapeProps->m_inertia;
 		clearCombinedVelocities();
 
 	}
@@ -1066,7 +970,7 @@ applyImpulse(
 	const MT_Point3& attach, const MT_Vector3& impulse
 ) {
 	applyCenterImpulse(impulse);                          // Change in linear momentum
-	applyAngularImpulse((attach - getNextFrame().getPosition()).cross(impulse)); // Change in angular momentump
+	applyAngularImpulse((attach - m_pos).cross(impulse)); // Change in angular momentump
 }
 
 	void 
@@ -1077,7 +981,7 @@ applyCenterImpulse(
 	if (m_shapeProps) {
 		m_lin_mom          += impulse;
 		m_reaction_impulse += impulse;
-		getNextFrame().setLinearVelocity(m_lin_mom * m_inv_mass);
+		m_lin_vel           = m_lin_mom * m_inv_mass;
 
 		// The linear velocity is immedialtely updated since otherwise
 		// simultaneous collisions will get a double impulse. 
@@ -1091,7 +995,7 @@ applyAngularImpulse(
 ) {
 	if (m_shapeProps) {
 		m_ang_mom += impulse;
-		getNextFrame().setAngularVelocity( m_inv_inertia_tensor * m_ang_mom);
+		m_ang_vel = m_inv_inertia_tensor * m_ang_mom;
 	}
 }
 
@@ -1195,7 +1099,7 @@ const
 SM_Object::
 actualLinVelocity(
 ) const {
-	return m_combined_lin_vel + getNextFrame().getLinearVelocity();
+	return m_combined_lin_vel + m_lin_vel;
 };
 
 const 
@@ -1203,98 +1107,10 @@ const
 SM_Object::
 actualAngVelocity(
 ) const {
-	return m_combined_ang_vel + getNextFrame().getAngularVelocity();
-}
-
-
-SM_MotionState&
-SM_Object::
-getCurrentFrame()
-{
-	return m_frames[1];
-}
-
-SM_MotionState&
-SM_Object::
-getPreviousFrame()
-{
-	return m_frames[0];
-}
-
-SM_MotionState &
-SM_Object::
-getNextFrame()
-{
-	return m_frames[2];
-}
-
-const SM_MotionState &
-SM_Object::
-getCurrentFrame() const
-{
-	return m_frames[1];
-}
-
-const SM_MotionState &
-SM_Object::
-getPreviousFrame() const
-{
-	return m_frames[0];
-}
-
-const SM_MotionState &
-SM_Object::
-getNextFrame() const
-{
-	return m_frames[2];
-}
-
-
-const MT_Point3&     
-SM_Object::
-getPosition()        const
-{
-	return m_frames[1].getPosition();
-}
+	return m_combined_ang_vel + m_ang_vel;
+};
 
-const MT_Quaternion& 
-SM_Object::
-getOrientation()     const
-{
-	return m_frames[1].getOrientation();
-}
 
-const MT_Vector3&    
-SM_Object::
-getLinearVelocity()  const
-{
-	return m_frames[1].getLinearVelocity();
-}
 
-const MT_Vector3&    
-SM_Object::
-getAngularVelocity() const
-{
-	return m_frames[1].getAngularVelocity();
-}
 
-void
-SM_Object::
-interpolate(MT_Scalar timeStep)
-{
-	if (!actualLinVelocity().fuzzyZero() || !actualAngVelocity().fuzzyZero()) 
-	{
-		getCurrentFrame().setTime(timeStep);
-		getCurrentFrame().lerp(getPreviousFrame(), getNextFrame());
-		notifyClient();
-	}
-}
 
-void
-SM_Object::
-endFrame()
-{
-	getPreviousFrame() = getNextFrame();
-	getCurrentFrame() = getNextFrame();
-	m_static = 0;
-}
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
index fdd8079b24185f4ce8979fd9292e81fac28eb9ce..c29be228d64bb19521090b1d4090e0af4d0fe003 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
@@ -54,7 +54,7 @@ SM_Scene::SM_Scene() :
 	m_secondaryRespTable(DT_CreateRespTable()),
 	m_fixRespTable(DT_CreateRespTable()),
 	m_forceField(0.0, 0.0, 0.0),
-	m_frames(0)
+	m_lastTime(-1.0)
 {
 	for (int i = 0 ; i < NUM_RESPONSE; i++)
 	{
@@ -83,8 +83,8 @@ SM_Scene::SM_Scene() :
 	
 	/* Fh Object */
 	DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this);
-	DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this);
-	DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this);
+	DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_FhObject::ray_hit, DT_BROAD_RESPONSE, this);
+	DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_FhObject::ray_hit, DT_BROAD_RESPONSE, this);
 	DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this);
 	
 	/* Object (Fix Pass) */
@@ -177,111 +177,105 @@ void SM_Scene::endFrame()
 		(*i)->clearForce();
 }
 
-bool SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) 
-{
-	if (!m_frames)
+bool SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
+	if (m_lastTime < 0.0)
 	{
-		if (ticrate > 0.)
-			m_frames = (unsigned int)(curtime*ticrate + 1.0);
-		else
-			m_frames = (unsigned int)(curtime*65536.0);
+		m_lastTime = curtime;
+		return false;
 	}
-	
+		
 	// Divide the timeStep into a number of subsamples of size roughly 
 	// equal to subS (might be a little smaller).
+	MT_Scalar timeStep = curtime - m_lastTime;
 	MT_Scalar subStep;
 	int num_samples;
-	int frames = m_frames;
 	
-	// Compute the number of steps to do this update.
 	if (ticrate > 0.0)
 	{
-		// Fixed time step
 		subStep = 1.0/ticrate;
-		num_samples = (unsigned int)(curtime*ticrate + 1.0) - m_frames;
+		num_samples = int(timeStep * ticrate);
 	
 		if (num_samples > 4)
 		{
-			std::cout << "Dropping physics frames! frames:" << num_samples << " substep: " << subStep << std::endl;
-			MT_Scalar tr = ticrate;
-			do
-			{
-				frames = frames / 2;
-				tr = tr / 2.0;
-				num_samples = (unsigned int)(curtime*tr + 1.0) - frames;
-				subStep *= 2.0;
-			} while (num_samples > 8);
-			std::cout << "                         frames:" << num_samples << " substep: " << subStep << std::endl;
+			std::cout << "Dropping physics frames! step: " << timeStep << " frames:" << num_samples << std::endl;
+			num_samples /= 4;
+			subStep *= 4.0;
 		}
 	} 
 	else
 	{
 		// Variable time step. (old update)
 		// Integrate at least 100 Hz
-		MT_Scalar timeStep = curtime - m_frames/65536.0;
 		subStep = timeStep > 0.01 ? 0.01 : timeStep;
 		num_samples = int(timeStep * 0.01);
 		if (num_samples < 1)
 			num_samples = 1;
 	}
 	
-	// Do a physics timestep.
 	T_ObjectList::iterator i;
-	if (num_samples > 0)
+	
+	// No timestep! (should do a mini update)
+	if (num_samples <= 0)
 	{
-		// Do the integration steps per object.
-		for (int step = 0; step != num_samples; ++step) 
+		// Apply a forcefield (such as gravity)
+#if 0
+		for (i = m_objectList.begin(); i != m_objectList.end(); ++i) 
 		{
-			MT_Scalar time;
-			if (ticrate > 0.)
-				time = MT_Scalar(frames + step + 1) * subStep;
-			else
-				time = MT_Scalar(m_frames)/65536.0 + MT_Scalar(step + 1)*subStep;
-			
-			for (i = m_objectList.begin(); i != m_objectList.end(); ++i) {
-				(*i)->endFrame();
-				// Apply a forcefield (such as gravity)
-				(*i)->integrateForces(subStep);
-				// And second we update the object positions by performing
-				// an integration step for each object
-				(*i)->integrateMomentum(subStep);
-			}
-	
-			// So now first we let the physics scene respond to 
-			// new forces, velocities set externally. 
-			// The collsion and friction impulses are computed here. 
-			// Collision phase
-			DT_Test(m_scene, m_respTable);
-		
-			// Contact phase
-			DT_Test(m_scene, m_fixRespTable);
-			
-			// Finish this timestep by saving al state information for the next
-			// timestep and clearing the accumulated forces. 
-			for (i = m_objectList.begin(); i != m_objectList.end(); ++i) {
-				(*i)->relax();
-				(*i)->proceedKinematic(subStep);
-				(*i)->saveReactionForce(subStep);
-				(*i)->getNextFrame().setTime(time);
-				//(*i)->clearForce();
-			}
+			//(*i)->applyForceField(m_forceField);
+			//(*i)->integrateForces(timeStep);
+			// And second we update the object positions by performing
+			// an integration step for each object
+			(*i)->integrateMomentum(timeStep);
+			//(*i)->clearForce();
 		}
+#endif
+		return false;	
 	}
-
-	if (ticrate > 0)
-	{
-		// Interpolate between time steps.
-		for (i = m_objectList.begin(); i != m_objectList.end(); ++i) 
-			(*i)->interpolate(curtime);
 	
-		m_frames = (unsigned int)(curtime*ticrate + 1.0);
-	}
-	else
-	{
-		m_frames = (unsigned int)(curtime*65536.0);
-	}
+	m_lastTime += MT_Scalar(num_samples)*subStep;
+	
+	// Do the integration steps per object.
+	int step;
+	for (step = 0; step != num_samples; ++step) {
+
+		for (i = m_objectList.begin(); i != m_objectList.end(); ++i) {
+			// Apply a forcefield (such as gravity)
+			//(*i)->applyForceField(m_forceField);
+			//(*i)->setTimeStep(timeStep);
+			(*i)->integrateForces(subStep);
+			// And second we update the object positions by performing
+			// an integration step for each object
+			(*i)->integrateMomentum(subStep);
+		}
+		
+		// I changed the order of the next 2 statements.
+		// Originally objects were first integrated with a call
+		// to proceed(). However if external objects were 
+		// directly manipulating the velocities etc of physics 
+		// objects then the physics environment would not be able 
+		// to react before object positions were updated. --- Laurence.
+
+		// So now first we let the physics scene respond to 
+		// new forces, velocities set externally. 
+		// The collsion and friction impulses are computed here. 
+		DT_Test(m_scene, m_respTable);
+
+	// clear the user set velocities.
+#if 0
+	clearObjectCombinedVelocities();
+#endif
+		DT_Test(m_scene, m_fixRespTable);
 		
-	return num_samples != 0;
+		// Finish this timestep by saving al state information for the next
+		// timestep and clearing the accumulated forces. 
+		for (i = m_objectList.begin(); i != m_objectList.end(); ++i) {
+			(*i)->relax();
+			(*i)->proceedKinematic(subStep);
+			(*i)->saveReactionForce(subStep);
+			//(*i)->clearForce();
+		}
+	}
+	return true;
 }
 
 void SM_Scene::notifyCollision(SM_Object *obj1, SM_Object *obj2)
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp
index 46eeef264def978088ff339fd89aaec69ae9e167..5301e125ce10c43957c70d6e01191c522f9285dc 100644
--- a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp
@@ -174,8 +174,7 @@ void		SumoPhysicsController::setPosition(float posX,float posY,float posZ)
 
 void		SumoPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ)
 {
-	if (!m_bDyna)
-		m_sumoObj->setScaling(MT_Vector3(scaleX,scaleY,scaleZ));
+	m_sumoObj->setScaling(MT_Vector3(scaleX,scaleY,scaleZ));
 }
 	
 	// physics methods