diff --git a/src/game.c b/src/game.c index e9cbde77..7420663c 100644 --- a/src/game.c +++ b/src/game.c @@ -108,7 +108,7 @@ INTERNAL void publish_game_tick(void) sys_mutex_unlock(&lock); } -INTERNAL void recalculate_world_xform_recurse(struct entity *parent) +INTERNAL void recalculate_world_xforms_recurse(struct entity *parent, struct sprite_scope *sprite_scope) { struct temp_arena scratch = scratch_begin_no_conflict(); @@ -126,11 +126,22 @@ INTERNAL void recalculate_world_xform_recurse(struct entity *parent) arena_pop(scratch.arena, struct stack_node, &node); --stack_count; - /* Calculate child world xform */ 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; + /* 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); + } + /* Append sub-children to stack */ struct entity *subchild = entity_from_handle(&G.world.entity_store, child->last); while (subchild->valid) { @@ -298,6 +309,7 @@ INTERNAL void game_update(void) ent->animation_frame = span_frame_offset; } +#if 0 /* ========================== * * Calculate sprite xform * ========================== */ @@ -308,7 +320,9 @@ INTERNAL void game_update(void) struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame); 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); } +#endif /* ========================== * * Test @@ -339,7 +353,6 @@ INTERNAL void game_update(void) * ========================== */ if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { -#if 1 /* Update focus */ ent->focus = G.world.player_aim; @@ -348,16 +361,14 @@ INTERNAL void game_update(void) 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); -#else - /* Update focus */ - ent->focus = G.world.player_aim; + } + } - /* Update view angle */ - struct v2 ent_pos = ent->rel_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); -#endif + /* Recalculate xforms */ + 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); } } @@ -368,7 +379,6 @@ 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) continue; - if (ent->parent.gen) continue; /* Only update parent entities */ /* ========================== * * Player movement @@ -397,12 +407,14 @@ INTERNAL void game_update(void) /* Apply velocity to position */ ent->rel_xform.og = v2_add(ent->rel_xform.og, v2_mul(ent->velocity, dt)); } + } - /* ========================== * - * Calculate xforms - * ========================== */ - - recalculate_world_xform_recurse(ent); + /* Recalculate xforms */ + 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); + } } /* ========================== * @@ -447,9 +459,6 @@ INTERNAL void game_update(void) ent->rel_xform = ent->camera_rel_xform_target; } ent->camera_applied_lerp_continuity_gen_plus_one = ent->camera_lerp_continuity_gen + 1; - - /* Recalculate xform tree */ - recalculate_world_xform_recurse(ent); } /* ========================== * @@ -473,6 +482,14 @@ INTERNAL void game_update(void) } } + /* Recalculate xforms */ + 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); + } + } + /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ diff --git a/src/user.c b/src/user.c index 02fa3a87..838d1612 100644 --- a/src/user.c +++ b/src/user.c @@ -769,7 +769,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, xform_mul(ent->world_xform, ent->sprite_quad_xform)); + struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, ent->sprite_quad_xform); 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); } @@ -833,7 +833,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, xform_mul(ent->world_xform, ent->sprite_quad_xform)); + quad = quad_mul_xform(quad, ent->sprite_quad_xform); draw_solid_quad_line(G.viewport_canvas, quad_mul_xform(quad, G.world_view), 3, COLOR_RED); } }