From 073cec41c41c77546824f2fda5780c8a28c86df5 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 16 Oct 2015 12:11:46 -0700 Subject: [PATCH] AnimClip & accumulateTime smoother looping anims Looping animations should have an extra frame of interpolation between the start and end frames. --- libraries/animation/src/AnimClip.cpp | 11 ++++++----- libraries/animation/src/AnimUtil.cpp | 7 +++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index 97f46a1b68..613194164f 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -47,16 +47,17 @@ const AnimPoseVec& AnimClip::evaluate(const AnimVariantMap& animVars, float dt, } if (_anim.size()) { - int frameCount = _anim.size(); - int prevIndex = (int)glm::floor(_frame); - int nextIndex = (int)glm::ceil(_frame); - if (_loopFlag && nextIndex >= frameCount) { - nextIndex = 0; + int nextIndex; + if (_loopFlag && _frame >= _endFrame) { + nextIndex = (int)glm::ceil(_startFrame); + } else { + nextIndex = (int)glm::ceil(_frame); } // It can be quite possible for the user to set _startFrame and _endFrame to // values before or past valid ranges. We clamp the frames here. + int frameCount = _anim.size(); prevIndex = std::min(std::max(0, prevIndex), frameCount - 1); nextIndex = std::min(std::max(0, nextIndex), frameCount - 1); diff --git a/libraries/animation/src/AnimUtil.cpp b/libraries/animation/src/AnimUtil.cpp index c8efa85df9..e9e5ea95de 100644 --- a/libraries/animation/src/AnimUtil.cpp +++ b/libraries/animation/src/AnimUtil.cpp @@ -29,8 +29,7 @@ float accumulateTime(float startFrame, float endFrame, float timeScale, float cu float frame = currentFrame; const float clampedStartFrame = std::min(startFrame, endFrame); - if (clampedStartFrame == endFrame) { - // when clampedStartFrame >= endFrame + if (fabsf(clampedStartFrame - endFrame) < 1.0f) { frame = endFrame; } else if (timeScale > 0.0f) { // accumulate time, keeping track of loops and end of animation events. @@ -38,6 +37,10 @@ float accumulateTime(float startFrame, float endFrame, float timeScale, float cu float framesRemaining = (dt * timeScale) * FRAMES_PER_SECOND; while (framesRemaining > 0.0f) { float framesTillEnd = endFrame - frame; + // when looping, add one frame between start and end. + if (loopFlag) { + framesTillEnd += 1.0f; + } if (framesRemaining >= framesTillEnd) { if (loopFlag) { // anim loop