measure avatar velocity while driving

and add to followVelocity for tighter tracking at high speeds
This commit is contained in:
Andrew Meadows 2016-09-27 16:59:50 -07:00
parent 910ea24bbd
commit a10ae20bf7
2 changed files with 44 additions and 14 deletions

View file

@ -230,6 +230,7 @@ const btScalar MIN_TARGET_SPEED_SQUARED = MIN_TARGET_SPEED * MIN_TARGET_SPEED;
void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
btVector3 velocity = _rigidBody->getLinearVelocity() - _parentVelocity;
if (_following) {
_followTimeAccumulator += dt;
// linear part uses a motor
const float MAX_WALKING_SPEED = 30.5f; // TODO: scale this stuff with avatar size
const float MAX_WALKING_SPEED_DISTANCE = 1.0f;
@ -243,22 +244,28 @@ void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
const float MIN_DELTA_DISTANCE = 0.01f; // TODO: scale by avatar size but cap at (NORMAL_WALKING_SPEED * FEW_SUBSTEPS)
if (deltaDistance > MIN_DELTA_DISTANCE) {
btVector3 vel = deltaPos;
if (deltaDistance > MAX_WALKING_SPEED_DISTANCE) {
// cap max speed
vel *= MAX_WALKING_SPEED / deltaDistance;
} else if (deltaDistance > NORMAL_WALKING_SPEED_DISTANCE) {
// linearly interpolate to NORMAL_WALKING_SPEED
btScalar alpha = (deltaDistance - NORMAL_WALKING_SPEED_DISTANCE) / (MAX_WALKING_SPEED_DISTANCE - NORMAL_WALKING_SPEED_DISTANCE);
vel *= NORMAL_WALKING_SPEED * (1.0f - alpha) + MAX_WALKING_SPEED * alpha;
if (_state == State::Hover) {
btScalar HOVER_FOLLOW_VELOCITY_TIMESCALE = 0.1f;
vel /= HOVER_FOLLOW_VELOCITY_TIMESCALE;
} else {
// use exponential decay but cap at NORMAL_WALKING_SPEED
vel /= FEW_SUBSTEPS;
btScalar speed = vel.length();
if (speed > NORMAL_WALKING_SPEED) {
vel *= NORMAL_WALKING_SPEED / speed;
if (deltaDistance > MAX_WALKING_SPEED_DISTANCE) {
// cap max speed
vel *= MAX_WALKING_SPEED / deltaDistance;
} else if (deltaDistance > NORMAL_WALKING_SPEED_DISTANCE) {
// linearly interpolate to NORMAL_WALKING_SPEED
btScalar alpha = (deltaDistance - NORMAL_WALKING_SPEED_DISTANCE) / (MAX_WALKING_SPEED_DISTANCE - NORMAL_WALKING_SPEED_DISTANCE);
vel *= NORMAL_WALKING_SPEED * (1.0f - alpha) + MAX_WALKING_SPEED * alpha;
} else {
// use exponential decay but cap at NORMAL_WALKING_SPEED
vel /= FEW_SUBSTEPS;
btScalar speed = vel.length();
if (speed > NORMAL_WALKING_SPEED) {
vel *= NORMAL_WALKING_SPEED / speed;
}
}
}
const float HORIZONTAL_FOLLOW_TIMESCALE = 0.1f;
vel += _followVelocity;
const float HORIZONTAL_FOLLOW_TIMESCALE = 0.05f;
const float VERTICAL_FOLLOW_TIMESCALE = (_state == State::Hover) ? HORIZONTAL_FOLLOW_TIMESCALE : 20.0f;
glm::quat worldFrameRotation; // identity
vel.setY(0.0f); // don't allow any vertical component of the follow velocity to enter the _targetVelocity.
@ -453,7 +460,27 @@ void CharacterController::setParentVelocity(const glm::vec3& velocity) {
void CharacterController::setFollowParameters(const glm::mat4& desiredWorldBodyMatrix) {
_followDesiredBodyTransform = glmToBullet(desiredWorldBodyMatrix) * btTransform(btQuaternion::getIdentity(), glmToBullet(_shapeLocalOffset));
_following = true;
if (!_following) {
_following = true;
_followVelocity = btVector3(0.0f, 0.0f, 0.0f);
} else if (_followTimeAccumulator > 0.0f) {
btVector3 newFollowVelocity = (_followDesiredBodyTransform.getOrigin() - _previousFollowPosition) / _followTimeAccumulator;
const float dontDivideByZero = 0.001f;
float newSpeed = newFollowVelocity.length() + dontDivideByZero;
float oldSpeed = _followVelocity.length();
const float VERY_SLOW_HOVER_SPEED = 0.25f;
if (oldSpeed / newSpeed > 100.0f && newSpeed < VERY_SLOW_HOVER_SPEED) {
// avatar is stopping quickly
// HACK: slam _followVelocity and _rigidBody velocity immediately
_followVelocity = newFollowVelocity;
_rigidBody->setLinearVelocity(_followVelocity);
} else {
const float blend = 0.2f;
_followVelocity = (1.0f - blend) * _followVelocity + blend * newFollowVelocity;
}
}
_previousFollowPosition = _followDesiredBodyTransform.getOrigin();
_followTimeAccumulator = 0.0f;
}
glm::vec3 CharacterController::getLinearVelocity() const {

View file

@ -148,6 +148,8 @@ protected:
glm::vec3 _preActionVelocity;
btVector3 _velocityChange;
btTransform _followDesiredBodyTransform;
btVector3 _followVelocity { 0.0f, 0.0f, 0.0f };
btVector3 _previousFollowPosition { 0.0f, 0.0f, 0.0f };
btVector3 _position;
btQuaternion _rotation;
@ -175,6 +177,7 @@ protected:
bool _hasSupport;
btScalar _gravity;
btScalar _followTimeAccumulator { 0.0f };
btScalar _jumpSpeed;
btVector3 _linearAcceleration;