From 4bdb00bbc5f3d0ccec115ba6a2f71c91088b8a58 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 25 Aug 2015 09:58:36 -0700 Subject: [PATCH] Added setCurrentFrame interface to AnimClip. This will recurse the tree and call setCurrentFrameInternal on each node. This method can be overriden, currently the only meaningful implementation is AnimClip. --- libraries/animation/src/AnimClip.cpp | 69 +++++++++++++++------------- libraries/animation/src/AnimClip.h | 2 + libraries/animation/src/AnimNode.h | 9 +++- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index 9863d71882..dca43cb735 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -45,38 +45,6 @@ void AnimClip::setLoopFlag(bool loopFlag) { _loopFlag = loopFlag; } -float AnimClip::accumulateTime(float frame, float dt) const { - const float startFrame = std::min(_startFrame, _endFrame); - if (startFrame == _endFrame) { - // when startFrame >= endFrame - frame = _endFrame; - } else if (_timeScale > 0.0f) { - // accumulate time, keeping track of loops and end of animation events. - const float FRAMES_PER_SECOND = 30.0f; - float framesRemaining = (dt * _timeScale) * FRAMES_PER_SECOND; - while (framesRemaining > 0.0f) { - float framesTillEnd = _endFrame - _frame; - if (framesRemaining >= framesTillEnd) { - if (_loopFlag) { - // anim loop - // TODO: trigger onLoop event - framesRemaining -= framesTillEnd; - frame = startFrame; - } else { - // anim end - // TODO: trigger onDone event - frame = _endFrame; - framesRemaining = 0.0f; - } - } else { - frame += framesRemaining; - framesRemaining = 0.0f; - } - } - } - return frame; -} - const std::vector& AnimClip::evaluate(float dt) { _frame = accumulateTime(_frame, dt); @@ -109,6 +77,43 @@ const std::vector& AnimClip::evaluate(float dt) { return _poses; } +void AnimClip::setCurrentFrameInternal(float frame) { + const float dt = 0.0f; + _frame = accumulateTime(frame, dt); +} + +float AnimClip::accumulateTime(float frame, float dt) const { + const float startFrame = std::min(_startFrame, _endFrame); + if (startFrame == _endFrame) { + // when startFrame >= endFrame + frame = _endFrame; + } else if (_timeScale > 0.0f) { + // accumulate time, keeping track of loops and end of animation events. + const float FRAMES_PER_SECOND = 30.0f; + float framesRemaining = (dt * _timeScale) * FRAMES_PER_SECOND; + while (framesRemaining > 0.0f) { + float framesTillEnd = _endFrame - _frame; + if (framesRemaining >= framesTillEnd) { + if (_loopFlag) { + // anim loop + // TODO: trigger onLoop event + framesRemaining -= framesTillEnd; + frame = startFrame; + } else { + // anim end + // TODO: trigger onDone event + frame = _endFrame; + framesRemaining = 0.0f; + } + } else { + frame += framesRemaining; + framesRemaining = 0.0f; + } + } + } + return frame; +} + void AnimClip::copyFromNetworkAnim() { assert(_networkAnim && _networkAnim->isLoaded() && _skeleton); _anim.clear(); diff --git a/libraries/animation/src/AnimClip.h b/libraries/animation/src/AnimClip.h index 1868ac0e03..3480fdc3cf 100644 --- a/libraries/animation/src/AnimClip.h +++ b/libraries/animation/src/AnimClip.h @@ -45,6 +45,8 @@ public: virtual const std::vector& evaluate(float dt) override; protected: + virtual void setCurrentFrameInternal(float frame) override; + float accumulateTime(float frame, float dt) const; void copyFromNetworkAnim(); diff --git a/libraries/animation/src/AnimNode.h b/libraries/animation/src/AnimNode.h index cae3d1805f..9063488e9b 100644 --- a/libraries/animation/src/AnimNode.h +++ b/libraries/animation/src/AnimNode.h @@ -43,6 +43,7 @@ public: typedef std::shared_ptr Pointer; AnimNode(Type type, const std::string& id) : _type(type), _id(id) {} + virtual ~AnimNode() {} const std::string& getID() const { return _id; } Type getType() const { return _type; } @@ -70,7 +71,12 @@ public: AnimSkeleton::ConstPointer getSkeleton() const { return _skeleton; } - virtual ~AnimNode() {} + void setCurrentFrame(float frame) { + setCurrentFrameInternal(frame); + for (auto&& child : _children) { + child->setCurrentFrameInternal(frame); + } + } virtual const std::vector& evaluate(float dt) = 0; virtual const std::vector& overlay(float dt, const std::vector& underPoses) { @@ -79,6 +85,7 @@ public: protected: + virtual void setCurrentFrameInternal(float frame) {} virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { _skeleton = skeleton; }