From 452e922e236e6b50e393534777fea0332cc6f15e Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 11 Mar 2024 13:21:31 -0500 Subject: [PATCH] rework animation logic, don't loop increasingly as time goes on --- src/entity.c | 21 --------------------- src/entity.h | 30 +++++++++++++++++++++++------- src/game.c | 52 ++++++++++++++++++++++------------------------------ src/user.c | 19 ++++++++----------- src/world.h | 6 ++---- 5 files changed, 55 insertions(+), 73 deletions(-) diff --git a/src/entity.c b/src/entity.c index cc79bc30..2e6d5bf2 100644 --- a/src/entity.c +++ b/src/entity.c @@ -1,24 +1,3 @@ #include "entity.h" READONLY struct entity _g_entity_nil = { 0 }; - -void entity_enable_prop(struct entity *entity, enum entity_prop prop) -{ - u64 index = prop / 64; - u64 bit = prop % 64; - entity->props[index] |= ((u64)1 << bit); -} - -void entity_disable_prop(struct entity *entity, enum entity_prop prop) -{ - u64 index = prop / 64; - u64 bit = prop % 64; - entity->props[index] &= ~((u64)1 << bit); -} - -b32 entity_has_prop(struct entity *entity, enum entity_prop prop) -{ - u64 index = prop / 64; - u64 bit = prop % 64; - return !!(entity->props[index] & ((u64)1 << bit)); -} diff --git a/src/entity.h b/src/entity.h index c5990d32..426914b6 100644 --- a/src/entity.h +++ b/src/entity.h @@ -41,9 +41,8 @@ struct entity { struct entity_handle last; /* ====================================================================== */ - /* Translation, rotation, scale in relation to parent entity */ - struct xform rel_xform; + struct xform rel_xform; /* Transform in relation to parent entity (or the world if entity has no parent) */ struct xform world_xform; /* Calculated post-physics */ /* ====================================================================== */ @@ -68,8 +67,8 @@ struct entity { /* Animation */ /* ENTITY_PROP_ANIMATING */ - b32 animation_looping; - f64 animation_start_time; /* Calculated */ + f64 animation_time_in_frame; + u64 animation_frame; /* ====================================================================== */ /* Testing */ @@ -95,8 +94,25 @@ struct entity { extern READONLY struct entity _g_entity_nil; INLINE READONLY struct entity *entity_nil(void) { return &_g_entity_nil; } -void entity_enable_prop(struct entity *entity, enum entity_prop prop); -void entity_disable_prop(struct entity *entity, enum entity_prop prop); -b32 entity_has_prop(struct entity *entity, enum entity_prop prop); +INLINE void entity_enable_prop(struct entity *entity, enum entity_prop prop) +{ + u64 index = prop / 64; + u64 bit = prop % 64; + entity->props[index] |= ((u64)1 << bit); +} + +INLINE void entity_disable_prop(struct entity *entity, enum entity_prop prop) +{ + u64 index = prop / 64; + u64 bit = prop % 64; + entity->props[index] &= ~((u64)1 << bit); +} + +INLINE b32 entity_has_prop(struct entity *entity, enum entity_prop prop) +{ + u64 index = prop / 64; + u64 bit = prop % 64; + return !!(entity->props[index] & ((u64)1 << bit)); +} #endif diff --git a/src/game.c b/src/game.c index ad7a9512..c549c73d 100644 --- a/src/game.c +++ b/src/game.c @@ -135,7 +135,6 @@ INTERNAL void game_update(void) e->player_acceleration = 15.0f; entity_enable_prop(e, ENTITY_PROP_ANIMATING); - e->animation_looping = true; player_ent = e; @@ -144,8 +143,9 @@ INTERNAL void game_update(void) } /* Child ent */ - { - struct v2 pos = V2(0, 0.25); + for (u64 i = 0; i < 100; ++i) { + //struct v2 pos = V2(0, 0.001); + struct v2 pos = V2(0, 0.25 * (i + 1)); struct v2 size = V2(1, 1); f32 r = 0; @@ -185,7 +185,6 @@ INTERNAL void game_update(void) //e->player_acceleration = 15.0f; entity_enable_prop(e, ENTITY_PROP_ANIMATING); - e->animation_looping = true; //entity_enable_prop(e, ENTITY_PROP_TEST); //entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE); @@ -271,41 +270,34 @@ INTERNAL void game_update(void) ent->test_start_sprite_xform = ent->sprite_xform; } - /* ENTITY_PROP_ANIMATING */ - if (entity_has_prop(ent, ENTITY_PROP_ANIMATING) && ent->animation_start_time == 0) { - ent->animation_start_time = L.world.time; - } - /* ========================== * * Update animation * ========================== */ - if (ent->animation_start_time > 0) { - /* Stop animation if past duration and not looping */ - if (!ent->animation_looping) { - f64 time_in_anim = L.world.time - ent->animation_start_time; + if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) { + f64 time_in_frame = ent->animation_time_in_frame + L.world.dt; + u64 tag_frame_offset = ent->animation_frame; - struct sheet *sheet = sheet_load(ent->sprite_name); - if (sheet) { - struct sheet_tag tag = sheet_get_tag(sheet, ent->sprite_tag_name); + struct sheet *sheet = sheet_load(ent->sprite_name); + if (sheet) { + struct sheet_tag tag = sheet_get_tag(sheet, ent->sprite_tag_name); + u64 frame_index = tag.start + tag_frame_offset; - struct sheet_frame frame = { 0 }; - u64 frame_index = tag.start; - while (time_in_anim > 0) { - frame = sheet_get_frame(sheet, frame_index); - if (frame_index > tag.end) { - entity_disable_prop(ent, ENTITY_PROP_ANIMATING); - ent->animation_start_time = 0; - break; - } - time_in_anim -= frame.duration; - ++frame_index; + struct sheet_frame frame = sheet_get_frame(sheet, frame_index); + while (time_in_frame > frame.duration) { + time_in_frame -= frame.duration; + ++frame_index; + if (frame_index > tag.end) { + /* Loop animation */ + frame_index = tag.start; } - } else { - entity_disable_prop(ent, ENTITY_PROP_ANIMATING); - ent->animation_start_time = 0; + frame = sheet_get_frame(sheet, frame_index); } + tag_frame_offset = frame_index - tag.start; } + + ent->animation_time_in_frame = time_in_frame; + ent->animation_frame = tag_frame_offset; } /* ========================== * diff --git a/src/user.c b/src/user.c index 1a158f7c..9cf8c5f9 100644 --- a/src/user.c +++ b/src/user.c @@ -528,6 +528,7 @@ INTERNAL void user_update(void) e->player_acceleration = math_lerp_f32(e0->player_acceleration, e1->player_acceleration, tick_blend); e->sprite_xform = xform_lerp(e0->sprite_xform, e1->sprite_xform, tick_blend); + e->animation_time_in_frame = math_lerp_f64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend); e->camera_zoom = math_lerp_f32(e0->camera_zoom, e1->camera_zoom, tick_blend); } @@ -629,22 +630,18 @@ INTERNAL void user_update(void) if (sheet) { struct sheet_tag tag = sheet_get_tag(sheet, ent->sprite_tag_name); - struct sheet_frame frame = sheet_get_frame(sheet, tag.start); + u64 frame_index = tag.start + ent->animation_frame; + struct sheet_frame frame = sheet_get_frame(sheet, frame_index); if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) { - b32 looping = ent->animation_looping; - f64 time_in_anim = L.world.time - ent->animation_start_time; - - u64 frame_index = tag.start; - while (time_in_anim > 0) { - frame = sheet_get_frame(sheet, frame_index); - time_in_anim -= frame.duration; + f64 time_in_frame = ent->animation_time_in_frame; + while (time_in_frame > frame.duration) { + time_in_frame -= frame.duration; ++frame_index; if (frame_index > tag.end) { + /* Loop animation */ frame_index = tag.start; - if (!looping) { - break; - } } + frame = sheet_get_frame(sheet, frame_index); } } diff --git a/src/world.h b/src/world.h index 5256a215..2494a6df 100644 --- a/src/world.h +++ b/src/world.h @@ -16,13 +16,11 @@ struct world { u64 entities_count; /* Includes 'released' & inactive entities */ struct entity_handle first_free_entity; - /* ====================================================================== */ - /* Everything after this field is not automatically coppied - * in world_copy_replace */ + /* Everything after this field is not dumb-MEMCPY'd by world_copy_replace */ u8 _copy_barrier; - /* Arenas */ + /* Entities array */ struct arena entities_arena; struct entity *entities; };