stop avatar integration when standing at rest

This commit is contained in:
Andrew Meadows 2014-05-02 10:43:10 -07:00
parent 9ceda573cc
commit d8cb84080c
3 changed files with 39 additions and 25 deletions

View file

@ -61,7 +61,6 @@ MyAvatar::MyAvatar() :
_shouldJump(false), _shouldJump(false),
_gravity(0.0f, -1.0f, 0.0f), _gravity(0.0f, -1.0f, 0.0f),
_distanceToNearestAvatar(std::numeric_limits<float>::max()), _distanceToNearestAvatar(std::numeric_limits<float>::max()),
_lastCollisionPosition(0, 0, 0),
_wasPushing(false), _wasPushing(false),
_isPushing(false), _isPushing(false),
_thrust(0.0f), _thrust(0.0f),
@ -70,6 +69,7 @@ MyAvatar::MyAvatar() :
_maxMotorSpeed(MAX_MOTOR_SPEED), _maxMotorSpeed(MAX_MOTOR_SPEED),
_motionBehaviors(AVATAR_MOTION_DEFAULTS), _motionBehaviors(AVATAR_MOTION_DEFAULTS),
_lastBodyPenetration(0.0f), _lastBodyPenetration(0.0f),
_lastFloorContactPoint(0.0f),
_lookAtTargetAvatar(), _lookAtTargetAvatar(),
_shouldRender(true), _shouldRender(true),
_billboardValid(false), _billboardValid(false),
@ -151,28 +151,44 @@ void MyAvatar::simulate(float deltaTime) {
// update the movement of the hand and process handshaking with other avatars... // update the movement of the hand and process handshaking with other avatars...
updateHandMovementAndTouching(deltaTime); updateHandMovementAndTouching(deltaTime);
// apply gravity
// For gravity, always move the avatar by the amount driven by gravity, so that the collision
// routines will detect it and collide every frame when pulled by gravity to a surface
const float MIN_DISTANCE_AFTER_COLLISION_FOR_GRAVITY = 0.02f;
if (glm::length(_position - _lastCollisionPosition) > MIN_DISTANCE_AFTER_COLLISION_FOR_GRAVITY) {
_velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime);
}
updateOrientation(deltaTime); updateOrientation(deltaTime);
rampMotor(deltaTime); float keyboardInput = fabsf(_driveKeys[FWD] - _driveKeys[BACK]) +
applyMotor(deltaTime); fabsf(_driveKeys[RIGHT] - _driveKeys[LEFT]) +
fabsf(_driveKeys[UP] - _driveKeys[DOWN]);
applyThrust(deltaTime); bool standingOnFloor = false;
float gravityLength = glm::length(_gravity);
if (gravityLength > EPSILON) {
const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape();
glm::vec3 startCap;
boundingShape.getStartPoint(startCap);
glm::vec3 bottomOfBoundingCapsule = startCap + (boundingShape.getRadius() / gravityLength) * _gravity;
updateChatCircle(deltaTime); float fallThreshold = 2.f * deltaTime * gravityLength;
standingOnFloor = (glm::distance(bottomOfBoundingCapsule, _lastFloorContactPoint) < fallThreshold);
}
if (keyboardInput > 0.0f || glm::length2(_velocity) > 0.0f || glm::length2(_thrust) > 0.0f ||
! standingOnFloor) {
_velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime);
updateMotorFromKeyboard(deltaTime);
applyMotor(deltaTime);
applyThrust(deltaTime);
if (glm::length2(_velocity) < EPSILON) {
_velocity = glm::vec3(0.0f);
} else {
_position += _velocity * deltaTime;
}
}
// update moving flag based on speed // update moving flag based on speed
const float MOVING_SPEED_THRESHOLD = 0.01f; const float MOVING_SPEED_THRESHOLD = 0.01f;
_moving = glm::length(_velocity) > MOVING_SPEED_THRESHOLD; _moving = glm::length(_velocity) > MOVING_SPEED_THRESHOLD;
updateChatCircle(deltaTime);
_position += _velocity * deltaTime;
// update avatar skeleton and simulate hand and head // update avatar skeleton and simulate hand and head
getHand()->collideAgainstOurself(); getHand()->collideAgainstOurself();
@ -631,9 +647,9 @@ void MyAvatar::updateOrientation(float deltaTime) {
setOrientation(orientation); setOrientation(orientation);
} }
void MyAvatar::rampMotor(float deltaTime) { void MyAvatar::updateMotorFromKeyboard(float deltaTime) {
// Increase motor velocity until its length is equal to _maxMotorSpeed. // Increase motor velocity until its length is equal to _maxMotorSpeed.
if (!(_motionBehaviors & AVATAR_MOTION_MOTOR_RAMP_AND_BRAKES_ENABLED)) { if (!(_motionBehaviors & AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED)) {
// nothing to do // nothing to do
return; return;
} }
@ -740,9 +756,8 @@ void MyAvatar::applyMotor(float deltaTime) {
} }
} }
float timescale = computeMotorTimescale();
// simple critical damping // simple critical damping
float timescale = computeMotorTimescale();
float tau = glm::clamp(deltaTime / timescale, 0.0f, 1.0f); float tau = glm::clamp(deltaTime / timescale, 0.0f, 1.0f);
_velocity += tau * deltaVelocity; _velocity += tau * deltaVelocity;
} }
@ -909,7 +924,6 @@ void MyAvatar::updateCollisionWithEnvironment(float deltaTime, float radius) {
if (Application::getInstance()->getEnvironment()->findCapsulePenetration( if (Application::getInstance()->getEnvironment()->findCapsulePenetration(
_position - up * (pelvisFloatingHeight - radius), _position - up * (pelvisFloatingHeight - radius),
_position + up * (getSkeletonHeight() - pelvisFloatingHeight + radius), radius, penetration)) { _position + up * (getSkeletonHeight() - pelvisFloatingHeight + radius), radius, penetration)) {
_lastCollisionPosition = _position;
updateCollisionSound(penetration, deltaTime, ENVIRONMENT_COLLISION_FREQUENCY); updateCollisionSound(penetration, deltaTime, ENVIRONMENT_COLLISION_FREQUENCY);
applyHardCollision(penetration, ENVIRONMENT_SURFACE_ELASTICITY, ENVIRONMENT_SURFACE_DAMPING); applyHardCollision(penetration, ENVIRONMENT_SURFACE_ELASTICITY, ENVIRONMENT_SURFACE_DAMPING);
} }
@ -921,7 +935,7 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
myCollisions.clear(); myCollisions.clear();
const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape(); const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape();
if (Application::getInstance()->getVoxelTree()->findShapeCollisions(&boundingShape, myCollisions)) { if (Application::getInstance()->getVoxelTree()->findShapeCollisions(&boundingShape, myCollisions)) {
const float VOXEL_ELASTICITY = 0.4f; const float VOXEL_ELASTICITY = 0.0f;
const float VOXEL_DAMPING = 0.0f; const float VOXEL_DAMPING = 0.0f;
for (int i = 0; i < myCollisions.size(); ++i) { for (int i = 0; i < myCollisions.size(); ++i) {
CollisionInfo* collision = myCollisions[i]; CollisionInfo* collision = myCollisions[i];

View file

@ -126,7 +126,6 @@ private:
float _distanceToNearestAvatar; // How close is the nearest avatar? float _distanceToNearestAvatar; // How close is the nearest avatar?
// old motion stuff // old motion stuff
glm::vec3 _lastCollisionPosition;
bool _wasPushing; bool _wasPushing;
bool _isPushing; bool _isPushing;
glm::vec3 _thrust; // final acceleration from outside sources for the current frame glm::vec3 _thrust; // final acceleration from outside sources for the current frame
@ -138,6 +137,7 @@ private:
quint32 _motionBehaviors; quint32 _motionBehaviors;
glm::vec3 _lastBodyPenetration; glm::vec3 _lastBodyPenetration;
glm::vec3 _lastFloorContactPoint;
QWeakPointer<AvatarData> _lookAtTargetAvatar; QWeakPointer<AvatarData> _lookAtTargetAvatar;
glm::vec3 _targetAvatarPosition; glm::vec3 _targetAvatarPosition;
bool _shouldRender; bool _shouldRender;
@ -146,7 +146,7 @@ private:
// private methods // private methods
void updateOrientation(float deltaTime); void updateOrientation(float deltaTime);
void rampMotor(float deltaTime); void updateMotorFromKeyboard(float deltaTime);
float computeMotorTimescale(); float computeMotorTimescale();
void applyMotor(float deltaTime); void applyMotor(float deltaTime);
void applyThrust(float deltaTime); void applyThrust(float deltaTime);

View file

@ -52,7 +52,7 @@ typedef unsigned long long quint64;
// avatar motion behaviors // avatar motion behaviors
const quint32 AVATAR_MOTION_MOTOR_ENABLED = 1U << 0; const quint32 AVATAR_MOTION_MOTOR_ENABLED = 1U << 0;
const quint32 AVATAR_MOTION_MOTOR_RAMP_AND_BRAKES_ENABLED = 1U << 1; const quint32 AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED = 1U << 1;
const quint32 AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME = 1U << 2; const quint32 AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME = 1U << 2;
const quint32 AVATAR_MOTION_MOTOR_COLLISION_SURFACE_ONLY = 1U << 3; const quint32 AVATAR_MOTION_MOTOR_COLLISION_SURFACE_ONLY = 1U << 3;
@ -61,7 +61,7 @@ const quint32 AVATAR_MOTION_OBEY_LOCAL_GRAVITY = 1U << 5;
const quint32 AVATAR_MOTION_DEFAULTS = const quint32 AVATAR_MOTION_DEFAULTS =
AVATAR_MOTION_MOTOR_ENABLED | AVATAR_MOTION_MOTOR_ENABLED |
AVATAR_MOTION_MOTOR_RAMP_AND_BRAKES_ENABLED | AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED |
AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME; AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME;
// these bits will be expanded as features are exposed // these bits will be expanded as features are exposed