--- /dev/null
+diff -urN a/src/BulletDynamics/Character/btCharacterControllerInterface.h b/src/BulletDynamics/Character/btCharacterControllerInterface.h
+--- a/src/BulletDynamics/Character/btCharacterControllerInterface.h 2013-01-22 17:54:25.468670949 -0600
++++ b/src/BulletDynamics/Character/btCharacterControllerInterface.h 2011-04-28 12:53:37.000000000 -0500
+@@ -31,7 +31,7 @@
+
+ virtual void setWalkDirection(const btVector3& walkDirection) = 0;
+ virtual void setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0;
+- virtual void reset () = 0;
++ virtual void reset ( btCollisionWorld* collisionWorld ) = 0;
+ virtual void warp (const btVector3& origin) = 0;
+
+ virtual void preStep ( btCollisionWorld* collisionWorld) = 0;
+@@ -40,6 +40,7 @@
+ virtual void jump () = 0;
+
+ virtual bool onGround () const = 0;
++ virtual void setUpInterpolate (bool value) = 0;
+ };
+
+ #endif //BT_CHARACTER_CONTROLLER_INTERFACE_H
+diff -urN a/src/BulletDynamics/Character/btKinematicCharacterController.cpp b/src/BulletDynamics/Character/btKinematicCharacterController.cpp
+--- a/src/BulletDynamics/Character/btKinematicCharacterController.cpp 2013-01-22 17:54:25.444670455 -0600
++++ b/src/BulletDynamics/Character/btKinematicCharacterController.cpp 2013-01-22 17:17:47.583541659 -0600
+@@ -14,6 +14,7 @@
+ */
+
+
++#include <stdio.h>
+ #include "LinearMath/btIDebugDraw.h"
+ #include "BulletCollision/CollisionDispatch/btGhostObject.h"
+ #include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
+@@ -77,6 +78,9 @@
+ if (convexResult.m_hitCollisionObject == m_me)
+ return btScalar(1.0);
+
++ if (!convexResult.m_hitCollisionObject->hasContactResponse())
++ return btScalar(1.0);
++
+ btVector3 hitNormalWorld;
+ if (normalInWorldSpace)
+ {
+@@ -146,7 +150,11 @@
+ m_jumpSpeed = 10.0; // ?
+ m_wasOnGround = false;
+ m_wasJumping = false;
++ m_interpolateUp = true;
+ setMaxSlope(btRadians(45.0));
++ m_currentStepOffset = 0;
++ full_drop = false;
++ bounce_fix = false;
+ }
+
+ btKinematicCharacterController::~btKinematicCharacterController ()
+@@ -187,6 +195,12 @@
+ m_manifoldArray.resize(0);
+
+ btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
++
++ btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
++ btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
++
++ if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
++ continue;
+
+ if (collisionPair->m_algorithm)
+ collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
+@@ -260,7 +274,10 @@
+ {
+ // we moved up only a fraction of the step height
+ m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
+- m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
++ if (m_interpolateUp == true)
++ m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
++ else
++ m_currentPosition = m_targetPosition;
+ }
+ m_verticalVelocity = 0.0;
+ m_verticalOffset = 0.0;
+@@ -325,7 +342,8 @@
+ {
+ if (m_normalizedDirection.dot(m_touchingNormal) > btScalar(0.0))
+ {
+- updateTargetPositionBasedOnCollision (m_touchingNormal);
++ //interferes with step movement
++ //updateTargetPositionBasedOnCollision (m_touchingNormal);
+ }
+ }
+
+@@ -397,7 +415,8 @@
+
+ void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt)
+ {
+- btTransform start, end;
++ btTransform start, end, end_double;
++ bool runonce = false;
+
+ // phase 3: down
+ /*btScalar additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
+@@ -406,44 +425,124 @@
+ btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity;
+ m_targetPosition -= (step_drop + gravity_drop);*/
+
++ btVector3 orig_position = m_targetPosition;
++
+ btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
+- if(downVelocity > 0.0 && downVelocity < m_stepHeight
++
++ if(downVelocity > 0.0 && downVelocity > m_fallSpeed
+ && (m_wasOnGround || !m_wasJumping))
+- {
+- downVelocity = m_stepHeight;
+- }
++ downVelocity = m_fallSpeed;
+
+ btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
+ m_targetPosition -= step_drop;
+
+- start.setIdentity ();
+- end.setIdentity ();
++ btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
++ callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
++ callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
+
+- start.setOrigin (m_currentPosition);
+- end.setOrigin (m_targetPosition);
++ btKinematicClosestNotMeConvexResultCallback callback2 (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
++ callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
++ callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
+
+- btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
+- callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
+- callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
+-
+- if (m_useGhostObjectSweepTest)
++ while (1)
+ {
+- m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
+- } else
+- {
+- collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
++ start.setIdentity ();
++ end.setIdentity ();
++
++ end_double.setIdentity ();
++
++ start.setOrigin (m_currentPosition);
++ end.setOrigin (m_targetPosition);
++
++ //set double test for 2x the step drop, to check for a large drop vs small drop
++ end_double.setOrigin (m_targetPosition - step_drop);
++
++ if (m_useGhostObjectSweepTest)
++ {
++ m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
++
++ if (!callback.hasHit())
++ {
++ //test a double fall height, to see if the character should interpolate it's fall (full) or not (partial)
++ m_ghostObject->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
++ }
++ } else
++ {
++ collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
++
++ if (!callback.hasHit())
++ {
++ //test a double fall height, to see if the character should interpolate it's fall (large) or not (small)
++ collisionWorld->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
++ }
++ }
++
++ btScalar downVelocity2 = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
++ bool has_hit = false;
++ if (bounce_fix == true)
++ has_hit = callback.hasHit() || callback2.hasHit();
++ else
++ has_hit = callback2.hasHit();
++
++ if(downVelocity2 > 0.0 && downVelocity2 < m_stepHeight && has_hit == true && runonce == false
++ && (m_wasOnGround || !m_wasJumping))
++ {
++ //redo the velocity calculation when falling a small amount, for fast stairs motion
++ //for larger falls, use the smoother/slower interpolated movement by not touching the target position
++
++ m_targetPosition = orig_position;
++ downVelocity = m_stepHeight;
++
++ btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
++ m_targetPosition -= step_drop;
++ runonce = true;
++ continue; //re-run previous tests
++ }
++ break;
+ }
+
+- if (callback.hasHit())
++ if (callback.hasHit() || runonce == true)
+ {
+ // we dropped a fraction of the height -> hit floor
+- m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
++
++ btScalar fraction = (m_currentPosition.getY() - callback.m_hitPointWorld.getY()) / 2;
++
++ //printf("hitpoint: %g - pos %g\n", callback.m_hitPointWorld.getY(), m_currentPosition.getY());
++
++ if (bounce_fix == true)
++ {
++ if (full_drop == true)
++ m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
++ else
++ //due to errors in the closestHitFraction variable when used with large polygons, calculate the hit fraction manually
++ m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, fraction);
++ }
++ else
++ m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
++
++ full_drop = false;
++
+ m_verticalVelocity = 0.0;
+ m_verticalOffset = 0.0;
+ m_wasJumping = false;
+ } else {
+ // we dropped the full height
+
++ full_drop = true;
++
++ if (bounce_fix == true)
++ {
++ downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
++ if (downVelocity > m_fallSpeed && (m_wasOnGround || !m_wasJumping))
++ {
++ m_targetPosition += step_drop; //undo previous target change
++ downVelocity = m_fallSpeed;
++ step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
++ m_targetPosition -= step_drop;
++ }
++ }
++ //printf("full drop - %g, %g\n", m_currentPosition.getY(), m_targetPosition.getY());
++
+ m_currentPosition = m_targetPosition;
+ }
+ }
+@@ -479,10 +578,21 @@
+ m_velocityTimeInterval = timeInterval;
+ }
+
+-
+-
+-void btKinematicCharacterController::reset ()
++void btKinematicCharacterController::reset ( btCollisionWorld* collisionWorld )
+ {
++ m_verticalVelocity = 0.0;
++ m_verticalOffset = 0.0;
++ m_wasOnGround = false;
++ m_wasJumping = false;
++ m_walkDirection.setValue(0,0,0);
++ m_velocityTimeInterval = 0.0;
++
++ //clear pair cache
++ btHashedOverlappingPairCache *cache = m_ghostObject->getOverlappingPairCache();
++ while (cache->getOverlappingPairArray().size() > 0)
++ {
++ cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, cache->getOverlappingPairArray()[0].m_pProxy1, collisionWorld->getDispatcher());
++ }
+ }
+
+ void btKinematicCharacterController::warp (const btVector3& origin)
+@@ -653,3 +763,8 @@
+ void btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)
+ {
+ }
++
++void btKinematicCharacterController::setUpInterpolate(bool value)
++{
++ m_interpolateUp = value;
++}
+diff -urN a/src/BulletDynamics/Character/btKinematicCharacterController.h b/src/BulletDynamics/Character/btKinematicCharacterController.h
+--- a/src/BulletDynamics/Character/btKinematicCharacterController.h 2013-01-22 17:54:25.440670373 -0600
++++ b/src/BulletDynamics/Character/btKinematicCharacterController.h 2013-01-13 14:33:42.262892731 -0600
+@@ -81,6 +81,9 @@
+ int m_upAxis;
+
+ static btVector3* getUpAxisDirections();
++ bool m_interpolateUp;
++ bool full_drop;
++ bool bounce_fix;
+
+ btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal);
+ btVector3 parallelComponent (const btVector3& direction, const btVector3& normal);
+@@ -133,7 +136,7 @@
+ virtual void setVelocityForTimeInterval(const btVector3& velocity,
+ btScalar timeInterval);
+
+- void reset ();
++ void reset ( btCollisionWorld* collisionWorld );
+ void warp (const btVector3& origin);
+
+ void preStep ( btCollisionWorld* collisionWorld);
+@@ -161,6 +164,7 @@
+ }
+
+ bool onGround () const;
++ void setUpInterpolate (bool value);
+ };
+
+ #endif // BT_KINEMATIC_CHARACTER_CONTROLLER_H
-diff -urN a/src/BulletDynamics/Character/btCharacterControllerInterface.h b/src/BulletDynamics/Character/btCharacterControllerInterface.h
---- a/src/BulletDynamics/Character/btCharacterControllerInterface.h 2013-01-22 17:54:25.468670949 -0600
-+++ b/src/BulletDynamics/Character/btCharacterControllerInterface.h 2011-04-28 12:53:37.000000000 -0500
-@@ -31,7 +31,7 @@
-
- virtual void setWalkDirection(const btVector3& walkDirection) = 0;
- virtual void setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0;
-- virtual void reset () = 0;
-+ virtual void reset ( btCollisionWorld* collisionWorld ) = 0;
- virtual void warp (const btVector3& origin) = 0;
-
- virtual void preStep ( btCollisionWorld* collisionWorld) = 0;
-@@ -40,6 +40,7 @@
- virtual void jump () = 0;
-
- virtual bool onGround () const = 0;
-+ virtual void setUpInterpolate (bool value) = 0;
- };
-
- #endif //BT_CHARACTER_CONTROLLER_INTERFACE_H
diff -urN a/src/BulletDynamics/Character/btKinematicCharacterController.cpp b/src/BulletDynamics/Character/btKinematicCharacterController.cpp
---- a/src/BulletDynamics/Character/btKinematicCharacterController.cpp 2013-01-22 17:54:25.444670455 -0600
-+++ b/src/BulletDynamics/Character/btKinematicCharacterController.cpp 2013-01-22 17:17:47.583541659 -0600
-@@ -14,6 +14,7 @@
- */
-
-
-+#include <stdio.h>
- #include "LinearMath/btIDebugDraw.h"
- #include "BulletCollision/CollisionDispatch/btGhostObject.h"
- #include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
-@@ -77,6 +78,9 @@
- if (convexResult.m_hitCollisionObject == m_me)
- return btScalar(1.0);
-
-+ if (!convexResult.m_hitCollisionObject->hasContactResponse())
-+ return btScalar(1.0);
-+
- btVector3 hitNormalWorld;
- if (normalInWorldSpace)
- {
-@@ -146,7 +150,11 @@
- m_jumpSpeed = 10.0; // ?
- m_wasOnGround = false;
- m_wasJumping = false;
-+ m_interpolateUp = true;
- setMaxSlope(btRadians(45.0));
-+ m_currentStepOffset = 0;
-+ full_drop = false;
-+ bounce_fix = false;
- }
-
- btKinematicCharacterController::~btKinematicCharacterController ()
-@@ -187,6 +195,12 @@
- m_manifoldArray.resize(0);
-
- btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
-+
-+ btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
-+ btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
+--- a/src/BulletDynamics/Character/btKinematicCharacterController.cpp 2014-01-10 15:47:47.572520001 -0600
++++ b/src/BulletDynamics/Character/btKinematicCharacterController.cpp 2014-01-10 15:48:52.389223177 -0600
+@@ -607,8 +607,11 @@
+ void btKinematicCharacterController::preStep ( btCollisionWorld* collisionWorld)
+ {
+
+- int numPenetrationLoops = 0;
++ //this causes other objects to 'push' character, and is turned off because
++ //it interferes with stairs stepping
++ /*int numPenetrationLoops = 0;
+ m_touchingContact = false;
+
-+ if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
-+ continue;
-
- if (collisionPair->m_algorithm)
- collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
-@@ -260,7 +274,10 @@
- {
- // we moved up only a fraction of the step height
- m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
-- m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
-+ if (m_interpolateUp == true)
-+ m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
-+ else
-+ m_currentPosition = m_targetPosition;
- }
- m_verticalVelocity = 0.0;
- m_verticalOffset = 0.0;
-@@ -325,7 +342,8 @@
+ while (recoverFromPenetration (collisionWorld))
{
- if (m_normalizedDirection.dot(m_touchingNormal) > btScalar(0.0))
- {
-- updateTargetPositionBasedOnCollision (m_touchingNormal);
-+ //interferes with step movement
-+ //updateTargetPositionBasedOnCollision (m_touchingNormal);
+ numPenetrationLoops++;
+@@ -618,7 +621,7 @@
+ //printf("character could not recover from penetration = %d\n", numPenetrationLoops);
+ break;
}
- }
-
-@@ -397,7 +415,8 @@
-
- void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt)
- {
-- btTransform start, end;
-+ btTransform start, end, end_double;
-+ bool runonce = false;
-
- // phase 3: down
- /*btScalar additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
-@@ -406,44 +425,124 @@
- btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity;
- m_targetPosition -= (step_drop + gravity_drop);*/
-
-+ btVector3 orig_position = m_targetPosition;
-+
- btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
-- if(downVelocity > 0.0 && downVelocity < m_stepHeight
-+
-+ if(downVelocity > 0.0 && downVelocity > m_fallSpeed
- && (m_wasOnGround || !m_wasJumping))
-- {
-- downVelocity = m_stepHeight;
- }
-+ downVelocity = m_fallSpeed;
-
- btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
- m_targetPosition -= step_drop;
-
-- start.setIdentity ();
-- end.setIdentity ();
-+ btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
-+ callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
-+ callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
-
-- start.setOrigin (m_currentPosition);
-- end.setOrigin (m_targetPosition);
-+ btKinematicClosestNotMeConvexResultCallback callback2 (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
-+ callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
-+ callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
-
-- btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
-- callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
-- callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
--
-- if (m_useGhostObjectSweepTest)
-+ while (1)
- {
-- m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
-- } else
-- {
-- collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
-+ start.setIdentity ();
-+ end.setIdentity ();
-+
-+ end_double.setIdentity ();
-+
-+ start.setOrigin (m_currentPosition);
-+ end.setOrigin (m_targetPosition);
-+
-+ //set double test for 2x the step drop, to check for a large drop vs small drop
-+ end_double.setOrigin (m_targetPosition - step_drop);
-+
-+ if (m_useGhostObjectSweepTest)
-+ {
-+ m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
-+
-+ if (!callback.hasHit())
-+ {
-+ //test a double fall height, to see if the character should interpolate it's fall (full) or not (partial)
-+ m_ghostObject->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
-+ }
-+ } else
-+ {
-+ collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
-+
-+ if (!callback.hasHit())
-+ {
-+ //test a double fall height, to see if the character should interpolate it's fall (large) or not (small)
-+ collisionWorld->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
-+ }
-+ }
-+
-+ btScalar downVelocity2 = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
-+ bool has_hit = false;
-+ if (bounce_fix == true)
-+ has_hit = callback.hasHit() || callback2.hasHit();
-+ else
-+ has_hit = callback2.hasHit();
-+
-+ if(downVelocity2 > 0.0 && downVelocity2 < m_stepHeight && has_hit == true && runonce == false
-+ && (m_wasOnGround || !m_wasJumping))
-+ {
-+ //redo the velocity calculation when falling a small amount, for fast stairs motion
-+ //for larger falls, use the smoother/slower interpolated movement by not touching the target position
-+
-+ m_targetPosition = orig_position;
-+ downVelocity = m_stepHeight;
-+
-+ btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
-+ m_targetPosition -= step_drop;
-+ runonce = true;
-+ continue; //re-run previous tests
-+ }
-+ break;
- }
-
-- if (callback.hasHit())
-+ if (callback.hasHit() || runonce == true)
- {
- // we dropped a fraction of the height -> hit floor
-- m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
-+
-+ btScalar fraction = (m_currentPosition.getY() - callback.m_hitPointWorld.getY()) / 2;
-+
-+ //printf("hitpoint: %g - pos %g\n", callback.m_hitPointWorld.getY(), m_currentPosition.getY());
-+
-+ if (bounce_fix == true)
-+ {
-+ if (full_drop == true)
-+ m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
-+ else
-+ //due to errors in the closestHitFraction variable when used with large polygons, calculate the hit fraction manually
-+ m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, fraction);
-+ }
-+ else
-+ m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
-+
-+ full_drop = false;
-+
- m_verticalVelocity = 0.0;
- m_verticalOffset = 0.0;
- m_wasJumping = false;
- } else {
- // we dropped the full height
-
-+ full_drop = true;
-+
-+ if (bounce_fix == true)
-+ {
-+ downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
-+ if (downVelocity > m_fallSpeed && (m_wasOnGround || !m_wasJumping))
-+ {
-+ m_targetPosition += step_drop; //undo previous target change
-+ downVelocity = m_fallSpeed;
-+ step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
-+ m_targetPosition -= step_drop;
-+ }
-+ }
-+ //printf("full drop - %g, %g\n", m_currentPosition.getY(), m_targetPosition.getY());
-+
- m_currentPosition = m_targetPosition;
- }
- }
-@@ -479,10 +578,21 @@
- m_velocityTimeInterval = timeInterval;
- }
-
--
--
--void btKinematicCharacterController::reset ()
-+void btKinematicCharacterController::reset ( btCollisionWorld* collisionWorld )
- {
-+ m_verticalVelocity = 0.0;
-+ m_verticalOffset = 0.0;
-+ m_wasOnGround = false;
-+ m_wasJumping = false;
-+ m_walkDirection.setValue(0,0,0);
-+ m_velocityTimeInterval = 0.0;
-+
-+ //clear pair cache
-+ btHashedOverlappingPairCache *cache = m_ghostObject->getOverlappingPairCache();
-+ while (cache->getOverlappingPairArray().size() > 0)
-+ {
-+ cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, cache->getOverlappingPairArray()[0].m_pProxy1, collisionWorld->getDispatcher());
-+ }
- }
-
- void btKinematicCharacterController::warp (const btVector3& origin)
-@@ -653,3 +763,8 @@
- void btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)
- {
- }
-+
-+void btKinematicCharacterController::setUpInterpolate(bool value)
-+{
-+ m_interpolateUp = value;
-+}
-diff -urN a/src/BulletDynamics/Character/btKinematicCharacterController.h b/src/BulletDynamics/Character/btKinematicCharacterController.h
---- a/src/BulletDynamics/Character/btKinematicCharacterController.h 2013-01-22 17:54:25.440670373 -0600
-+++ b/src/BulletDynamics/Character/btKinematicCharacterController.h 2013-01-13 14:33:42.262892731 -0600
-@@ -81,6 +81,9 @@
- int m_upAxis;
-
- static btVector3* getUpAxisDirections();
-+ bool m_interpolateUp;
-+ bool full_drop;
-+ bool bounce_fix;
-
- btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal);
- btVector3 parallelComponent (const btVector3& direction, const btVector3& normal);
-@@ -133,7 +136,7 @@
- virtual void setVelocityForTimeInterval(const btVector3& velocity,
- btScalar timeInterval);
-
-- void reset ();
-+ void reset ( btCollisionWorld* collisionWorld );
- void warp (const btVector3& origin);
-
- void preStep ( btCollisionWorld* collisionWorld);
-@@ -161,6 +164,7 @@
- }
-
- bool onGround () const;
-+ void setUpInterpolate (bool value);
- };
++ }*/
- #endif // BT_KINEMATIC_CHARACTER_CONTROLLER_H
+ m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
+ m_targetPosition = m_currentPosition;