sort tile chunks by x & y separately to fix bug

This commit is contained in:
jacob 2025-05-21 23:01:40 -05:00
parent d9f841dad6
commit 92bb82cdb4
2 changed files with 155 additions and 141 deletions

View File

@ -374,16 +374,29 @@ INTERNAL void test_spawn_tile(struct sim_snapshot *world, struct v2 world_pos)
INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort, arg_a, arg_b, udata) INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort_x, arg_a, arg_b, udata)
{ {
(UNUSED)udata; (UNUSED)udata;
struct sim_ent *a = *(struct sim_ent **)arg_a; struct sim_ent *a = *(struct sim_ent **)arg_a;
struct sim_ent *b = *(struct sim_ent **)arg_b; struct sim_ent *b = *(struct sim_ent **)arg_b;
struct v2i32 index_a = a->tile_chunk_index; i32 a_x = a->tile_chunk_index.x;
struct v2i32 index_b = b->tile_chunk_index; i32 b_x = b->tile_chunk_index.x;
i32 res = 0; i32 res = 0;
res = 2 * ((index_a.y < index_b.y) - (index_a.y > index_b.y)) + ((index_a.x < index_b.x) - (index_a.x > index_b.x)); res = (a_x < b_x) - (a_x > b_x);
return res;
}
INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort_y, arg_a, arg_b, udata)
{
(UNUSED)udata;
struct sim_ent *a = *(struct sim_ent **)arg_a;
struct sim_ent *b = *(struct sim_ent **)arg_b;
i32 a_y = a->tile_chunk_index.y;
i32 b_y = b->tile_chunk_index.y;
i32 res = 0;
res = (a_y < b_y) - (a_y > b_y);
return res; return res;
} }
@ -403,10 +416,10 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
} }
/* Sort tile chunks */ /* Sort tile chunks */
/* NOTE: We sort tile chunks from top-left to bottom-right so that cross /* NOTE: We sort tile chunks from left-right and top-bottom so that cross
* chunk tile checks only have to happen in one direction (because we * chunk tile checks only have to happen in one direction (because we
* know the left & top chunks have already been processed) */ * know the left & top chunks have already been processed) */
struct sim_ent **sorted_tile_chunks = arena_dry_push(scratch.arena, struct sim_ent *); struct sim_ent **x_sorted_tile_chunks = arena_dry_push(scratch.arena, struct sim_ent *);
u64 sorted_tile_chunks_count = 0; u64 sorted_tile_chunks_count = 0;
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
struct sim_ent *ent = &world->ents[ent_index]; struct sim_ent *ent = &world->ents[ent_index];
@ -416,7 +429,11 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
++sorted_tile_chunks_count; ++sorted_tile_chunks_count;
} }
} }
merge_sort(sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*sorted_tile_chunks), tile_chunk_sort, NULL); struct sim_ent **y_sorted_tile_chunks = arena_push_array_no_zero(scratch.arena, struct sim_ent *, sorted_tile_chunks_count);
MEMCPY(y_sorted_tile_chunks, x_sorted_tile_chunks, sizeof(*x_sorted_tile_chunks) * sorted_tile_chunks_count);
merge_sort(x_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*x_sorted_tile_chunks), tile_chunk_sort_x, NULL);
merge_sort(y_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*y_sorted_tile_chunks), tile_chunk_sort_y, NULL);
struct wall_node { struct wall_node {
struct v2i32 start; struct v2i32 start;
@ -433,10 +450,8 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
/* Generate horizontal wall nodes */ /* Generate horizontal wall nodes */
for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) { for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) {
struct sim_ent *chunk = sorted_tile_chunks[sorted_index]; struct sim_ent *chunk = x_sorted_tile_chunks[sorted_index];
struct v2i32 chunk_index = chunk->tile_chunk_index; struct v2i32 chunk_index = chunk->tile_chunk_index;
/* Generate horizontal wall nodes */
{
struct sim_ent *top_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y - 1)); struct sim_ent *top_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y - 1));
struct sim_ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y + 1)); struct sim_ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y + 1));
/* If there's no chunk below this one, then do an extra iteration (since walls are created at the top of each tile) */ /* If there's no chunk below this one, then do an extra iteration (since walls are created at the top of each tile) */
@ -507,8 +522,11 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
} }
} }
} }
/* Generate vertical wall nodes */ /* Generate vertical wall nodes */
{ for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) {
struct sim_ent *chunk = y_sorted_tile_chunks[sorted_index];
struct v2i32 chunk_index = chunk->tile_chunk_index;
struct sim_ent *left_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x - 1, chunk_index.y)); struct sim_ent *left_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x - 1, chunk_index.y));
struct sim_ent *right_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x + 1, chunk_index.y)); struct sim_ent *right_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x + 1, chunk_index.y));
/* If there's no chunk to the right of this one, then do an extra iteration (since walls are created on the left of each tile) */ /* If there's no chunk to the right of this one, then do an extra iteration (since walls are created on the left of each tile) */
@ -580,7 +598,6 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
} }
} }
} }
}
/* Create wall entities */ /* Create wall entities */
for (struct wall_node *node = first_wall; node; node = node->next) { for (struct wall_node *node = first_wall; node; node = node->next) {

View File

@ -1861,9 +1861,6 @@ INTERNAL void user_update(void)
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Video memory usage: %F MiB"), FMT_FLOAT((f64)gstat_get(GSTAT_VRAM_USAGE) / 1024 / 1024))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Video memory usage: %F MiB"), FMT_FLOAT((f64)gstat_get(GSTAT_VRAM_USAGE) / 1024 / 1024)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Video memory budget: %F GiB"), FMT_FLOAT((f64)gstat_get(GSTAT_VRAM_BUDGET) / 1024 / 1024 / 1024)));
pos.y += spacing;
pos.y += spacing; pos.y += spacing;
#if 0 #if 0