cleanup logic to be more readable

This commit is contained in:
Andrew Meadows 2017-05-08 10:52:54 -07:00
parent 2bfbb63906
commit f00a3cafb6

View file

@ -273,28 +273,37 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar
if (_steppingUp) { if (_steppingUp) {
// compute a stepUpSpeed that will reach the top of the step in the time it would take // compute a stepUpSpeed that will reach the top of the step in the time it would take
// to move over the _stepPoint at target speed // to move over the _stepPoint at target speed
float hDistance = sqrtf(_stepPoint.getX() * _stepPoint.getX() + _stepPoint.getZ() * _stepPoint.getZ()); float horizontalDistance = (_stepPoint - _stepPoint.dot(_currentUp) * _currentUp).length();
float targetSpeed = _targetVelocity.length(); float horizontalTargetSpeed = (_targetVelocity - _targetVelocity.dot(_currentUp) * _currentUp).length();
float timeToStep = hDistance / targetSpeed; float timeToStep = horizontalDistance / horizontalTargetSpeed;
float stepUpSpeed = _stepHeight / timeToStep + 0.5f * _gravity * timeToStep; float stepUpSpeed = _stepHeight / timeToStep;
const float MAX_STEP_UP_SPEED = 0.65f * targetSpeed;
// magically clamp stepUpSpeed to a fraction of horizontalTargetSpeed
// to prevent the avatar from moving unreasonably fast according to human eye
const float MAX_STEP_UP_SPEED = 0.65f * horizontalTargetSpeed;
if (stepUpSpeed > MAX_STEP_UP_SPEED) { if (stepUpSpeed > MAX_STEP_UP_SPEED) {
stepUpSpeed = MAX_STEP_UP_SPEED; stepUpSpeed = MAX_STEP_UP_SPEED;
} }
btScalar vDotUp = velocity.dot(_currentUp); // add minimum velocity to counteract gravity's displacement during one step
if (stepUpSpeed > vDotUp) { // Note: the 0.5 factor comes from the fact that we really want the
// don't have enough upward velocity to cover the step // average velocity contribution from gravity during the step
stepUpSpeed -= 0.5f * _gravity * timeToStep; // remember: _gravity is negative scalar
// we step up with micro-teleports rather than applying velocity btScalar vDotUp = velocity.dot(_currentUp);
// use a speed that would ballistically reach _stepHeight under gravity if (vDotUp < stepUpSpeed) {
// character doesn't have enough upward velocity to cover the step so we help using a "sky hook"
// which uses micro-teleports rather than applying real velocity
// to prevent the avatar from popping up after the step is done
btTransform transform = _rigidBody->getWorldTransform(); btTransform transform = _rigidBody->getWorldTransform();
transform.setOrigin(transform.getOrigin() + (dt * stepUpSpeed) * _currentUp); transform.setOrigin(transform.getOrigin() + (dt * stepUpSpeed) * _currentUp);
_rigidBody->setWorldTransform(transform); _rigidBody->setWorldTransform(transform);
} }
float minStepUpSpeed = 0.0f;
if (vDotUp < minStepUpSpeed) { // don't allow the avatar to fall downward when stepping up
velocity += (minStepUpSpeed - vDotUp) * _currentUp; // since otherwise this would tend to defeat the step-up behavior
if (vDotUp < 0.0f) {
velocity -= vDotUp * _currentUp;
} }
} }
_rigidBody->setLinearVelocity(velocity + _parentVelocity); _rigidBody->setLinearVelocity(velocity + _parentVelocity);