mirror of https://github.com/auygun/kaliber.git
133 lines
3.3 KiB
C++
133 lines
3.3 KiB
C++
#ifndef ANIMATOR_H
|
|
#define ANIMATOR_H
|
|
|
|
#include <vector>
|
|
|
|
#include "../base/closure.h"
|
|
#include "../base/vecmath.h"
|
|
|
|
namespace eng {
|
|
|
|
class Animatable;
|
|
|
|
class Animator {
|
|
public:
|
|
// Animation type flags.
|
|
enum Flags {
|
|
kNone = 0,
|
|
kMovement = 1,
|
|
kRotation = 2,
|
|
kBlending = 4,
|
|
kFrames = 8,
|
|
kTimer = 16,
|
|
kAllAnimations = kMovement | kRotation | kBlending | kFrames
|
|
};
|
|
|
|
using Interpolator = std::function<float(float)>;
|
|
|
|
Animator();
|
|
~Animator();
|
|
|
|
void Attach(Animatable* animatable);
|
|
|
|
void Play(int animation, bool loop);
|
|
void Pause(int animation);
|
|
void Stop(int animation);
|
|
|
|
void PauseOrResumeAll(bool pause);
|
|
|
|
// Get/set current time of the given animation.
|
|
float GetTime(int animation);
|
|
void SetTime(int animation, float time, bool force_update = false);
|
|
|
|
// Set callback ro be called once animation ends.
|
|
void SetEndCallback(int animation, base::Closure cb);
|
|
|
|
// Distance is the magnitude of direction vector. Duration is in seconds.
|
|
void SetMovement(base::Vector2f direction,
|
|
float duration,
|
|
Interpolator interpolator = nullptr);
|
|
|
|
// Rotation is in radian. Duration is in seconds.
|
|
void SetRotation(float target,
|
|
float duration,
|
|
Interpolator interpolator = nullptr);
|
|
|
|
void SetBlending(base::Vector4f target,
|
|
float duration,
|
|
Interpolator interpolator = nullptr);
|
|
|
|
// Plays count number of frames.
|
|
void SetFrames(int count,
|
|
int frames_per_second,
|
|
Interpolator interpolator = nullptr);
|
|
|
|
// Triggers a callback after the given seconds passed.
|
|
void SetTimer(float duration);
|
|
|
|
// Set visibility of all attached animatables.
|
|
void SetVisible(bool visible);
|
|
|
|
void Update(float delta_time);
|
|
void Evaluate(float frame_frac_time);
|
|
|
|
bool IsPlaying(int animation) const { return play_flags_ & animation; }
|
|
|
|
private:
|
|
struct Element {
|
|
Animatable* animatable;
|
|
base::Vector2f movement_last_pos = {0, 0};
|
|
float rotation_last_theta = 0;
|
|
base::Vector4f blending_start = {0, 0, 0, 0};
|
|
int frame_start_ = 0;
|
|
};
|
|
|
|
unsigned int play_flags_ = 0;
|
|
unsigned int loop_flags_ = 0;
|
|
unsigned int resume_flags_ = 0;
|
|
std::vector<Element> elements_;
|
|
|
|
base::Vector2f movement_direction_ = {0, 0};
|
|
float movement_speed_ = 0;
|
|
float movement_time_ = 0;
|
|
Interpolator movement_interpolator_;
|
|
base::Closure movement_cb_;
|
|
|
|
float rotation_target_ = 0;
|
|
float rotation_speed_ = 0;
|
|
float rotation_time_ = 0;
|
|
Interpolator rotation_interpolator_;
|
|
base::Closure rotation_cb_;
|
|
|
|
base::Vector4f blending_target_ = {0, 0, 0, 0};
|
|
float blending_speed_ = 0;
|
|
float blending_time_ = 0;
|
|
Interpolator blending_interpolator_;
|
|
base::Closure blending_cb_;
|
|
|
|
int frame_count_ = 0;
|
|
float frame_speed_ = 0;
|
|
float frame_time_ = 0;
|
|
Interpolator frame_interpolator_;
|
|
base::Closure frame_cb_;
|
|
|
|
float timer_speed_ = 0;
|
|
float timer_time_ = 0;
|
|
base::Closure timer_cb_;
|
|
|
|
// State used to set new callback during a callback.
|
|
bool has_pending_cb_ = false;
|
|
base::Closure pending_cb_;
|
|
Flags inside_cb_ = kNone;
|
|
|
|
void UpdateAnimTime(float delta_time,
|
|
int anim,
|
|
float anim_speed,
|
|
float& anim_time,
|
|
base::Closure& cb);
|
|
};
|
|
|
|
} // namespace eng
|
|
|
|
#endif // ANIMATOR_H
|