From d8cb84080c2fa5cf4dbd961ce2699ae46e6e0540 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 2 May 2014 10:43:10 -0700 Subject: [PATCH] stop avatar integration when standing at rest --- interface/src/avatar/MyAvatar.cpp | 56 +++++++++++++++++++----------- interface/src/avatar/MyAvatar.h | 4 +-- libraries/avatars/src/AvatarData.h | 4 +-- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 2f76032a44..ff85900065 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -61,7 +61,6 @@ MyAvatar::MyAvatar() : _shouldJump(false), _gravity(0.0f, -1.0f, 0.0f), _distanceToNearestAvatar(std::numeric_limits::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]; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index b357f7bb6e..eed567d030 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -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 _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); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 3c1aa9963d..af0b0c57d6 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -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