OSDN Git Service

-made new bullet patch, renamed old patch due to it being found in the Bullet trunk
authorryan <>
Fri, 10 Jan 2014 22:34:16 +0000 (22:34 +0000)
committerryan <>
Fri, 10 Jan 2014 22:34:16 +0000 (22:34 +0000)
-disabled penetration recovery in preStep() function, which interferes with stairs stepping

bullet-changes.old.patch [new file with mode: 0644]
bullet-changes.patch

diff --git a/bullet-changes.old.patch b/bullet-changes.old.patch
new file mode 100644 (file)
index 0000000..f304d67
--- /dev/null
@@ -0,0 +1,306 @@
+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
index f304d67..96ffc2e 100644 (file)
-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;