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