From 91d7812f8a6d4ea1e685cb94075dbd958706d46d Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 1 Aug 2024 13:10:37 -0500 Subject: [PATCH] rename rel_xform -> exform. world_xform -> xform_world. sprite_quad_xform -> sprite_xform_world. add rel sprite_xform field. --- src/entity.c | 6 ++-- src/entity.h | 8 +++-- src/game.c | 88 +++++++++++++++++++++++++++++----------------------- src/user.c | 35 +++++++++++---------- 4 files changed, 75 insertions(+), 62 deletions(-) diff --git a/src/entity.c b/src/entity.c index 9206e86b..613af4b4 100644 --- a/src/entity.c +++ b/src/entity.c @@ -3,9 +3,9 @@ /* Accessed via entity_nil() */ READONLY struct entity _g_entity_nil = { - .rel_xform = XFORM_IDENT_NOCAST, - .world_xform = XFORM_IDENT_NOCAST, - .sprite_quad_xform = XFORM_IDENT_NOCAST, + .xform = XFORM_IDENT_NOCAST, + .xform_world = XFORM_IDENT_NOCAST, + .sprite_xform = XFORM_IDENT_NOCAST, .sprite_tint = COLOR_WHITE }; diff --git a/src/entity.h b/src/entity.h index 15cbb7c6..84e2b1f8 100644 --- a/src/entity.h +++ b/src/entity.h @@ -48,8 +48,8 @@ struct entity { /* ====================================================================== */ - 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 */ + struct xform xform; /* Transform in relation to parent entity (or the world if entity has no parent) */ + struct xform xform_world; /* Calculated from entity tree */ /* ====================================================================== */ /* Physics */ @@ -67,9 +67,11 @@ struct entity { struct sprite_tag sprite; struct string sprite_span_name; - struct xform sprite_quad_xform; u32 sprite_tint; + struct xform sprite_xform; /* Sprite transform in relation to xform_world */ + struct xform sprite_xform_world; /* Calculated from world xform */ + /* ====================================================================== */ /* Animation */ diff --git a/src/game.c b/src/game.c index 7420663c..5a526536 100644 --- a/src/game.c +++ b/src/game.c @@ -108,17 +108,17 @@ INTERNAL void publish_game_tick(void) sys_mutex_unlock(&lock); } -INTERNAL void recalculate_world_xforms_recurse(struct entity *parent, struct sprite_scope *sprite_scope) +INTERNAL void recalculate_world_xforms_recurse(struct entity *parent) { struct temp_arena scratch = scratch_begin_no_conflict(); struct stack_node { struct entity *entity; - struct xform parent_xform; + struct xform parent_xform_world; }; /* Depth first iteration */ - *arena_push(scratch.arena, struct stack_node) = (struct stack_node) { .entity = parent, .parent_xform = XFORM_IDENT }; + *arena_push(scratch.arena, struct stack_node) = (struct stack_node) { .entity = parent, .parent_xform_world = XFORM_IDENT }; u64 stack_count = 1; while (stack_count > 0) { /* Pull from top of stack */ @@ -129,23 +129,17 @@ INTERNAL void recalculate_world_xforms_recurse(struct entity *parent, struct spr struct entity *child = node.entity; /* Calculate world xform */ - struct xform world_xform = xform_mul(node.parent_xform, child->rel_xform); - child->world_xform = world_xform; + struct xform xform_world = xform_mul(node.parent_xform_world, child->xform); + child->xform_world = xform_world; /* Calculate sprite xform */ - if (!sprite_tag_is_nil(child->sprite)) { - struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_scope, child->sprite); - struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT); - struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), child->animation_frame); - struct v2 pivot_pos = v2_mul_v2(slice.center_norm, sprite_size); - child->sprite_quad_xform = xform_with_scale(XFORM_POS(v2_neg(pivot_pos)), sprite_size); - child->sprite_quad_xform = xform_mul(child->world_xform, child->sprite_quad_xform); - } + struct xform sprite_xform_world = xform_mul(xform_world, child->sprite_xform); + child->sprite_xform_world = sprite_xform_world; /* Append sub-children to stack */ struct entity *subchild = entity_from_handle(&G.world.entity_store, child->last); while (subchild->valid) { - *arena_push(scratch.arena, struct stack_node) = (struct stack_node) { .entity = subchild, .parent_xform = world_xform }; + *arena_push(scratch.arena, struct stack_node) = (struct stack_node) { .entity = subchild, .parent_xform_world = xform_world }; ++stack_count; subchild = entity_from_handle(&G.world.entity_store, subchild->prev); } @@ -181,7 +175,7 @@ INTERNAL void game_update(void) struct entity *e = entity_alloc(&G.world.entity_store); e->valid = true; - e->rel_xform = XFORM_TRS(.t = pos, .r = r, .s = size); + e->xform = XFORM_TRS(.t = pos, .r = r, .s = size); e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase")); e->sprite_span_name = STR("idle.unarmed"); @@ -203,7 +197,7 @@ INTERNAL void game_update(void) { struct entity *e = entity_alloc(&G.world.entity_store); e->valid = true; - e->rel_xform = XFORM_IDENT; + e->xform = XFORM_IDENT; entity_enable_prop(e, ENTITY_PROP_CAMERA); entity_enable_prop(e, ENTITY_PROP_CAMERA_ACTIVE); @@ -277,8 +271,8 @@ INTERNAL void game_update(void) /* ENTITY_PROP_TEST */ if (entity_has_prop(ent, ENTITY_PROP_TEST) && !ent->test_initialized) { ent->test_initialized = true; - ent->test_start_rel_xform = ent->rel_xform; - ent->test_start_sprite_xform = ent->sprite_quad_xform; + ent->test_start_rel_xform = ent->xform; + ent->test_start_sprite_xform = ent->sprite_xform; } /* ========================== * @@ -309,20 +303,17 @@ INTERNAL void game_update(void) ent->animation_frame = span_frame_offset; } -#if 0 /* ========================== * - * Calculate sprite xform + * Update sprite xform * ========================== */ if (!sprite_tag_is_nil(ent->sprite)) { struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite); - struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT); 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_norm, sprite_size); - ent->sprite_quad_xform = xform_with_scale(XFORM_POS(v2_neg(pivot_pos)), sprite_size); - ent->sprite_quad_xform = xform_mul(ent->world_xform, ent->sprite_quad_xform); + ent->sprite_xform = xform_with_scale(XFORM_POS(v2_neg(pivot_pos)), sprite_size); } -#endif /* ========================== * * Test @@ -343,9 +334,9 @@ INTERNAL void game_update(void) s = v2_add(s, xform_get_scale(ent->test_start_rel_xform)); - ent->rel_xform.og = og; - ent->rel_xform = xform_with_rotation(ent->rel_xform, r); - ent->rel_xform = xform_with_scale(ent->rel_xform, s); + ent->xform.og = og; + ent->xform = xform_with_rotation(ent->xform, r); + ent->xform = xform_with_scale(ent->xform, s); } /* ========================== * @@ -353,14 +344,33 @@ INTERNAL void game_update(void) * ========================== */ if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { +#if 0 /* Update focus */ ent->focus = G.world.player_aim; /* Update view angle */ - struct v2 ent_pos = ent->rel_xform.og; + struct v2 ent_pos = ent->xform.og; + struct v2 look_pos = v2_add(ent_pos, ent->focus); + + float r; + { + struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_scope, ent->sprite); + struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("hold"), ent->animation_frame); + + struct v2 dir = slice.dir_norm; + } + + ent->xform = xform_with_rotation(ent->xform, r); +#else + /* Update focus */ + ent->focus = G.world.player_aim; + + /* Update view angle */ + struct v2 ent_pos = ent->xform.og; struct v2 look_pos = v2_add(ent_pos, ent->focus); f32 r = v2_angle_to_point(ent_pos, look_pos) + PI / 2; - ent->rel_xform = xform_with_rotation(ent->rel_xform, r); + ent->xform = xform_with_rotation(ent->xform, r); +#endif } } @@ -368,7 +378,7 @@ INTERNAL void game_update(void) for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) { struct entity *ent = &entities_array.entities[entity_index]; if (ent->valid && !ent->parent.gen) { - recalculate_world_xforms_recurse(ent, sprite_frame_scope); + recalculate_world_xforms_recurse(ent); } } @@ -405,7 +415,7 @@ INTERNAL void game_update(void) ent->velocity = v2_add(ent->velocity, a); /* Apply velocity to position */ - ent->rel_xform.og = v2_add(ent->rel_xform.og, v2_mul(ent->velocity, dt)); + ent->xform.og = v2_add(ent->xform.og, v2_mul(ent->velocity, dt)); } } @@ -413,7 +423,7 @@ INTERNAL void game_update(void) for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) { struct entity *ent = &entities_array.entities[entity_index]; if (ent->valid && !ent->parent.gen) { - recalculate_world_xforms_recurse(ent, sprite_frame_scope); + recalculate_world_xforms_recurse(ent); } } @@ -436,7 +446,7 @@ INTERNAL void game_update(void) if (entity_has_prop(follow, ENTITY_PROP_PLAYER_CONTROLLED)) { f32 aspect_ratio = 1.0; { - struct xform quad_xf = xform_mul(ent->world_xform, ent->camera_quad_xform); + struct xform quad_xf = xform_mul(ent->xform_world, ent->camera_quad_xform); struct v2 camera_size = xform_get_scale(quad_xf); if (!v2_eq(camera_size, V2(0, 0))) { aspect_ratio = camera_size.x / camera_size.y; @@ -445,18 +455,18 @@ INTERNAL void game_update(void) f32 ratio_y = 0.33f; f32 ratio_x = ratio_y / aspect_ratio; struct v2 camera_focus_dir = v2_mul_v2(follow->focus, V2(ratio_x, ratio_y)); - struct v2 camera_focus_pos = v2_add(follow->world_xform.og, camera_focus_dir); - ent->camera_rel_xform_target = ent->rel_xform; + struct v2 camera_focus_pos = v2_add(follow->xform_world.og, camera_focus_dir); + ent->camera_rel_xform_target = ent->xform; ent->camera_rel_xform_target.og = camera_focus_pos; } /* Lerp camera */ if (ent->camera_applied_lerp_continuity_gen_plus_one == ent->camera_lerp_continuity_gen + 1) { f32 t = 1 - math_pow(2.f, -20.f * (f32)G.world.dt); - ent->rel_xform = xform_lerp(ent->rel_xform, ent->camera_rel_xform_target, t); + ent->xform = xform_lerp(ent->xform, ent->camera_rel_xform_target, t); } else { /* Skip lerp */ - ent->rel_xform = ent->camera_rel_xform_target; + ent->xform = ent->camera_rel_xform_target; } ent->camera_applied_lerp_continuity_gen_plus_one = ent->camera_lerp_continuity_gen + 1; } @@ -469,7 +479,7 @@ INTERNAL void game_update(void) struct mixer_desc desc = ent->sound_desc; desc.speed = G.world.timescale; - desc.pos = ent->world_xform.og; + desc.pos = ent->xform_world.og; struct sound *sound = sound_load_async(ent->sound_name, 0); b32 played = ent->sound_handle.gen != 0; if (sound) { @@ -486,7 +496,7 @@ INTERNAL void game_update(void) for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) { struct entity *ent = &entities_array.entities[entity_index]; if (ent->valid && !ent->parent.gen) { - recalculate_world_xforms_recurse(ent, sprite_frame_scope); + recalculate_world_xforms_recurse(ent); } } diff --git a/src/user.c b/src/user.c index 838d1612..e631a7a0 100644 --- a/src/user.c +++ b/src/user.c @@ -375,7 +375,7 @@ INTERNAL void debug_draw_movement(struct entity *ent) u32 color_vel = RGBA_32_F(1, 0.5, 0, 1); u32 color_acc = RGBA_32_F(1, 1, 0.5, 1); - struct v2 pos = xform_mul_v2(G.world_view, ent->world_xform.og); + struct v2 pos = xform_mul_v2(G.world_view, ent->xform_world.og); struct v2 vel_ray = xform_basis_mul_v2(G.world_view, ent->velocity); struct v2 acc_ray = xform_basis_mul_v2(G.world_view, ent->acceleration); @@ -447,15 +447,16 @@ INTERNAL void user_update(void) struct entity *e1 = &t1_entities.entities[i]; struct entity *e = &world_entities.entities[i]; if (e0->handle.gen == e1->handle.gen && e0->continuity_gen == e1->continuity_gen) { - e->rel_xform = xform_lerp(e0->rel_xform, e1->rel_xform, tick_blend); - e->world_xform = xform_lerp(e0->world_xform, e1->world_xform, tick_blend); + e->xform = xform_lerp(e0->xform, e1->xform, tick_blend); + e->xform_world = xform_lerp(e0->xform_world, e1->xform_world, tick_blend); e->acceleration = v2_lerp(e0->acceleration, e1->acceleration, tick_blend); e->velocity = v2_lerp(e0->velocity, e1->velocity, tick_blend); e->player_acceleration = math_lerp(e0->player_acceleration, e1->player_acceleration, tick_blend); e->focus = v2_lerp(e0->focus, e1->focus, tick_blend); - e->sprite_quad_xform = xform_lerp(e0->sprite_quad_xform, e1->sprite_quad_xform, tick_blend); + e->sprite_xform = xform_lerp(e0->sprite_xform, e1->sprite_xform, tick_blend); + e->sprite_xform_world = xform_lerp(e0->sprite_xform_world, e1->sprite_xform_world, tick_blend); e->animation_time_in_frame = math_lerp64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend); e->animation_frame = (u32)math_round_to_int(math_lerp(e0->animation_frame, e1->animation_frame, tick_blend)); @@ -597,7 +598,7 @@ INTERNAL void user_update(void) /* Determine viewport size by camera & window dimensions */ f32 aspect_ratio = 1.0; { - struct xform quad_xf = xform_mul(active_camera->world_xform, active_camera->camera_quad_xform); + struct xform quad_xf = xform_mul(active_camera->xform_world, active_camera->camera_quad_xform); struct v2 camera_size = xform_get_scale(quad_xf); if (!v2_eq(camera_size, V2(0, 0))) { aspect_ratio = camera_size.x / camera_size.y; @@ -655,13 +656,13 @@ INTERNAL void user_update(void) G.world_view = xform_translate(G.world_view, v2_neg(world_cursor)); } } else { - struct v2 center = active_camera->world_xform.og; - f32 rot = xform_get_rotation(active_camera->world_xform); + struct v2 center = active_camera->xform_world.og; + f32 rot = xform_get_rotation(active_camera->xform_world); /* Scale view into viewport based on camera size */ struct v2 size = G.viewport_size; { - struct xform quad_xf = xform_mul(active_camera->world_xform, active_camera->camera_quad_xform); + struct xform quad_xf = xform_mul(active_camera->xform_world, active_camera->camera_quad_xform); struct v2 camera_size = xform_get_scale(quad_xf); if (!v2_eq(camera_size, V2(0, 0))) { size = v2_div_v2(size, camera_size); @@ -769,7 +770,7 @@ INTERNAL void user_update(void) /* TODO: Fade in placeholder if texture isn't loaded */ if (sheet->loaded) { struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, ent->animation_frame); - struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, ent->sprite_quad_xform); + struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, ent->sprite_xform_world); struct draw_sprite_params params = DRAW_SPRITE_PARAMS(.sprite = sprite, .tint = ent->sprite_tint, .clip = frame.clip); draw_sprite_quad(G.world_canvas, params, quad); } @@ -782,7 +783,7 @@ INTERNAL void user_update(void) #if 0 struct font *disp_font = font_load_async(STR("res/fonts/fixedsys.ttf"), 12.0f); if (disp_font) { - struct xform xf = ent->world_xform; + struct xform xf = ent->xform_world; struct trs trs = trs_from_xform(xf); struct v2 velocity = ent->velocity; struct v2 acceleration = ent->acceleration; @@ -819,7 +820,7 @@ INTERNAL void user_update(void) debug_draw_movement(ent); if (!skip_debug_draw_transform) { - debug_draw_xform(ent->world_xform); + debug_draw_xform(ent->xform_world); } /* Draw slices */ @@ -833,7 +834,7 @@ INTERNAL void user_update(void) for (u32 j = 0; j < group->per_frame_count; ++j) { struct sprite_sheet_slice slice = group->frame_slices[(ent->animation_frame * group->per_frame_count) + j]; struct quad quad = quad_from_rect(slice.rect_norm); - quad = quad_mul_xform(quad, ent->sprite_quad_xform); + quad = quad_mul_xform(quad, ent->sprite_xform_world); draw_solid_quad_line(G.viewport_canvas, quad_mul_xform(quad, G.world_view), 3, COLOR_RED); } } @@ -846,8 +847,8 @@ INTERNAL void user_update(void) f32 thickness = 5; f32 arrow_height = 15; - struct v2 start = xform_mul_v2(G.world_view, ent->world_xform.og); - struct v2 end = xform_mul_v2(G.world_view, parent->world_xform.og); + struct v2 start = xform_mul_v2(G.world_view, ent->xform_world.og); + struct v2 end = xform_mul_v2(G.world_view, parent->xform_world.og); draw_solid_arrow_line(G.viewport_canvas, start, end, thickness, arrow_height, color); } @@ -856,7 +857,7 @@ INTERNAL void user_update(void) u32 color = RGBA_32_F(0.75, 0, 0.75, 0.5); f32 thickness = 3; f32 arrow_height = 10; - struct v2 pos = xform_mul_v2(G.world_view, ent->world_xform.og); + struct v2 pos = xform_mul_v2(G.world_view, ent->xform_world.og); struct v2 aim_ray = xform_basis_mul_v2(G.world_view, ent->focus); draw_solid_arrow_ray(G.viewport_canvas, pos, aim_ray, thickness, arrow_height, color); } @@ -867,7 +868,7 @@ INTERNAL void user_update(void) f32 thickness = 3; - struct xform quad_xf = xform_mul(ent->world_xform, ent->camera_quad_xform); + struct xform quad_xf = xform_mul(ent->xform_world, ent->camera_quad_xform); struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, quad_xf); quad = quad_mul_xform(quad, G.world_view); @@ -950,7 +951,7 @@ INTERNAL void user_update(void) /* Queue aim cmd */ if (!G.debug_camera) { - struct v2 input_aim = v2_sub(G.world_cursor, player->world_xform.og); + struct v2 input_aim = v2_sub(G.world_cursor, player->xform_world.og); queue_game_cmd(&cmd_list, (struct game_cmd) { .kind = GAME_CMD_KIND_PLAYER_AIM, .aim = input_aim,