2023-05-22 20:31:55 +02:00
|
|
|
#region global
|
2023-07-06 19:49:16 +02:00
|
|
|
enum ANIMATOR_END {
|
|
|
|
loop,
|
2024-07-29 06:58:47 +02:00
|
|
|
stop,
|
|
|
|
pingpong,
|
2023-07-06 19:49:16 +02:00
|
|
|
}
|
2023-07-25 20:12:40 +02:00
|
|
|
|
|
|
|
#macro ANIMATION_STATIC !(PROJECT.animator.is_playing || PROJECT.animator.frame_progress)
|
2023-10-31 13:33:36 +01:00
|
|
|
#macro IS_PLAYING PROJECT.animator.is_playing
|
2024-01-19 09:33:37 +01:00
|
|
|
#macro IS_RENDERING PROJECT.animator.is_rendering
|
2023-10-09 16:07:33 +02:00
|
|
|
#macro CURRENT_FRAME PROJECT.animator.current_frame
|
2024-01-19 09:33:37 +01:00
|
|
|
|
2023-10-09 16:07:33 +02:00
|
|
|
#macro TOTAL_FRAMES PROJECT.animator.frames_total
|
2024-01-18 14:13:20 +01:00
|
|
|
#macro FRAME_RANGE PROJECT.animator.frame_range
|
2024-01-19 09:33:37 +01:00
|
|
|
|
|
|
|
#macro FIRST_FRAME PROJECT.animator.getFirstFrame()
|
|
|
|
#macro LAST_FRAME PROJECT.animator.getLastFrame()
|
|
|
|
|
|
|
|
#macro IS_FIRST_FRAME PROJECT.animator.isFirstFrame()
|
|
|
|
#macro IS_LAST_FRAME PROJECT.animator.isLastFrame()
|
2023-05-22 20:31:55 +02:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region animation class
|
2022-12-10 05:06:01 +01:00
|
|
|
function AnimationManager() constructor {
|
2023-03-07 14:29:47 +01:00
|
|
|
frames_total = 30;
|
|
|
|
current_frame = 0;
|
|
|
|
real_frame = 0;
|
2023-01-01 02:06:02 +01:00
|
|
|
time_since_last_frame = 0;
|
2024-01-18 14:13:20 +01:00
|
|
|
|
2023-03-07 14:29:47 +01:00
|
|
|
framerate = 30;
|
|
|
|
is_playing = false;
|
2024-01-19 09:33:37 +01:00
|
|
|
is_rendering = false;
|
2023-03-07 14:29:47 +01:00
|
|
|
frame_progress = false;
|
2024-01-18 14:13:20 +01:00
|
|
|
frame_range = noone;
|
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
play_direction = 1;
|
2024-01-19 09:33:37 +01:00
|
|
|
is_simulating = false;
|
|
|
|
|
2023-11-26 13:16:38 +01:00
|
|
|
__debug_animator_counter = 0;
|
|
|
|
|
2023-11-03 14:43:28 +01:00
|
|
|
playback = ANIMATOR_END.loop;
|
2022-12-10 05:06:01 +01:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static setFrame = function(_frame, _round = true) {
|
2023-11-08 13:05:24 +01:00
|
|
|
var _c = current_frame;
|
2024-07-29 06:58:47 +02:00
|
|
|
_frame = clamp(_frame, 0, frames_total);
|
|
|
|
real_frame = _frame;
|
|
|
|
current_frame = _round? round(_frame) : _frame;
|
2022-12-12 09:08:03 +01:00
|
|
|
|
2024-01-19 09:33:37 +01:00
|
|
|
frame_progress = _c != current_frame;
|
2023-02-14 02:51:14 +01:00
|
|
|
|
2024-01-19 09:33:37 +01:00
|
|
|
if(frame_progress) {
|
|
|
|
time_since_last_frame = 0;
|
2023-10-02 10:45:30 +02:00
|
|
|
RENDER_ALL
|
2024-01-19 09:33:37 +01:00
|
|
|
}
|
2024-07-29 06:58:47 +02:00
|
|
|
}
|
2023-04-10 20:02:59 +02:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static getFirstFrame = function(range = true) { return range && frame_range != noone? frame_range[0] - 1 : 0; }
|
|
|
|
static getLastFrame = function(range = true) { return range && frame_range != noone? frame_range[1] - 1 : frames_total - 1; }
|
2024-01-19 09:33:37 +01:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static firstFrame = function(range = true) { setFrame(getFirstFrame(range)); }
|
|
|
|
static lastFrame = function(range = true) { setFrame(getLastFrame(range)); }
|
2024-01-19 09:33:37 +01:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static isFirstFrame = function() { return current_frame == getFirstFrame(); }
|
|
|
|
static isLastFrame = function() { return current_frame == getLastFrame(); }
|
2024-01-19 09:33:37 +01:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static resetAnimation = function() {
|
2024-06-08 13:31:27 +02:00
|
|
|
array_foreach(PROJECT.allNodes, function(node) { node.resetAnimation(); });
|
2024-07-29 06:58:47 +02:00
|
|
|
}
|
2023-05-16 21:28:16 +02:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static toggle = function() {
|
2024-01-19 09:33:37 +01:00
|
|
|
is_playing = !is_playing;
|
|
|
|
frame_progress = true;
|
2023-07-25 20:12:40 +02:00
|
|
|
time_since_last_frame = 0;
|
2024-07-29 06:58:47 +02:00
|
|
|
}
|
2023-06-04 12:38:40 +02:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static pause = function() {
|
2024-01-19 09:33:37 +01:00
|
|
|
is_playing = false;
|
|
|
|
frame_progress = true;
|
2023-07-25 20:12:40 +02:00
|
|
|
time_since_last_frame = 0;
|
2024-07-29 06:58:47 +02:00
|
|
|
}
|
2023-05-16 21:28:16 +02:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static play = function() {
|
2024-01-19 09:33:37 +01:00
|
|
|
if(is_simulating) setFrame(0);
|
|
|
|
else firstFrame();
|
|
|
|
|
|
|
|
is_playing = true;
|
|
|
|
frame_progress = true;
|
|
|
|
time_since_last_frame = 0;
|
2024-07-29 06:58:47 +02:00
|
|
|
play_direction = 1;
|
|
|
|
}
|
2024-01-19 09:33:37 +01:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static render = function() {
|
2024-01-19 09:33:37 +01:00
|
|
|
if(is_simulating) setFrame(0);
|
|
|
|
else firstFrame();
|
|
|
|
|
|
|
|
is_playing = true;
|
|
|
|
is_rendering = true;
|
|
|
|
frame_progress = true;
|
2023-07-25 20:12:40 +02:00
|
|
|
time_since_last_frame = 0;
|
2024-07-29 06:58:47 +02:00
|
|
|
}
|
2023-05-22 20:31:55 +02:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static resume = function() {
|
2024-01-19 09:33:37 +01:00
|
|
|
is_playing = true;
|
|
|
|
frame_progress = true;
|
2023-07-25 20:12:40 +02:00
|
|
|
time_since_last_frame = 0;
|
2024-07-29 06:58:47 +02:00
|
|
|
}
|
2023-05-16 21:28:16 +02:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static stop = function() {
|
2024-01-19 09:33:37 +01:00
|
|
|
firstFrame();
|
|
|
|
|
|
|
|
is_playing = false;
|
2023-07-25 20:12:40 +02:00
|
|
|
time_since_last_frame = 0;
|
2024-07-29 06:58:47 +02:00
|
|
|
}
|
2023-07-25 20:12:40 +02:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
static step = function() {
|
2024-01-19 09:33:37 +01:00
|
|
|
if(frame_range != noone) {
|
|
|
|
var _fr0 = min(frame_range[0], frame_range[1]);
|
|
|
|
var _fr1 = max(frame_range[0], frame_range[1]);
|
|
|
|
|
|
|
|
if(_fr0 == _fr1) {
|
|
|
|
frame_range = noone;
|
|
|
|
} else {
|
|
|
|
frame_range[0] = max(_fr0, 0);
|
|
|
|
frame_range[1] = min(_fr1, frames_total);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-26 13:16:38 +01:00
|
|
|
if(!is_playing) return;
|
|
|
|
|
|
|
|
var _frTime = 1 / framerate;
|
|
|
|
time_since_last_frame += delta_time / 1_000_000;
|
2024-02-12 13:59:43 +01:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
if(time_since_last_frame < _frTime) return;
|
|
|
|
|
|
|
|
var dt = time_since_last_frame - _frTime;
|
|
|
|
setFrame(real_frame + play_direction);
|
|
|
|
time_since_last_frame = dt;
|
|
|
|
|
|
|
|
var _maxFrame = frame_range != noone? frame_range[1] : frames_total;
|
|
|
|
|
|
|
|
if(current_frame >= _maxFrame) {
|
|
|
|
firstFrame();
|
2024-01-19 09:33:37 +01:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
if(playback == ANIMATOR_END.stop || is_rendering) {
|
|
|
|
is_playing = false;
|
|
|
|
is_rendering = false;
|
|
|
|
time_since_last_frame = 0;
|
2023-11-26 13:16:38 +01:00
|
|
|
|
2024-07-29 06:58:47 +02:00
|
|
|
} else if(playback == ANIMATOR_END.pingpong) {
|
|
|
|
setFrame(max(0, frames_total - 2));
|
|
|
|
play_direction = -1;
|
2024-01-19 09:33:37 +01:00
|
|
|
}
|
2024-07-29 06:58:47 +02:00
|
|
|
|
|
|
|
} else if(current_frame <= 0) {
|
|
|
|
if(playback == ANIMATOR_END.pingpong)
|
|
|
|
play_direction = 1;
|
2024-01-19 09:33:37 +01:00
|
|
|
}
|
2024-07-29 06:58:47 +02:00
|
|
|
}
|
2022-12-10 05:06:01 +01:00
|
|
|
}
|
|
|
|
#endregion
|