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),
_gravity(0.0f, -1.0f, 0.0f),
_distanceToNearestAvatar(std::numeric_limits<float>::max()),
_lastCollisionPosition(0, 0, 0),
_wasPushing(false),
_isPushing(false),
_thrust(0.0f),
@ -70,6 +69,7 @@ MyAvatar::MyAvatar() :
_maxMotorSpeed(MAX_MOTOR_SPEED),
_motionBehaviors(AVATAR_MOTION_DEFAULTS),
_lastBodyPenetration(0.0f),
_lastFloorContactPoint(0.0f),
_lookAtTargetAvatar(),
_shouldRender(true),
_billboardValid(false),
@ -151,28 +151,44 @@ void MyAvatar::simulate(float deltaTime) {
// update the movement of the hand and process handshaking with other avatars...
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);
rampMotor(deltaTime);
applyMotor(deltaTime);
float keyboardInput = fabsf(_driveKeys[FWD] - _driveKeys[BACK]) +
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
const float MOVING_SPEED_THRESHOLD = 0.01f;
_moving = glm::length(_velocity) > MOVING_SPEED_THRESHOLD;
_position += _velocity * deltaTime;
updateChatCircle(deltaTime);
// update avatar skeleton and simulate hand and head
getHand()->collideAgainstOurself();
@ -631,9 +647,9 @@ void MyAvatar::updateOrientation(float deltaTime) {
setOrientation(orientation);
}
void MyAvatar::rampMotor(float deltaTime) {
void MyAvatar::updateMotorFromKeyboard(float deltaTime) {
// 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
return;
}
@ -740,9 +756,8 @@ void MyAvatar::applyMotor(float deltaTime) {
}
}
float timescale = computeMotorTimescale();
// simple critical damping
float timescale = computeMotorTimescale();
float tau = glm::clamp(deltaTime / timescale, 0.0f, 1.0f);
_velocity += tau * deltaVelocity;
}
@ -909,7 +924,6 @@ void MyAvatar::updateCollisionWithEnvironment(float deltaTime, float radius) {
if (Application::getInstance()->getEnvironment()->findCapsulePenetration(
_position - up * (pelvisFloatingHeight - radius),
_position + up * (getSkeletonHeight() - pelvisFloatingHeight + radius), radius, penetration)) {
_lastCollisionPosition = _position;
updateCollisionSound(penetration, deltaTime, ENVIRONMENT_COLLISION_FREQUENCY);
applyHardCollision(penetration, ENVIRONMENT_SURFACE_ELASTICITY, ENVIRONMENT_SURFACE_DAMPING);
}
@ -921,7 +935,7 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
myCollisions.clear();
const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape();
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;
for (int i = 0; i < myCollisions.size(); ++i) {
CollisionInfo* collision = myCollisions[i];

View file

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

View file

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