From: Randy McShandy Date: Sun, 28 Apr 2024 16:11:49 +0000 (-0500) Subject: More proper grid size management X-Git-Url: http://git.mcshandy.xyz/gitweb.cgi?a=commitdiff_plain;h=15f7cca499bf4f86de615852c40b9b5ce021b960;p=barrow_crawler More proper grid size management --- diff --git a/main.c b/main.c index 7397f42..9af3a99 100755 --- a/main.c +++ b/main.c @@ -1,22 +1,19 @@ #include +#include #include "structs.h" int main(int argc, char** argv) { - RD_Opts barrow_circ = - { - .max_iterations = 1e4, - .diff_a = 0.8f, - .diff_b = 0.3f, - .feed = 0.058f, - .kill = 0.066f, - .delta_t = 0.6f, - .name = "puffer", - .shape = eCircle - }; + IVec2 grid_size = {.x = GRID_X * 1.5, .y = GRID_Y * 1.5}; + FVec2 **grid = NULL; + grid = (FVec2**)malloc(grid_size.x * sizeof(FVec2*)); + for (int n = 0; n < grid_size.x; n++) + { + grid[n] = (FVec2*)malloc(grid_size.y * sizeof(FVec2)); + } - generate_rd(8, barrow); + generate_rd(8, barrow, grid, grid_size); return 0; } diff --git a/structs.c b/structs.c index 3cc769c..0997ca3 100644 --- a/structs.c +++ b/structs.c @@ -19,14 +19,14 @@ RD_Opts puffer = // diff values influence tightness, delta between them shouldn't get wider than ~0.5 or narrower than ~0.4 RD_Opts barrow = { - .max_iterations = 1e4, + .max_iterations = 1e4 * 1.0f, .diff_a = 0.8f, .diff_b = 0.3f, .feed = 0.055f, .kill = 0.062f, .delta_t = 0.6f, - .name = "puffer", + .name = "barrow", .shape = eBarrow }; diff --git a/structs.h b/structs.h index 0673129..a239fd0 100644 --- a/structs.h +++ b/structs.h @@ -26,6 +26,12 @@ typedef struct float c; } FVec2; +typedef struct +{ + int x; + int y; +} IVec2; + typedef struct { int max_iterations; @@ -62,6 +68,6 @@ extern RD_Opts worms; extern RD_Opts meiosis; extern const Mat3 laplacian_kernel; -int generate_rd(int worker_count, RD_Opts opts); +int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 pgrid_size); #endif //__RD_STRUCTS__ diff --git a/utils.c b/utils.c index c58bda4..c898a4b 100644 --- a/utils.c +++ b/utils.c @@ -2,6 +2,7 @@ #include #include #include + #include "structs.h" #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" @@ -22,6 +23,7 @@ pthread_barrier_t barrier; FVec2 ** grid; FVec2 ** grid_prime; FVec2 ** grid_temp; +IVec2 grid_size; float kernel_sum(Mat3 kernel, Mat3 source) { float result = 0.0f; @@ -41,8 +43,8 @@ float rd_a_prime(FVec2 **source_grid, RD_Opts opts, int x, int y, Mat3 kernel, float a_prime = 1.0f; int x_less = (x - 1 < 0) ? x : x - 1; int y_less = (y - 1 < 0) ? y : y - 1; - int x_more = (x + 1 == GRID_X) ? x : x + 1; - int y_more = (y + 1 == GRID_Y) ? y : y + 1; + int x_more = (x + 1 == grid_size.x) ? x : x + 1; + int y_more = (y + 1 == grid_size.y) ? y : y + 1; // Use species A in the convolution, b_prime will need B // For now we won't iterate over edge rows and columns to avoid special case @@ -65,8 +67,8 @@ float rd_b_prime(FVec2** source_grid, RD_Opts opts, int x, int y, Mat3 kernel, f float b_prime = 1.0f; int x_less = (x-1 < 0) ? x : x-1; int y_less = (y-1 < 0) ? y : y-1; - int x_more = (x+1 == GRID_X) ? x : x+1; - int y_more = (y+1 == GRID_Y) ? y : y+1; + int x_more = (x+1 == grid_size.x) ? x : x+1; + int y_more = (y+1 == grid_size.y) ? y : y+1; // Use species A in the convolution, b_prime will need B Mat3 source = @@ -95,13 +97,16 @@ void* iterator(void* _arg) for (warg->iterations = 0; warg->iterations < warg->max_iterations; warg->iterations++) { printf("worker %d: work unit %d/%d\n", warg->worker_id, warg->iterations, warg->max_iterations); - for (int x = start_x; x < w + start_x && x < GRID_X; x++) + for (int x = start_x; x < w + start_x && x < grid_size.x; x++) { - for (int y = start_y; y < h + start_y && y < GRID_Y; y++) + for (int y = start_y; y < h + start_y && y < grid_size.y; y++) { FVec2 each = grid[x][y]; if (each.c >= 0.5f) + { each.b = 1.0f; + each.c -= 5.0f/((float)(opts.max_iterations/100.0f)); + } grid_prime[x][y].a = rd_a_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b); grid_prime[x][y].b = rd_b_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b); } @@ -115,20 +120,6 @@ void* iterator(void* _arg) grid_prime = grid_temp; waiting_workers = 0; printf("worker-boss %d: completing report\n", warg->worker_id); - if ((warg->iterations % 100 == 0)) - { - char buffer[GRID_X][GRID_Y]; - for (int x = 0; x < GRID_X; x++) - { - for (int y = 0; y < GRID_Y; y++) - { - buffer[x][y] = (uint8_t)(255.0f * grid[x][y].a); - } - } - char name[64] = {0}; - sprintf(name, "img/%s/%d.png", opts.name, warg->iterations); - stbi_write_png(name, GRID_X, GRID_Y, 1, buffer, GRID_X * sizeof(uint8_t)); - } } pthread_mutex_unlock(&mutex); pthread_barrier_wait(&barrier); @@ -145,26 +136,20 @@ void* iterator(void* _arg) int initialize(int worker_count, RD_Opts active_opt) { - grid = (FVec2**)malloc(GRID_X * sizeof(FVec2*)); - for (int n = 0; n < GRID_X; n++) - { - grid[n] = (FVec2*)malloc(GRID_Y * sizeof(FVec2)); - } - - grid_prime = (FVec2**)malloc(GRID_X * sizeof(FVec2*)); - for (int n = 0; n < GRID_X; n++) + grid_prime = (FVec2**)malloc(grid_size.x * sizeof(FVec2*)); + for (int n = 0; n < grid_size.x; n++) { - grid_prime[n] = (FVec2*)malloc(GRID_Y * sizeof(FVec2)); + grid_prime[n] = (FVec2*)malloc(grid_size.y * sizeof(FVec2)); } srand(time(NULL)); - float radius = GRID_X/2.1f; - int center_x = GRID_X/2; - int center_y = GRID_Y/2; - for (int x = 0; x < GRID_X; x++) + float radius = grid_size.x/2.1f; + int center_x = grid_size.x/2; + int center_y = grid_size.y/2; + for (int x = 0; x < grid_size.x; x++) { - for (int y = 0; y < GRID_Y; y++) + for (int y = 0; y < grid_size.y; y++) { grid[x][y].a = 1.0f; grid[x][y].b = 0.0f; @@ -200,19 +185,29 @@ int initialize(int worker_count, RD_Opts active_opt) // Slap in an entrance or something here // or add support for post-processing + if (abs(x-center_x) < 3 && (y <= (5 * (grid_size.y/8)))) + { + grid[x][y].c = 1.0f; + } + + if (abs(y-center_y) < 8 && (x <= (6 * (grid_size.x/8))) && (x >= (2 * (grid_size.x/8)))) + { + grid[x][y].c = 1.0f; + } } break; } } } - const int seed_count = sqrt(GRID_X) * 1; - const int width = 4 * (GRID_X/128); + /* Big seeds good for rooms */ + const int seed_count = sqrt(grid_size.x) * 2; + const int width = 12 * (grid_size.x/128); const int height = width * 1; for (int n = 0; n < seed_count; n++) { - int rand_x = rand() % GRID_X; - int rand_y = rand() % GRID_Y; + int rand_x = rand() % grid_size.x; + int rand_y = rand() % grid_size.y; grid[rand_x][rand_y].b = 1.0f; grid[rand_x][rand_y].c = 0.0f; @@ -220,7 +215,7 @@ int initialize(int worker_count, RD_Opts active_opt) { for (int y = rand_y-(height/2); y < rand_y+(height/2); y++) { - if (y >= GRID_Y || x >= GRID_X || y < 0 || x < 0) + if (y >= grid_size.y || x >= grid_size.x || y < 0 || x < 0) continue; // Third parameter for permanent presence of B chemicals (black) grid[x][y].c = 1.0f; @@ -230,7 +225,7 @@ int initialize(int worker_count, RD_Opts active_opt) warg = (worker_arg){ active_opt, grid, grid_prime, - 0, 0, (GRID_X), (GRID_Y), + 0, 0, (grid_size.x), (grid_size.y), .worker_count = worker_count, .max_iterations = active_opt.max_iterations }; @@ -245,7 +240,7 @@ int initialize(int worker_count, RD_Opts active_opt) { wargs[t] = warg; wargs[t].worker_id = t; - wargs[t].width = (GRID_X/worker_count) + ((t == worker_count-1) ? 0 : 4); + wargs[t].width = (grid_size.x/worker_count) + ((t == worker_count-1) ? 0 : 4); wargs[t].start_x = (wargs[t].width * t); printf("worker %d x_span %d, %d\n", t, wargs[t].start_x, wargs[t].width); pthread_create(&threads[t], NULL, iterator, &wargs[t]); @@ -268,14 +263,29 @@ int cleanup() return 0; } -int generate_rd(int worker_count, RD_Opts active_opt) +int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 pgrid_size) { + grid = grid_buffer; + grid_size = pgrid_size; + initialize(worker_count, active_opt); while(!should_quit) {} printf("Opts: {\nIterations: %d\nTime delta: %f\nDiffA: %f\nDiffB: %f\nFeed: %f\nKill: %f\n\n}\n", active_opt.max_iterations, active_opt.delta_t, active_opt.diff_a, active_opt.diff_b, active_opt.feed, active_opt.kill); + char buffer[pgrid_size.x][pgrid_size.y]; + for (int x = 0; x < pgrid_size.x; x++) + { + for (int y = 0; y < pgrid_size.y; y++) + { + buffer[x][y] = (uint8_t)(255.0f * grid_buffer[x][y].a); + } + } + char name[64] = {0}; + sprintf(name, "./%s.png", active_opt.name); + stbi_write_png(name, pgrid_size.x, pgrid_size.y, 1, buffer, pgrid_size.x * sizeof(uint8_t)); + cleanup(); return 0; }