1 diff -urN a/src/BulletDynamics/Character/btCharacterControllerInterface.h b/src/BulletDynamics/Character/btCharacterControllerInterface.h
2 --- a/src/BulletDynamics/Character/btCharacterControllerInterface.h 2013-01-22 17:54:25.468670949 -0600
3 +++ b/src/BulletDynamics/Character/btCharacterControllerInterface.h 2011-04-28 12:53:37.000000000 -0500
6 virtual void setWalkDirection(const btVector3& walkDirection) = 0;
7 virtual void setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0;
8 - virtual void reset () = 0;
9 + virtual void reset ( btCollisionWorld* collisionWorld ) = 0;
10 virtual void warp (const btVector3& origin) = 0;
12 virtual void preStep ( btCollisionWorld* collisionWorld) = 0;
14 virtual void jump () = 0;
16 virtual bool onGround () const = 0;
17 + virtual void setUpInterpolate (bool value) = 0;
20 #endif //BT_CHARACTER_CONTROLLER_INTERFACE_H
21 diff -urN a/src/BulletDynamics/Character/btKinematicCharacterController.cpp b/src/BulletDynamics/Character/btKinematicCharacterController.cpp
22 --- a/src/BulletDynamics/Character/btKinematicCharacterController.cpp 2013-01-22 17:54:25.444670455 -0600
23 +++ b/src/BulletDynamics/Character/btKinematicCharacterController.cpp 2013-01-22 17:17:47.583541659 -0600
29 #include "LinearMath/btIDebugDraw.h"
30 #include "BulletCollision/CollisionDispatch/btGhostObject.h"
31 #include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
33 if (convexResult.m_hitCollisionObject == m_me)
36 + if (!convexResult.m_hitCollisionObject->hasContactResponse())
37 + return btScalar(1.0);
39 btVector3 hitNormalWorld;
40 if (normalInWorldSpace)
43 m_jumpSpeed = 10.0; // ?
44 m_wasOnGround = false;
46 + m_interpolateUp = true;
47 setMaxSlope(btRadians(45.0));
48 + m_currentStepOffset = 0;
53 btKinematicCharacterController::~btKinematicCharacterController ()
55 m_manifoldArray.resize(0);
57 btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
59 + btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
60 + btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
62 + if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
65 if (collisionPair->m_algorithm)
66 collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
69 // we moved up only a fraction of the step height
70 m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
71 - m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
72 + if (m_interpolateUp == true)
73 + m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
75 + m_currentPosition = m_targetPosition;
77 m_verticalVelocity = 0.0;
78 m_verticalOffset = 0.0;
81 if (m_normalizedDirection.dot(m_touchingNormal) > btScalar(0.0))
83 - updateTargetPositionBasedOnCollision (m_touchingNormal);
84 + //interferes with step movement
85 + //updateTargetPositionBasedOnCollision (m_touchingNormal);
91 void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt)
93 - btTransform start, end;
94 + btTransform start, end, end_double;
95 + bool runonce = false;
98 /*btScalar additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
99 @@ -406,44 +425,124 @@
100 btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity;
101 m_targetPosition -= (step_drop + gravity_drop);*/
103 + btVector3 orig_position = m_targetPosition;
105 btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
106 - if(downVelocity > 0.0 && downVelocity < m_stepHeight
108 + if(downVelocity > 0.0 && downVelocity > m_fallSpeed
109 && (m_wasOnGround || !m_wasJumping))
111 - downVelocity = m_stepHeight;
113 + downVelocity = m_fallSpeed;
115 btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
116 m_targetPosition -= step_drop;
118 - start.setIdentity ();
119 - end.setIdentity ();
120 + btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
121 + callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
122 + callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
124 - start.setOrigin (m_currentPosition);
125 - end.setOrigin (m_targetPosition);
126 + btKinematicClosestNotMeConvexResultCallback callback2 (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
127 + callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
128 + callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
130 - btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
131 - callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
132 - callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
134 - if (m_useGhostObjectSweepTest)
137 - m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
140 - collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
141 + start.setIdentity ();
142 + end.setIdentity ();
144 + end_double.setIdentity ();
146 + start.setOrigin (m_currentPosition);
147 + end.setOrigin (m_targetPosition);
149 + //set double test for 2x the step drop, to check for a large drop vs small drop
150 + end_double.setOrigin (m_targetPosition - step_drop);
152 + if (m_useGhostObjectSweepTest)
154 + m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
156 + if (!callback.hasHit())
158 + //test a double fall height, to see if the character should interpolate it's fall (full) or not (partial)
159 + m_ghostObject->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
163 + collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
165 + if (!callback.hasHit())
167 + //test a double fall height, to see if the character should interpolate it's fall (large) or not (small)
168 + collisionWorld->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
172 + btScalar downVelocity2 = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
173 + bool has_hit = false;
174 + if (bounce_fix == true)
175 + has_hit = callback.hasHit() || callback2.hasHit();
177 + has_hit = callback2.hasHit();
179 + if(downVelocity2 > 0.0 && downVelocity2 < m_stepHeight && has_hit == true && runonce == false
180 + && (m_wasOnGround || !m_wasJumping))
182 + //redo the velocity calculation when falling a small amount, for fast stairs motion
183 + //for larger falls, use the smoother/slower interpolated movement by not touching the target position
185 + m_targetPosition = orig_position;
186 + downVelocity = m_stepHeight;
188 + btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
189 + m_targetPosition -= step_drop;
191 + continue; //re-run previous tests
196 - if (callback.hasHit())
197 + if (callback.hasHit() || runonce == true)
199 // we dropped a fraction of the height -> hit floor
200 - m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
202 + btScalar fraction = (m_currentPosition.getY() - callback.m_hitPointWorld.getY()) / 2;
204 + //printf("hitpoint: %g - pos %g\n", callback.m_hitPointWorld.getY(), m_currentPosition.getY());
206 + if (bounce_fix == true)
208 + if (full_drop == true)
209 + m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
211 + //due to errors in the closestHitFraction variable when used with large polygons, calculate the hit fraction manually
212 + m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, fraction);
215 + m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
219 m_verticalVelocity = 0.0;
220 m_verticalOffset = 0.0;
221 m_wasJumping = false;
223 // we dropped the full height
227 + if (bounce_fix == true)
229 + downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
230 + if (downVelocity > m_fallSpeed && (m_wasOnGround || !m_wasJumping))
232 + m_targetPosition += step_drop; //undo previous target change
233 + downVelocity = m_fallSpeed;
234 + step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
235 + m_targetPosition -= step_drop;
238 + //printf("full drop - %g, %g\n", m_currentPosition.getY(), m_targetPosition.getY());
240 m_currentPosition = m_targetPosition;
243 @@ -479,10 +578,21 @@
244 m_velocityTimeInterval = timeInterval;
249 -void btKinematicCharacterController::reset ()
250 +void btKinematicCharacterController::reset ( btCollisionWorld* collisionWorld )
252 + m_verticalVelocity = 0.0;
253 + m_verticalOffset = 0.0;
254 + m_wasOnGround = false;
255 + m_wasJumping = false;
256 + m_walkDirection.setValue(0,0,0);
257 + m_velocityTimeInterval = 0.0;
260 + btHashedOverlappingPairCache *cache = m_ghostObject->getOverlappingPairCache();
261 + while (cache->getOverlappingPairArray().size() > 0)
263 + cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, cache->getOverlappingPairArray()[0].m_pProxy1, collisionWorld->getDispatcher());
267 void btKinematicCharacterController::warp (const btVector3& origin)
269 void btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)
273 +void btKinematicCharacterController::setUpInterpolate(bool value)
275 + m_interpolateUp = value;
277 diff -urN a/src/BulletDynamics/Character/btKinematicCharacterController.h b/src/BulletDynamics/Character/btKinematicCharacterController.h
278 --- a/src/BulletDynamics/Character/btKinematicCharacterController.h 2013-01-22 17:54:25.440670373 -0600
279 +++ b/src/BulletDynamics/Character/btKinematicCharacterController.h 2013-01-13 14:33:42.262892731 -0600
283 static btVector3* getUpAxisDirections();
284 + bool m_interpolateUp;
288 btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal);
289 btVector3 parallelComponent (const btVector3& direction, const btVector3& normal);
291 virtual void setVelocityForTimeInterval(const btVector3& velocity,
292 btScalar timeInterval);
295 + void reset ( btCollisionWorld* collisionWorld );
296 void warp (const btVector3& origin);
298 void preStep ( btCollisionWorld* collisionWorld);
302 bool onGround () const;
303 + void setUpInterpolate (bool value);
306 #endif // BT_KINEMATIC_CHARACTER_CONTROLLER_H