This commit is contained in:
jacob 2025-05-22 14:39:36 -05:00
parent e9c7cced16
commit 15d3efe346

View File

@ -406,34 +406,43 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
/* Release existing walls */ /* Gather tile chunks and release existing walls.
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { * NOTE: We sort tile chunks before iterating so that chunk-edge tiles only
struct sim_ent *ent = &world->ents[ent_index]; * need to check for adjacent walls to merge with in one direction */
if (!ent->valid) continue; struct sim_ent **x_sorted_tile_chunks = NULL;
if (sim_ent_has_prop(ent, SEPROP_WALL)) { struct sim_ent **y_sorted_tile_chunks = NULL;
sim_ent_enable_prop(ent, SEPROP_RELEASE);
}
}
/* Sort tile chunks */
/* 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
* know the left & top chunks have already been processed) */
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;
{
/* NOTE: We sort x & y separately because of the possibility for diagonal
* tile chunks to depend on each other.
*
* For example: In a horizontal iteration, if 2 chunks exist diagonally
* with one to the bottom-left and one to the top-right and the top-right
* chunk has no chunk below it, then the processing of the top-right chunk
* will have to iterate an extra row at the bottom to create bottom walls (since
* walls are created at the tops of tiles). When creating a wall at the bottom-left
* tile of the top-right chunk, it needs to know whether any walls exist at
* the left of that tile that it may need to merge with. If it was iterating
* an array sorted with top-bottom priority, then the bottom-left chunk will not
* have been processed yet, meaning no walls will have been generated to merge with. */
x_sorted_tile_chunks = arena_dry_push(scratch.arena, struct sim_ent *);
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];
if (!ent->valid) continue; if (!ent->valid) continue;
if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) { if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) {
/* Append chunk to array */
*arena_push_no_zero(scratch.arena, struct sim_ent *) = ent; *arena_push_no_zero(scratch.arena, struct sim_ent *) = ent;
++sorted_tile_chunks_count; ++sorted_tile_chunks_count;
} else if (sim_ent_has_prop(ent, SEPROP_WALL)) {
sim_ent_enable_prop(ent, SEPROP_RELEASE);
} }
} }
struct sim_ent **y_sorted_tile_chunks = arena_push_array_no_zero(scratch.arena, struct sim_ent *, sorted_tile_chunks_count); 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); 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(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); 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;
@ -443,7 +452,7 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world)
}; };
/* Dicts containing walls that end on edge of tile chunk, keyed by tile end index. /* Dicts containing walls that end on edge of tile chunk, keyed by tile end index.
* Used to expand walls accross tile chunks. */ * Used to merge walls accross tile chunks. */
struct dict horizontal_ends_dict = dict_init(scratch.arena, 1024); struct dict horizontal_ends_dict = dict_init(scratch.arena, 1024);
struct dict vertical_ends_dict = dict_init(scratch.arena, 1024); struct dict vertical_ends_dict = dict_init(scratch.arena, 1024);