mirror of https://github.com/auygun/kaliber.git
Refactoring Animator class.
This commit is contained in:
parent
cda1d750f8
commit
be1d562a07
|
@ -126,10 +126,10 @@ void Animator::SetMovement(Vector2f direction,
|
||||||
a.movement_last_pos = {0, 0};
|
a.movement_last_pos = {0, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animator::SetRotation(float trget,
|
void Animator::SetRotation(float target,
|
||||||
float duration,
|
float duration,
|
||||||
Interpolator interpolator) {
|
Interpolator interpolator) {
|
||||||
rotation_target_ = trget;
|
rotation_target_ = target;
|
||||||
rotation_speed_ = 1.0f / duration;
|
rotation_speed_ = 1.0f / duration;
|
||||||
rotation_interpolator_ = std::move(interpolator);
|
rotation_interpolator_ = std::move(interpolator);
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ void Animator::SetFrames(int count,
|
||||||
frame_count_ = count;
|
frame_count_ = count;
|
||||||
frame_speed_ = (float)frames_per_second / (float)count;
|
frame_speed_ = (float)frames_per_second / (float)count;
|
||||||
for (auto& a : elements_)
|
for (auto& a : elements_)
|
||||||
a.frame_start_ = a.animatable->GetFrame();
|
a.frame_start = a.animatable->GetFrame();
|
||||||
frame_interpolator_ = std::move(interpolator);
|
frame_interpolator_ = std::move(interpolator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,66 +180,43 @@ void Animator::Update(float delta_time) {
|
||||||
UpdateAnimTime(delta_time, kFrames, frame_speed_, frame_time_, frame_cb_);
|
UpdateAnimTime(delta_time, kFrames, frame_speed_, frame_time_, frame_cb_);
|
||||||
if (play_flags_ & kTimer)
|
if (play_flags_ & kTimer)
|
||||||
UpdateAnimTime(delta_time, kTimer, timer_speed_, timer_time_, timer_cb_);
|
UpdateAnimTime(delta_time, kTimer, timer_speed_, timer_time_, timer_cb_);
|
||||||
|
|
||||||
did_evaluate_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animator::Evaluate(float frame_frac_time) {
|
void Animator::Evaluate(float frame_frac) {
|
||||||
did_evaluate_ = true;
|
if (play_flags_ & kMovement)
|
||||||
|
EvaluateAnimation<Vector2f, true>(
|
||||||
|
frame_frac, movement_speed_, movement_time_, movement_interpolator_,
|
||||||
|
movement_direction_, [](Element& a, Vector2f pos) {
|
||||||
|
a.animatable->Translate(pos - a.movement_last_pos);
|
||||||
|
a.movement_last_pos = pos;
|
||||||
|
});
|
||||||
|
|
||||||
Vector2f pos = {0, 0};
|
if (play_flags_ & kRotation)
|
||||||
if (play_flags_ & kMovement) {
|
EvaluateAnimation<float, true>(
|
||||||
float time = movement_time_ + movement_speed_ * frame_frac_time;
|
frame_frac, rotation_speed_, rotation_time_, rotation_interpolator_,
|
||||||
float interpolated_time =
|
rotation_target_, [](Element& a, float theta) {
|
||||||
movement_interpolator_ ? movement_interpolator_(time) : time;
|
a.animatable->Rotate(theta - a.rotation_last_theta);
|
||||||
pos = base::Lerp({0, 0}, movement_direction_, interpolated_time);
|
a.rotation_last_theta = theta;
|
||||||
}
|
});
|
||||||
|
|
||||||
float theta = 0;
|
if (play_flags_ & kBlending)
|
||||||
if (play_flags_ & kRotation) {
|
EvaluateAnimation<float, false>(
|
||||||
float time = rotation_time_ + rotation_speed_ * frame_frac_time;
|
frame_frac, blending_speed_, blending_time_, blending_interpolator_, {},
|
||||||
float interpolated_time =
|
[&](Element& a, float interpolated_time) {
|
||||||
rotation_interpolator_ ? rotation_interpolator_(time) : time;
|
Vector4f blending =
|
||||||
theta = base::Lerp(0.0f, rotation_target_, interpolated_time);
|
base::Lerp(a.blending_start, blending_target_, interpolated_time);
|
||||||
}
|
a.animatable->SetColor(blending);
|
||||||
|
});
|
||||||
|
|
||||||
float blending_itime = 0;
|
if (play_flags_ & kFrames)
|
||||||
if (play_flags_ & kBlending) {
|
EvaluateAnimation<float, false>(
|
||||||
float time = blending_time_ + blending_speed_ * frame_frac_time;
|
frame_frac, frame_speed_, frame_time_, frame_interpolator_, {},
|
||||||
blending_itime =
|
[&](Element& a, float interpolated_time) {
|
||||||
blending_interpolator_ ? blending_interpolator_(time) : time;
|
int target = a.frame_start + frame_count_;
|
||||||
}
|
int frame = base::Lerp(a.frame_start, target, interpolated_time);
|
||||||
|
if (frame < target)
|
||||||
float frame_itime = 0;
|
a.animatable->SetFrame(frame);
|
||||||
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.movement_last_pos = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (play_flags_ & kRotation) {
|
|
||||||
a.animatable->Rotate(theta - a.rotation_last_theta);
|
|
||||||
a.rotation_last_theta = theta;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (play_flags_ & kBlending) {
|
|
||||||
Vector4f blending =
|
|
||||||
base::Lerp(a.blending_start, blending_target_, blending_itime);
|
|
||||||
a.animatable->SetColor(blending);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (play_flags_ & kFrames) {
|
|
||||||
int target = a.frame_start_ + frame_count_;
|
|
||||||
int frame = base::Lerp(a.frame_start_, target, frame_itime);
|
|
||||||
if (frame < target)
|
|
||||||
a.animatable->SetFrame(frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animator::UpdateAnimTime(float delta_time,
|
void Animator::UpdateAnimTime(float delta_time,
|
||||||
|
@ -252,8 +229,8 @@ void Animator::UpdateAnimTime(float delta_time,
|
||||||
if (loop_flags_ & anim) {
|
if (loop_flags_ & anim) {
|
||||||
anim_time = fmod(anim_time, 1.0f);
|
anim_time = fmod(anim_time, 1.0f);
|
||||||
} else {
|
} else {
|
||||||
if (!did_evaluate_)
|
anim_time = 1.0f;
|
||||||
Evaluate(0);
|
Evaluate(0);
|
||||||
anim_time = 0;
|
anim_time = 0;
|
||||||
play_flags_ &= ~anim;
|
play_flags_ &= ~anim;
|
||||||
if (cb) {
|
if (cb) {
|
||||||
|
@ -269,4 +246,24 @@ void Animator::UpdateAnimTime(float delta_time,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, bool relative>
|
||||||
|
void Animator::EvaluateAnimation(float frame_frac,
|
||||||
|
float anim_speed,
|
||||||
|
float anim_time,
|
||||||
|
Interpolator& interpolator,
|
||||||
|
T target,
|
||||||
|
ResultSetter<T> set_result) {
|
||||||
|
float time = anim_time + anim_speed * frame_frac;
|
||||||
|
float interpolated_time = interpolator ? interpolator(time) : time;
|
||||||
|
|
||||||
|
if constexpr (relative) {
|
||||||
|
T result = base::Lerp(T{0}, target, interpolated_time);
|
||||||
|
for (auto& a : elements_)
|
||||||
|
set_result(a, result);
|
||||||
|
} else {
|
||||||
|
for (auto& a : elements_)
|
||||||
|
set_result(a, interpolated_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Animator {
|
||||||
float GetTime(int animation);
|
float GetTime(int animation);
|
||||||
void SetTime(int animation, float time, bool force_update = false);
|
void SetTime(int animation, float time, bool force_update = false);
|
||||||
|
|
||||||
// Set callback ro be called once animation ends.
|
// Set callback to be called once animation ends.
|
||||||
void SetEndCallback(int animation, base::Closure cb);
|
void SetEndCallback(int animation, base::Closure cb);
|
||||||
|
|
||||||
// Distance is the magnitude of direction vector. Duration is in seconds.
|
// Distance is the magnitude of direction vector. Duration is in seconds.
|
||||||
|
@ -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 Evaluate(float frame_frac_time);
|
void Evaluate(float frame_frac);
|
||||||
|
|
||||||
bool IsPlaying(int animation) const { return play_flags_ & animation; }
|
bool IsPlaying(int animation) const { return play_flags_ & animation; }
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ class Animator {
|
||||||
base::Vector2f movement_last_pos = {0, 0};
|
base::Vector2f movement_last_pos = {0, 0};
|
||||||
float rotation_last_theta = 0;
|
float rotation_last_theta = 0;
|
||||||
base::Vector4f blending_start = {0, 0, 0, 0};
|
base::Vector4f blending_start = {0, 0, 0, 0};
|
||||||
int frame_start_ = 0;
|
int frame_start = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int play_flags_ = 0;
|
unsigned int play_flags_ = 0;
|
||||||
|
@ -120,13 +120,22 @@ class Animator {
|
||||||
base::Closure pending_cb_;
|
base::Closure pending_cb_;
|
||||||
Flags inside_cb_ = kNone;
|
Flags inside_cb_ = kNone;
|
||||||
|
|
||||||
bool did_evaluate_ = false;
|
|
||||||
|
|
||||||
void UpdateAnimTime(float delta_time,
|
void UpdateAnimTime(float delta_time,
|
||||||
int anim,
|
int anim,
|
||||||
float anim_speed,
|
float anim_speed,
|
||||||
float& anim_time,
|
float& anim_time,
|
||||||
base::Closure& cb);
|
base::Closure& cb);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using ResultSetter = std::function<void(Element&, T)>;
|
||||||
|
|
||||||
|
template <typename T, bool relative>
|
||||||
|
void EvaluateAnimation(float frame_frac,
|
||||||
|
float anim_speed,
|
||||||
|
float anim_time,
|
||||||
|
Interpolator& interpolator,
|
||||||
|
T target,
|
||||||
|
ResultSetter<T> set_result);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
Loading…
Reference in New Issue