Refactoring Animator.

This commit is contained in:
Attila Uygun 2021-02-18 17:33:30 +01:00
parent 1ae44b6a76
commit 744d4485eb
3 changed files with 76 additions and 133 deletions

View File

@ -31,6 +31,8 @@ void Animator::Play(int animation, bool loop) {
loop_flags_ |= animation; loop_flags_ |= animation;
else else
loop_flags_ &= ~animation; loop_flags_ &= ~animation;
if ((loop_flags_ & kTimer) != 0)
loop_flags_ &= ~kTimer;
} }
void Animator::Pause(int animation) { void Animator::Pause(int animation) {
@ -51,6 +53,7 @@ void Animator::Stop(int animation) {
play_flags_ |= animation; play_flags_ |= animation;
Update(0); Update(0);
Evaluate(0);
play_flags_ &= ~animation; play_flags_ &= ~animation;
loop_flags_ &= ~animation; loop_flags_ &= ~animation;
} }
@ -95,6 +98,7 @@ void Animator::SetTime(int animation, float time, bool force_update) {
unsigned play_flags = play_flags_; unsigned play_flags = play_flags_;
play_flags_ = animation; play_flags_ = animation;
Update(0); Update(0);
Evaluate(0);
play_flags_ = play_flags; play_flags_ = play_flags;
} }
} }
@ -169,166 +173,105 @@ void Animator::SetVisible(bool visible) {
void Animator::Update(float delta_time) { void Animator::Update(float delta_time) {
if (play_flags_ & kMovement) if (play_flags_ & kMovement)
UpdateMovement(delta_time); UpdateAnimTime(delta_time, kMovement, movement_speed_, movement_time_,
movement_cb_);
if (play_flags_ & kRotation) if (play_flags_ & kRotation)
UpdateRotation(delta_time); UpdateAnimTime(delta_time, kRotation, rotation_speed_, rotation_time_,
rotation_cb_);
if (play_flags_ & kBlending) if (play_flags_ & kBlending)
UpdateBlending(delta_time); UpdateAnimTime(delta_time, kBlending, blending_speed_, blending_time_,
blending_cb_);
if (play_flags_ & kFrames) if (play_flags_ & kFrames)
UpdateFrame(delta_time); UpdateAnimTime(delta_time, kFrames, frame_speed_, frame_time_, frame_cb_);
if (play_flags_ & kTimer) if (play_flags_ & kTimer)
UpdateTimer(delta_time); UpdateAnimTime(delta_time, kTimer, timer_speed_, timer_time_, timer_cb_);
} }
void Animator::EvalAnim(float frame_time) { void Animator::Evaluate(float frame_frac_time) {
for (auto& a : elements_) { Vector2f pos = {0, 0};
if (play_flags_ & kMovement) { if (play_flags_ & kMovement) {
float time = movement_time_ + movement_speed_ * frame_time; float time = movement_time_ + movement_speed_ * frame_frac_time;
float interpolated_time = float interpolated_time =
movement_interpolator_ ? movement_interpolator_(time) : time; movement_interpolator_ ? movement_interpolator_(time) : time;
Vector2f pos = base::Lerp({0, 0}, movement_direction_, interpolated_time); pos = base::Lerp({0, 0}, movement_direction_, interpolated_time);
}
float theta = 0;
if (play_flags_ & kRotation) {
float time = rotation_time_ + rotation_speed_ * frame_frac_time;
float interpolated_time =
rotation_interpolator_ ? rotation_interpolator_(time) : time;
theta = base::Lerp(0.0f, rotation_target_, interpolated_time);
}
float blending_itime = 0;
if (play_flags_ & kBlending) {
float time = blending_time_ + blending_speed_ * frame_frac_time;
blending_itime =
blending_interpolator_ ? blending_interpolator_(time) : time;
}
float frame_itime = 0;
if (play_flags_ & kFrames) {
float time = frame_time_ + frame_speed_ * frame_frac_time;
frame_itime = frame_interpolator_ ? frame_interpolator_(time) : time;
}
for (auto& a : elements_) {
if (play_flags_ & kMovement) {
a.animatable->Translate(pos - a.movement_last_pos); a.animatable->Translate(pos - a.movement_last_pos);
a.movement_last_pos = pos; a.movement_last_pos = pos;
} }
if (play_flags_ & kRotation) { if (play_flags_ & kRotation) {
float time = rotation_time_ + rotation_speed_ * frame_time;
float interpolated_time =
rotation_interpolator_ ? rotation_interpolator_(time) : time;
float theta = base::Lerp(0.0f, rotation_target_, interpolated_time);
a.animatable->Rotate(theta - a.rotation_last_theta); a.animatable->Rotate(theta - a.rotation_last_theta);
a.rotation_last_theta = theta; a.rotation_last_theta = theta;
} }
if (play_flags_ & kBlending) { if (play_flags_ & kBlending) {
float time = blending_time_ + blending_speed_ * frame_time; Vector4f blending =
float interpolated_time = base::Lerp(a.blending_start, blending_target_, blending_itime);
blending_interpolator_ ? blending_interpolator_(time) : time; a.animatable->SetColor(blending);
Vector4f r =
base::Lerp(a.blending_start, blending_target_, interpolated_time);
a.animatable->SetColor(r);
} }
if (play_flags_ & kFrames) { if (play_flags_ & kFrames) {
float time = frame_time_ + frame_speed_ * frame_time;
float interpolated_time =
frame_interpolator_ ? frame_interpolator_(time) : time;
int target = a.frame_start_ + frame_count_; int target = a.frame_start_ + frame_count_;
int r = base::Lerp(a.frame_start_, target, interpolated_time); int frame = base::Lerp(a.frame_start_, target, frame_itime);
if (r < target) if (frame < target)
a.animatable->SetFrame(r); a.animatable->SetFrame(frame);
} }
} }
} }
void Animator::UpdateMovement(float delta_time) { void Animator::UpdateAnimTime(float delta_time,
if ((loop_flags_ & kMovement) == 0 && movement_time_ == 1.0f) { int anim,
movement_time_ = 0; float anim_speed,
play_flags_ &= ~kMovement; float& anim_time,
if (movement_cb_) { base::Closure& cb) {
inside_cb_ = kMovement; if ((loop_flags_ & anim) == 0 && anim_time == 1.0f) {
movement_cb_(); anim_time = 0;
play_flags_ &= ~anim;
if (cb) {
inside_cb_ = (Flags)anim;
cb();
inside_cb_ = kNone; inside_cb_ = kNone;
if (has_pending_cb_) { if (has_pending_cb_) {
has_pending_cb_ = false; has_pending_cb_ = false;
movement_cb_ = std::move(pending_cb_); cb = std::move(pending_cb_);
} }
} }
return; return;
} else if ((anim & kFrames) != 0 && (loop_flags_ & kFrames) != 0 &&
anim_time == 1.0f) {
anim_time = 0;
} }
movement_time_ += movement_speed_ * delta_time; anim_time += anim_speed * delta_time;
if (movement_time_ > 1) if (anim_time > 1)
movement_time_ = anim_time = (anim & kFrames) != 0 || (anim & kTimer) != 0 ||
(loop_flags_ & kMovement) == 0 ? 1 : fmod(movement_time_, 1.0f); (loop_flags_ & anim) == 0
} ? 1
: fmod(anim_time, 1.0f);
void Animator::UpdateRotation(float delta_time) {
if ((loop_flags_ & kRotation) == 0 && rotation_time_ == 1.0f) {
rotation_time_ = 0;
play_flags_ &= ~kRotation;
if (rotation_cb_) {
inside_cb_ = kRotation;
rotation_cb_();
inside_cb_ = kNone;
if (has_pending_cb_) {
has_pending_cb_ = false;
rotation_cb_ = std::move(pending_cb_);
}
}
return;
}
rotation_time_ += rotation_speed_ * delta_time;
if (rotation_time_ > 1)
rotation_time_ =
(loop_flags_ & kRotation) == 0 ? 1 : fmod(rotation_time_, 1.0f);
}
void Animator::UpdateBlending(float delta_time) {
if ((loop_flags_ & kBlending) == 0 && blending_time_ == 1.0f) {
blending_time_ = 0;
play_flags_ &= ~kBlending;
if (blending_cb_) {
inside_cb_ = kBlending;
blending_cb_();
inside_cb_ = kNone;
if (has_pending_cb_) {
has_pending_cb_ = false;
blending_cb_ = std::move(pending_cb_);
}
}
return;
}
blending_time_ += blending_speed_ * delta_time;
if (blending_time_ > 1)
blending_time_ =
(loop_flags_ & kBlending) == 0 ? 1 : fmod(blending_time_, 1.0f);
}
void Animator::UpdateFrame(float delta_time) {
if ((loop_flags_ & kFrames) == 0 && frame_time_ == 1.0f) {
frame_time_ = 0;
play_flags_ &= ~kFrames;
if (frame_cb_) {
inside_cb_ = kFrames;
frame_cb_();
inside_cb_ = kNone;
if (has_pending_cb_) {
has_pending_cb_ = false;
frame_cb_ = std::move(pending_cb_);
}
}
return;
} else if ((loop_flags_ & kFrames) != 0 && frame_time_ == 1.0f) {
frame_time_ = 0;
}
frame_time_ += frame_speed_ * delta_time;
if (frame_time_ > 1)
frame_time_ = 1;
}
void Animator::UpdateTimer(float delta_time) {
if (timer_time_ == 1.0f) {
timer_time_ = 0;
play_flags_ &= ~kTimer;
if (timer_cb_) {
inside_cb_ = kTimer;
timer_cb_();
inside_cb_ = kNone;
if (has_pending_cb_) {
has_pending_cb_ = false;
timer_cb_ = std::move(pending_cb_);
}
}
return;
}
timer_time_ += timer_speed_ * delta_time;
if (timer_time_ > 1)
timer_time_ = 1;
} }
} // namespace eng } // namespace eng

View File

@ -69,7 +69,7 @@ class Animator {
void SetVisible(bool visible); void SetVisible(bool visible);
void Update(float delta_time); void Update(float delta_time);
void EvalAnim(float frame_time); void Evaluate(float frame_frac_time);
bool IsPlaying(int animation) const { return play_flags_ & animation; } bool IsPlaying(int animation) const { return play_flags_ & animation; }
@ -120,11 +120,11 @@ class Animator {
base::Closure pending_cb_; base::Closure pending_cb_;
Flags inside_cb_ = kNone; Flags inside_cb_ = kNone;
void UpdateMovement(float delta_time); void UpdateAnimTime(float delta_time,
void UpdateRotation(float delta_time); int anim,
void UpdateBlending(float delta_time); float anim_speed,
void UpdateFrame(float delta_time); float& anim_time,
void UpdateTimer(float delta_time); base::Closure& cb);
}; };
} // namespace eng } // namespace eng

View File

@ -140,7 +140,7 @@ void Engine::Update(float delta_time) {
void Engine::Draw(float frame_frac) { void Engine::Draw(float frame_frac) {
for (auto d : animators_) for (auto d : animators_)
d->EvalAnim(time_step_ * frame_frac); d->Evaluate(time_step_ * frame_frac);
drawables_.sort( drawables_.sort(
[](auto& a, auto& b) { return a->GetZOrder() < b->GetZOrder(); }); [](auto& a, auto& b) { return a->GetZOrder() < b->GetZOrder(); });