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.
This commit is contained in:
Anthony J. Thibault 2015-08-25 09:58:36 -07:00
parent 7a2ca047cb
commit 4bdb00bbc5
3 changed files with 47 additions and 33 deletions

View file

@ -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<AnimPose>& AnimClip::evaluate(float dt) {
_frame = accumulateTime(_frame, dt);
@ -109,6 +77,43 @@ const std::vector<AnimPose>& 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();

View file

@ -45,6 +45,8 @@ public:
virtual const std::vector<AnimPose>& evaluate(float dt) override;
protected:
virtual void setCurrentFrameInternal(float frame) override;
float accumulateTime(float frame, float dt) const;
void copyFromNetworkAnim();

View file

@ -43,6 +43,7 @@ public:
typedef std::shared_ptr<AnimNode> 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<AnimPose>& evaluate(float dt) = 0;
virtual const std::vector<AnimPose>& overlay(float dt, const std::vector<AnimPose>& underPoses) {
@ -79,6 +85,7 @@ public:
protected:
virtual void setCurrentFrameInternal(float frame) {}
virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) {
_skeleton = skeleton;
}