From a7d8e197840ac564ff1069fe9b747c2a923eac77 Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 8 Aug 2024 13:38:25 -0500 Subject: [PATCH] use pivot dir to determine sprite transform rotation. --- src/app.c | 2 +- src/game.c | 45 +++++++++++++++++++++++++++++++++------------ src/math.h | 23 +++++++++++------------ src/sprite.c | 4 ++-- src/user.c | 2 +- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/app.c b/src/app.c index d55a819d..be4ed93b 100644 --- a/src/app.c +++ b/src/app.c @@ -184,7 +184,7 @@ void app_entry_point(void) "------------\n" "%F\n" "------------\n" - "To stop this error from appearing, either Fix the issue above or delete the file from the system." + "To stop this error from appearing, either fix the issue above or delete the file from the system." ), FMT_STR(settings_path), FMT_STR(error)); diff --git a/src/game.c b/src/game.c index 0f8678c0..f02a6580 100644 --- a/src/game.c +++ b/src/game.c @@ -130,10 +130,10 @@ INTERNAL void spawn_test_entities(void) //entity_enable_prop(e, ENTITY_PROP_TEST); } - /* Child ent 1 */ + /* Child 1 */ { - struct v2 pos = V2(-0.15, -0.05); - struct v2 size = V2(0.25, 0.5); + struct v2 pos = V2(0.15, -0.05); + struct v2 size = V2(1, 1); f32 r = 0; struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size); @@ -141,18 +141,17 @@ INTERNAL void spawn_test_entities(void) struct entity *e = entity_alloc_child(player_ent); entity_set_local_xform(e, xf); - e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase")); - e->sprite_span_name = STR("idle.two_handed"); - e->sprite_tint = RGBA_32_F(0, 0, 0, 1); + e->sprite = sprite_tag_from_path(STR("res/graphics/gun.ase")); + //e->sprite_tint = RGBA_32_F(0, 0, 0, 1); entity_enable_prop(e, ENTITY_PROP_ANIMATING); entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); } - /* Child ent 2 */ + /* Child 2 */ { - struct v2 pos = V2(0.15, -0.05); + struct v2 pos = V2(-0.15, -0.05); struct v2 size = V2(-0.25, 0.5); f32 r = 0; @@ -395,8 +394,15 @@ INTERNAL void game_update(void) struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite); struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame); struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT); - struct v2 pivot_pos = v2_mul_v2(slice.center, sprite_size); - ent->sprite_local_xform = xform_with_scale(XFORM_POS(v2_neg(pivot_pos)), sprite_size); + + struct v2 dir = v2_mul_v2(sprite_size, slice.dir); + f32 rot = v2_angle(dir) + PI / 2; + + struct xform xf = XFORM_IDENT; + xf = xform_rotate(xf, -rot); + xf = xform_scale(xf, sprite_size); + xf = xform_translate(xf, v2_neg(slice.center)); + ent->sprite_local_xform = xf; } @@ -425,7 +431,8 @@ INTERNAL void game_update(void) } /* Calculate player aim pos from camera focus */ - struct v2 player_aim_pos = v2_add(entity_get_xform(active_camera).og, G.world.camera_focus);; + struct v2 player_aim_pos = v2_add(entity_get_xform(active_camera).og, G.world.camera_focus); + (UNUSED)player_aim_pos; for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) { struct entity *ent = &entities_array.entities[entity_index]; @@ -467,7 +474,21 @@ INTERNAL void game_update(void) struct v2 ent_pos = xf.og; struct v2 focus_pos = v2_add(ent_pos, ent->focus); - struct v2 hold_pos = xform_mul_v2(xf, xform_mul_v2(ent->sprite_local_xform, slice.center)); + + struct v2 hold_pos; + { + struct xform hold_pos_xf = xform_translate(ent->sprite_local_xform, slice.center); + hold_pos_xf = xform_mul(xf, hold_pos_xf); + + struct v2 hold_pos_xf_dir = xform_basis_mul_v2(hold_pos_xf, slice.dir); + hold_pos_xf = xform_with_rotation(hold_pos_xf, v2_angle(hold_pos_xf_dir) + PI / 2); + + if (v2_eq(hold_pos_xf.og, ent_pos)) { + /* If hold pos is same as origin (E.G if pivot is being used as hold pos), then move hold pos forward a tad to avoid issue */ + hold_pos_xf = xform_translate(hold_pos_xf, V2(0, -1)); + } + hold_pos = hold_pos_xf.og; + } struct v2 hold_dir = xform_basis_mul_v2(xf, xform_basis_mul_v2(ent->sprite_local_xform, slice.dir)); struct v2 hold_ent_dir = v2_sub(ent_pos, hold_pos); diff --git a/src/math.h b/src/math.h index df543993..70a8e47e 100644 --- a/src/math.h +++ b/src/math.h @@ -435,12 +435,13 @@ INLINE f32 math_cos(f32 x) } /* https://mazzo.li/posts/vectorized-atan2.html */ -INLINE f32 math_atan2(f32 y, f32 x) { - const f32 a1 = 0.99997726f; - const f32 a3 = -0.33262347f; - const f32 a5 = 0.19354346f; - const f32 a7 = -0.11643287f; - const f32 a9 = 0.05265332f; +INLINE f32 math_atan2(f32 y, f32 x) +{ + const f32 a1 = 0.99997726f; + const f32 a3 = -0.33262347f; + const f32 a5 = 0.19354346f; + const f32 a7 = -0.11643287f; + const f32 a9 = 0.05265332f; const f32 a11 = -0.01172120f; /* Ensure input is in [-1, +1] */ @@ -448,14 +449,14 @@ INLINE f32 math_atan2(f32 y, f32 x) { f32 s = (swap ? x : y) / (swap ? y : x); /* Approximate atan */ - f32 s_sq = s*s; + f32 s_sq = s * s; f32 res = s * (a1 + s_sq * (a3 + s_sq * (a5 + s_sq * (a7 + s_sq * (a9 + s_sq * a11))))); res = swap ? (s >= 0.0f ? (PI / 2.f) : -(PI / 2.f)) - res : res; /* Adjust quadrants */ - if (x < 0.0f && y >= 0.0f) { res = PI + res; } /* 2nd quadrant */ - else if (x <= 0.0f && y < 0.0f) { res = -PI + res; } /* 3rd quadrant */ - else if (x == 0.0f && y == 0.0f) { res = 0; } /* NaN -> 0 */ + if (x < 0.0f && y >= 0.0f) { res = PI + res; } /* 2nd quadrant */ + else if (x <= 0.0f && y < 0.0f) { res = -PI + res; } /* 3rd quadrant */ + else if (x == 0.0f && y == 0.0f) { res = 0; } /* NaN -> 0 */ return res; } @@ -837,9 +838,7 @@ INLINE struct xform xform_lerp(struct xform a, struct xform b, f32 t) { struct trs trs_a = trs_from_xform(a); struct trs trs_b = trs_from_xform(b); - struct trs trs = trs_lerp(trs_a, trs_b, t); - return xform_from_trs(trs); } diff --git a/src/sprite.c b/src/sprite.c index 0bb6d829..8ab8abc5 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -539,8 +539,8 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str struct v2 center_px = V2(x1_px + (width_px * 0.5f), y1_px + (height_px * 0.5f)); struct v2 center = V2(x1 + (width * 0.5f), y1 + (height * 0.5f)); /* Dir */ - struct v2 dir_px = V2(center_px.x, 0); - struct v2 dir = V2(0, -0.5); + struct v2 dir_px = V2(center_px.x, -1); + struct v2 dir = V2(0, -1); slice->rect_px = rect_px; slice->center_px = center_px; diff --git a/src/user.c b/src/user.c index f9cd99cd..d4cd1c80 100644 --- a/src/user.c +++ b/src/user.c @@ -772,7 +772,7 @@ INTERNAL void user_update(void) struct xform parent_xf = entity_get_xform(parent); b32 skip_debug_draw = !G.debug_camera && ent == active_camera; - b32 skip_debug_draw_transform = ent == active_camera; + b32 skip_debug_draw_transform = entity_has_prop(ent, ENTITY_PROP_CAMERA); /* Draw sprite */ if (!sprite_tag_is_nil(ent->sprite)) {