diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp index 0856332d1..774fde26c 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp @@ -107,7 +107,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& m_lastUsedMethod = -1; { - btScalar squaredDistance = SIMD_INFINITY; + btScalar squaredDistance = BT_LARGE_FLOAT; btScalar delta = btScalar(0.); btScalar margin = marginA + marginB; diff --git a/src/BulletDynamics/Character/btCharacterControllerInterface.h b/src/BulletDynamics/Character/btCharacterControllerInterface.h index 1c045338a..19373daa2 100644 --- a/src/BulletDynamics/Character/btCharacterControllerInterface.h +++ b/src/BulletDynamics/Character/btCharacterControllerInterface.h @@ -30,6 +30,7 @@ public: virtual ~btCharacterControllerInterface () {}; virtual void setWalkDirection(const btVector3& walkDirection) = 0; + virtual void setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0; virtual void reset () = 0; virtual void warp (const btVector3& origin) = 0; diff --git a/src/BulletDynamics/Character/btKinematicCharacterController.cpp b/src/BulletDynamics/Character/btKinematicCharacterController.cpp index f3ecc2ac1..4a2d6089e 100644 --- a/src/BulletDynamics/Character/btKinematicCharacterController.cpp +++ b/src/BulletDynamics/Character/btKinematicCharacterController.cpp @@ -13,6 +13,7 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ + #include "LinearMath/btIDebugDraw.h" #include "BulletCollision/CollisionDispatch/btGhostObject.h" #include "BulletCollision/CollisionShapes/btMultiSphereShape.h" @@ -24,6 +25,19 @@ subject to the following restrictions: static btVector3 upAxisDirection[3] = { btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f) }; + +// static helper method +static btVector3 +getNormalizedVector(const btVector3& v) +{ + btVector3 n = v.normalized(); + if (n.length() < SIMD_EPSILON) { + n.setValue(0, 0, 0); + } + return n; +} + + ///@todo Interact with dynamic objects, ///Ride kinematicly animated platforms properly ///More realistic (or maybe just a config option) falling @@ -105,6 +119,8 @@ btKinematicCharacterController::btKinematicCharacterController (btPairCachingGho m_stepHeight = stepHeight; m_turnAngle = btScalar(0.0); m_convexShape=convexShape; + m_useWalkDirection = true; // use walk direction by default, legacy behavior + m_velocityTimeInterval = 0.0; } btKinematicCharacterController::~btKinematicCharacterController () @@ -244,13 +260,8 @@ void btKinematicCharacterController::updateTargetPositionBasedOnCollision (const void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* collisionWorld, const btVector3& walkMove) { - - btVector3 originalDir = walkMove.normalized(); - if (walkMove.length() < SIMD_EPSILON) - { - originalDir.setValue(0.f,0.f,0.f); - } -// printf("originalDir=%f,%f,%f\n",originalDir[0],originalDir[1],originalDir[2]); + // printf("m_normalizedDirection=%f,%f,%f\n", + // m_normalizedDirection[0],m_normalizedDirection[1],m_normalizedDirection[2]); // phase 2: forward and strafe btTransform start, end; m_targetPosition = m_currentPosition + walkMove; @@ -263,7 +274,7 @@ void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* co if (m_touchingContact) { - if (originalDir.dot(m_touchingNormal) > btScalar(0.0)) + if (m_normalizedDirection.dot(m_touchingNormal) > btScalar(0.0)) updateTargetPositionBasedOnCollision (m_touchingNormal); } @@ -319,7 +330,7 @@ void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* co { currentDir.normalize(); /* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */ - if (currentDir.dot(originalDir) <= btScalar(0.0)) + if (currentDir.dot(m_normalizedDirection) <= btScalar(0.0)) { break; } @@ -377,6 +388,39 @@ void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld } } + + +void btKinematicCharacterController::setWalkDirection +( +const btVector3& walkDirection +) +{ + m_useWalkDirection = true; + m_walkDirection = walkDirection; + m_normalizedDirection = getNormalizedVector(m_walkDirection); +} + + + +void btKinematicCharacterController::setVelocityForTimeInterval +( +const btVector3& velocity, +btScalar timeInterval +) +{ +// printf("setVelocity!\n"); +// printf(" interval: %f\n", timeInterval); +// printf(" velocity: (%f, %f, %f)\n", +// velocity.x(), velocity.y(), velocity.z()); + + m_useWalkDirection = false; + m_walkDirection = velocity; + m_normalizedDirection = getNormalizedVector(m_walkDirection); + m_velocityTimeInterval = timeInterval; +} + + + void btKinematicCharacterController::reset () { } @@ -415,6 +459,15 @@ void btKinematicCharacterController::preStep ( btCollisionWorld* collisionWorld void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWorld, btScalar dt) { +// printf("playerStep(): "); +// printf(" dt = %f", dt); + + // quick check... + if (!m_useWalkDirection && m_velocityTimeInterval <= 0.0) { +// printf("\n"); + return; // no motion + } + btTransform xform; xform = m_ghostObject->getWorldTransform (); @@ -422,9 +475,27 @@ void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWo // printf("walkSpeed=%f\n",walkSpeed); stepUp (collisionWorld); - stepForwardAndStrafe (collisionWorld, m_walkDirection); + if (m_useWalkDirection) { + stepForwardAndStrafe (collisionWorld, m_walkDirection); + } else { + //printf(" time: %f", m_velocityTimeInterval); + // still have some time left for moving! + btScalar dtMoving = + (dt < m_velocityTimeInterval) ? dt : m_velocityTimeInterval; + m_velocityTimeInterval -= dt; + + // how far will we move while we are moving? + btVector3 move = m_walkDirection * dtMoving; + + // printf(" dtMoving: %f", dtMoving); + + // okay, step + stepForwardAndStrafe(collisionWorld, move); + } stepDown (collisionWorld, dt); + // printf("\n"); + xform.setOrigin (m_currentPosition); m_ghostObject->setWorldTransform (xform); } @@ -473,4 +544,4 @@ bool btKinematicCharacterController::onGround () const void btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer) { -} \ No newline at end of file +} diff --git a/src/BulletDynamics/Character/btKinematicCharacterController.h b/src/BulletDynamics/Character/btKinematicCharacterController.h index 5b96863a7..4fc56c056 100644 --- a/src/BulletDynamics/Character/btKinematicCharacterController.h +++ b/src/BulletDynamics/Character/btKinematicCharacterController.h @@ -20,6 +20,9 @@ subject to the following restrictions: #include "btCharacterControllerInterface.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" + + class btCollisionShape; class btRigidBody; class btCollisionWorld; @@ -49,6 +52,7 @@ protected: ///this is the desired walk direction, set by the user btVector3 m_walkDirection; + btVector3 m_normalizedDirection; //some internal variables btVector3 m_currentPosition; @@ -62,7 +66,8 @@ protected: btVector3 m_touchingNormal; bool m_useGhostObjectSweepTest; - + bool m_useWalkDirection; + float m_velocityTimeInterval; int m_upAxis; btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal); @@ -98,10 +103,20 @@ public: m_upAxis = axis; } - virtual void setWalkDirection(const btVector3& walkDirection) - { - m_walkDirection = walkDirection; - } + /// This should probably be called setPositionIncrementPerSimulatorStep. + /// This is neither a direction nor a velocity, but the amount to + /// increment the position each simulation iteration, regardless + /// of dt. + /// This call will reset any velocity set by setVelocityForTimeInterval(). + virtual void setWalkDirection(const btVector3& walkDirection); + + /// Caller provides a velocity with which the character should move for + /// the given time period. After the time period, velocity is reset + /// to zero. + /// This call will reset any walk direction set by setWalkDirection(). + /// Negative time intervals will result in no motion. + virtual void setVelocityForTimeInterval(const btVector3& velocity, + btScalar timeInterval); void reset (); void warp (const btVector3& origin);