From 1ad6b041cd0ebb46eebfd31880ddd797c0db2f61 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 6 Aug 2018 18:36:32 -0700 Subject: [PATCH] updated the elipes equation code for determining the forward speed of the avatar. We can now set the max forward == walkSpeed, max side and backwards == walkBackwardsSpeed and the sprint speed == sprintSpeed --- .../resources/avatar/avatar-animation.json | 10 +++---- interface/src/avatar/MyAvatar.cpp | 30 ++++++++++++++----- interface/src/avatar/MyAvatar.h | 5 ++++ interface/src/ui/Stats.cpp | 3 -- libraries/animation/src/AnimBlendLinear.cpp | 25 +++++++--------- .../animation/src/AnimBlendLinearMove.cpp | 16 ++++++---- libraries/animation/src/Rig.cpp | 13 -------- 7 files changed, 53 insertions(+), 49 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index 10e841f05d..982d9ab8d2 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -654,7 +654,7 @@ "interpDuration": 6, "interpType": "snapshotPrev", "transitions": [ - { "var": "isNotMoving", "state": "idle" }, + { "var": "isNotMoving", "state": "idleSettle" }, { "var": "isMovingBackward", "state": "walkBwd" }, { "var": "isMovingRight", "state": "strafeRight" }, { "var": "isMovingLeft", "state": "strafeLeft" }, @@ -675,7 +675,7 @@ "interpDuration": 6, "interpType": "snapshotPrev", "transitions": [ - { "var": "isNotMoving", "state": "idle" }, + { "var": "isNotMoving", "state": "idleSettle" }, { "var": "isMovingForward", "state": "walkFwd" }, { "var": "isMovingRight", "state": "strafeRight" }, { "var": "isMovingLeft", "state": "strafeLeft" }, @@ -696,7 +696,7 @@ "interpDuration": 8, "interpType": "snapshotPrev", "transitions": [ - { "var": "isNotMoving", "state": "idle" }, + { "var": "isNotMoving", "state": "idleSettle" }, { "var": "isMovingForward", "state": "walkFwd" }, { "var": "isMovingBackward", "state": "walkBwd" }, { "var": "isMovingLeft", "state": "strafeLeft" }, @@ -717,7 +717,7 @@ "interpDuration": 6, "interpType": "snapshotPrev", "transitions": [ - { "var": "isNotMoving", "state": "idle" }, + { "var": "isNotMoving", "state": "idleSettle" }, { "var": "isMovingForward", "state": "walkFwd" }, { "var": "isMovingBackward", "state": "walkBwd" }, { "var": "isMovingRight", "state": "strafeRight" }, @@ -821,7 +821,7 @@ "interpTarget": 6, "interpDuration": 6, "transitions": [ - { "var": "isNotFlying", "state": "idle" } + { "var": "isNotFlying", "state": "idleSettle" } ] }, { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ac6790d241..dff14e8d40 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2336,13 +2336,19 @@ void MyAvatar::updateOrientation(float deltaTime) { } } -static float scaleSpeedByDirection(glm::vec2 velocityDirection, float speed) { - float scale = 1.0f; - float x = sqrtf(1.0f - (velocityDirection.y * velocityDirection.y) / 3.0f); - if (velocityDirection.y > 0.0f) { - scale = 0.5f; +static float scaleSpeedByDirection(glm::vec2 velocityDirection, float forwardSpeed, float backwardSpeed) { + // for the elipse function --> (x^2)*(1/backwardSpeed*backwardSpeed) + y^2/(forwardSpeed*forwardSpeed) = 1, scale == y^2 when x is 0 + float fwdScale = forwardSpeed * forwardSpeed; + float backScale = 1.0f / (backwardSpeed * backwardSpeed); + float scaledX = velocityDirection.x * backwardSpeed; + float scaledSpeed = backwardSpeed; + if (velocityDirection.y < 0.0f) { + float yValue = sqrtf(fwdScale * (1.0f - (scaledX * scaledX * backScale))); + scaledSpeed = sqrtf((scaledX * scaledX) + (yValue * yValue)); + } else { + scaledSpeed = backwardSpeed; } - return scale * speed; + return scaledSpeed; } void MyAvatar::updateActionMotor(float deltaTime) { @@ -2407,8 +2413,7 @@ void MyAvatar::updateActionMotor(float deltaTime) { } else { // we're interacting with a floor --> simple horizontal speed and exponential decay const glm::vec2 currentVel = { direction.x, direction.z }; - float wspd = _walkSpeed.get(); - float scaledSpeed = scaleSpeedByDirection(currentVel, wspd); + float scaledSpeed = scaleSpeedByDirection(currentVel, _walkSpeed.get(), _walkBackwardSpeed.get()); _actionMotorVelocity = getSensorToWorldScale() * (scaledSpeed * _walkSpeedScalar) * direction; } @@ -3418,6 +3423,10 @@ float MyAvatar::getWalkSpeed() const { return _walkSpeed.get() * _walkSpeedScalar; } +float MyAvatar::getWalkBackwardSpeed() const { + return _walkSpeed.get() * _walkSpeedScalar; +} + bool MyAvatar::isReadyForPhysics() const { return qApp->isServerlessMode() || _haveReceivedHeightLimitsFromDomain; } @@ -3430,6 +3439,11 @@ void MyAvatar::setWalkSpeed(float value) { _walkSpeed.set(value); } +void MyAvatar::setWalkBackwardSpeed(float value) { + _walkBackwardSpeed.set(value); +} + + void MyAvatar::setSprintSpeed(float speed) { _sprintSpeed.set(speed); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 486e4479be..d1ad22d2aa 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -138,6 +138,7 @@ class MyAvatar : public Avatar { * where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain). Note: Likely to be deprecated. * Read-only. * @property {number} walkSpeed + * @property {number} walkBackwardSpeed * @property {number} sprintSpeed * * @property {Vec3} skeletonOffset - Can be used to apply a translation offset between the avatar's position and the @@ -234,6 +235,7 @@ class MyAvatar : public Avatar { Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT) Q_PROPERTY(float walkSpeed READ getWalkSpeed WRITE setWalkSpeed); + Q_PROPERTY(float walkBackwardSpeed READ getWalkBackwardSpeed WRITE setWalkBackwardSpeed); Q_PROPERTY(float sprintSpeed READ getSprintSpeed WRITE setSprintSpeed); const QString DOMINANT_LEFT_HAND = "left"; @@ -1076,6 +1078,8 @@ public: void setWalkSpeed(float value); float getWalkSpeed() const; + void setWalkBackwardSpeed(float value); + float getWalkBackwardSpeed() const; void setSprintSpeed(float speed); float getSprintSpeed() const; @@ -1735,6 +1739,7 @@ private: // max unscaled forward movement speed ThreadSafeValueCache _walkSpeed { DEFAULT_AVATAR_MAX_WALKING_SPEED }; + ThreadSafeValueCache _walkBackwardSpeed{ 0.5 * DEFAULT_AVATAR_MAX_WALKING_SPEED }; ThreadSafeValueCache _sprintSpeed { AVATAR_SPRINT_SPEED_SCALAR }; float _walkSpeedScalar { AVATAR_WALK_SPEED_SCALAR }; diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 99ce8b4f03..d94a5bf6fe 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -34,7 +34,6 @@ #include "Util.h" #include "SequenceNumberStats.h" #include "StatTracker.h" -#include "InterfaceLogging.h" HIFI_QML_DEF(Stats) @@ -194,12 +193,10 @@ void Stats::updateStats(bool force) { auto myAvatar = avatarManager->getMyAvatar(); auto rigCopy = myAvatar->getSkeletonModel(); auto animStack = rigCopy->getRig().getAnimStack(); - qCDebug(interfaceapp) << "Animation Stack Begin: "; //check to see if the anim stack has changed _animStackNames.clear(); for (auto animStackIterator = animStack.begin(); animStackIterator != animStack.end(); ++animStackIterator) { - qCDebug(interfaceapp) << "---" << animStackIterator->first << " " << animStackIterator->second; _animStackNames << animStackIterator->first + ": " + QString::number(animStackIterator->second,'f',3); } emit animStackNamesChanged(); diff --git a/libraries/animation/src/AnimBlendLinear.cpp b/libraries/animation/src/AnimBlendLinear.cpp index 50fdb166fc..e2d79f864d 100644 --- a/libraries/animation/src/AnimBlendLinear.cpp +++ b/libraries/animation/src/AnimBlendLinear.cpp @@ -37,27 +37,24 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, con _poses = _children[0]->evaluate(animVars, context, dt, triggersOut); _animStack[_children[0]->getID()] = parentAlpha; } else { - float clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1)); size_t prevPoseIndex = glm::floor(clampedAlpha); size_t nextPoseIndex = glm::ceil(clampedAlpha); - if (prevPoseIndex == nextPoseIndex) { - if (nextPoseIndex == 0) { - nextPoseIndex = 1; - } else { - prevPoseIndex = (nextPoseIndex - 1); - } - } - float alpha = clampedAlpha - (float)prevPoseIndex; + auto alpha = glm::fract(clampedAlpha); evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, dt); - float weight2 = _alpha - (float)prevPoseIndex; - float weight1 = 1.0f - weight2; - _animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha; - if (nextPoseIndex < _children.size()) { + // weights are for animation stack debug purposes only. + float weight1 = 0.0f; + float weight2 = 0.0f; + if (prevPoseIndex == nextPoseIndex) { + weight2 = 1.0f; + _animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha; + } else { + weight2 = alpha; + weight1 = 1.0f - weight2; + _animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha; _animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha; } - } processOutputJoints(triggersOut); diff --git a/libraries/animation/src/AnimBlendLinearMove.cpp b/libraries/animation/src/AnimBlendLinearMove.cpp index f17ac3defe..5084a45f68 100644 --- a/libraries/animation/src/AnimBlendLinearMove.cpp +++ b/libraries/animation/src/AnimBlendLinearMove.cpp @@ -67,8 +67,6 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars, _animStack["speed"] = speed; - qCDebug(animation) << "speed is now: " << speed; - if (_children.size() == 0) { for (auto&& pose : _poses) { pose = AnimPose::identity; @@ -90,10 +88,16 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars, setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut); evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime); - float weight2 = alpha; - float weight1 = 1.0f - weight2; - _animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha; - if ((int)nextPoseIndex < _children.size()) { + // weights are for animation stack debug purposes only. + float weight1 = 0.0f; + float weight2 = 0.0f; + if (prevPoseIndex == nextPoseIndex) { + weight2 = 1.0f; + _animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha; + } else { + weight2 = alpha; + weight1 = 1.0f - weight2; + _animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha; _animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha; } } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 3ab8dfe8ff..5c3305e05c 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -815,19 +815,6 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInAirRun", false); _animVars.set("isNotInAir", true); - if (false) { - // if we are changing anim states. - //reset the average speed to the current reading of speed - qCDebug(animation) << "reset the average movement speeds"; - _averageForwardSpeed.reset(); - _averageLateralSpeed.reset(); - _averageForwardSpeed.updateAverage(forwardSpeed); - _averageLateralSpeed.updateAverage(lateralSpeed); - _animVars.set("moveForwardSpeed", _averageForwardSpeed.getAverage()); - _animVars.set("moveBackwardSpeed", -_averageForwardSpeed.getAverage()); - _animVars.set("moveLateralSpeed", fabsf(_averageLateralSpeed.getAverage())); - } - } else if (_state == RigRole::Turn) { if (turningSpeed > 0.0f) { // turning right