mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-10 03:53:22 +02:00
Added hysteresis to the state machine for turning and moving states.
This should help a bit with the jerkiness, as state transitions occur less often due to noise or the user straddling the boundary between two states.
This commit is contained in:
parent
85cb503152
commit
dcecd7b73a
2 changed files with 34 additions and 6 deletions
|
@ -427,10 +427,12 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
glm::vec3 positionDelta = worldPosition - _lastPosition;
|
glm::vec3 positionDelta = worldPosition - _lastPosition;
|
||||||
glm::vec3 workingVelocity = positionDelta / deltaTime;
|
glm::vec3 workingVelocity = positionDelta / deltaTime;
|
||||||
|
|
||||||
|
#if !WANT_DEBUG
|
||||||
// But for smoothest (non-hmd standing) results, go ahead and use velocity:
|
// But for smoothest (non-hmd standing) results, go ahead and use velocity:
|
||||||
if (!positionDelta.x && !positionDelta.y && !positionDelta.z) {
|
if (!positionDelta.x && !positionDelta.y && !positionDelta.z) {
|
||||||
workingVelocity = worldVelocity;
|
workingVelocity = worldVelocity;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_enableAnimGraph) {
|
if (_enableAnimGraph) {
|
||||||
|
|
||||||
|
@ -454,12 +456,29 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
_animVars.set("isNotTurning", true);
|
_animVars.set("isNotTurning", true);
|
||||||
|
|
||||||
const float ANIM_WALK_SPEED = 1.4f; // m/s
|
const float ANIM_WALK_SPEED = 1.4f; // m/s
|
||||||
_animVars.set("walkTimeScale", glm::clamp(0.1f, 2.0f, glm::length(localVel) / ANIM_WALK_SPEED));
|
_animVars.set("walkTimeScale", glm::clamp(0.5f, 2.0f, glm::length(localVel) / ANIM_WALK_SPEED));
|
||||||
|
|
||||||
const float MOVE_SPEED_THRESHOLD = 0.01f; // m/sec
|
const float MOVE_ENTER_SPEED_THRESHOLD = 0.2f; // m/sec
|
||||||
const float TURN_SPEED_THRESHOLD = 0.5f; // rad/sec
|
const float MOVE_EXIT_SPEED_THRESHOLD = 0.07f; // m/sec
|
||||||
if (glm::length(localVel) > MOVE_SPEED_THRESHOLD) {
|
const float TURN_ENTER_SPEED_THRESHOLD = 0.5f; // rad/sec
|
||||||
if (fabs(forwardSpeed) > fabs(lateralSpeed)) {
|
const float TURN_EXIT_SPEED_THRESHOLD = 0.2f; // rad/sec
|
||||||
|
|
||||||
|
float moveThresh;
|
||||||
|
if (_state != RigRole::Move) {
|
||||||
|
moveThresh = MOVE_ENTER_SPEED_THRESHOLD;
|
||||||
|
} else {
|
||||||
|
moveThresh = MOVE_EXIT_SPEED_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
float turnThresh;
|
||||||
|
if (_state != RigRole::Turn) {
|
||||||
|
turnThresh = TURN_ENTER_SPEED_THRESHOLD;
|
||||||
|
} else {
|
||||||
|
turnThresh = TURN_EXIT_SPEED_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glm::length(localVel) > moveThresh) {
|
||||||
|
if (fabs(forwardSpeed) > 0.5f * fabs(lateralSpeed)) {
|
||||||
if (forwardSpeed > 0.0f) {
|
if (forwardSpeed > 0.0f) {
|
||||||
// forward
|
// forward
|
||||||
_animVars.set("isMovingForward", true);
|
_animVars.set("isMovingForward", true);
|
||||||
|
@ -481,8 +500,9 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
_animVars.set("isNotMoving", false);
|
_animVars.set("isNotMoving", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_state = RigRole::Move;
|
||||||
} else {
|
} else {
|
||||||
if (fabs(turningSpeed) > TURN_SPEED_THRESHOLD) {
|
if (fabs(turningSpeed) > turnThresh) {
|
||||||
if (turningSpeed > 0.0f) {
|
if (turningSpeed > 0.0f) {
|
||||||
// turning right
|
// turning right
|
||||||
_animVars.set("isTurningRight", true);
|
_animVars.set("isTurningRight", true);
|
||||||
|
@ -492,8 +512,10 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
_animVars.set("isTurningLeft", true);
|
_animVars.set("isTurningLeft", true);
|
||||||
_animVars.set("isNotTurning", false);
|
_animVars.set("isNotTurning", false);
|
||||||
}
|
}
|
||||||
|
_state = RigRole::Turn;
|
||||||
} else {
|
} else {
|
||||||
// idle
|
// idle
|
||||||
|
_state = RigRole::Idle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,12 @@ public:
|
||||||
std::shared_ptr<AnimSkeleton> _animSkeleton;
|
std::shared_ptr<AnimSkeleton> _animSkeleton;
|
||||||
std::unique_ptr<AnimNodeLoader> _animLoader;
|
std::unique_ptr<AnimNodeLoader> _animLoader;
|
||||||
AnimVariantMap _animVars;
|
AnimVariantMap _animVars;
|
||||||
|
enum class RigRole {
|
||||||
|
Idle = 0,
|
||||||
|
Turn,
|
||||||
|
Move
|
||||||
|
};
|
||||||
|
RigRole _state = RigRole::Idle;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__Rig__) */
|
#endif /* defined(__hifi__Rig__) */
|
||||||
|
|
Loading…
Reference in a new issue