From b6b3483a3987f0d56cad070804a54015573f1015 Mon Sep 17 00:00:00 2001 From: onezplpl Date: Wed, 17 Jul 2024 19:54:19 -0400 Subject: [PATCH] yet another API cleanup --- control.c | 6 ++--- control.h | 9 ++++--- cubes.c | 37 +++++++++++--------------- cubes.h | 4 +-- gen.c | 79 +++++-------------------------------------------------- gen.h | 8 +++--- main.c | 18 ++++++------- noise.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ noise.h | 12 +++++++++ 9 files changed, 134 insertions(+), 114 deletions(-) create mode 100644 noise.c create mode 100644 noise.h diff --git a/control.c b/control.c index 14e0e79..b130a44 100644 --- a/control.c +++ b/control.c @@ -32,7 +32,7 @@ int collision(struct chunk chunk, vec3 pos, vec3 dir_temp, int col, int n) { return 0; } -struct v3f controlHandler(double cx, double cy, vec3 pos, vec3 dir_temp, +struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp, GLFWwindow *window, struct chunk chunk) { vec3 direction = {cosf(cy) * sinf(cx) * 0.1, sinf(cy) * 0.1, cosf(cy) * cosf(cx) * 0.1}; @@ -70,7 +70,7 @@ struct v3f controlHandler(double cx, double cy, vec3 pos, vec3 dir_temp, int col = 0; for (int a = -2; a < 0; a++) { off[1] = a; - col = col || cube_exists(pos[0] + off[0], pos[1] + off[1], pos[2] + off[2], + col = col || gen_cube(pos[0] + off[0], pos[1] + off[1], pos[2] + off[2], chunk, 0); } @@ -80,7 +80,7 @@ struct v3f controlHandler(double cx, double cy, vec3 pos, vec3 dir_temp, col = 0; for (int a = -2; a < 0; a++) { off[1] = a; - col = col || cube_exists(pos[0] + off[0], pos[1] + off[1], + col = col || gen_cube(pos[0] + off[0], pos[1] + off[1], pos[2] + off[2], chunk, 0); } diff --git a/control.h b/control.h index 3e75bc6..62aa04f 100644 --- a/control.h +++ b/control.h @@ -1,5 +1,8 @@ -#include "linmath.h" +#ifndef V_CONTROL_H +#define V_CONTROL_H #include "cubes.h" +#include "linmath.h" #include -struct v3f controlHandler(double cx, double cy, vec3 pos, vec3 dir_temp, - GLFWwindow *window, struct chunk chunk); \ No newline at end of file +struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp, + GLFWwindow *window, struct chunk chunk); +#endif \ No newline at end of file diff --git a/cubes.c b/cubes.c index a27a954..0c4a0c7 100644 --- a/cubes.c +++ b/cubes.c @@ -22,16 +22,16 @@ int oz = -1024; struct chunk *chunk_old = NULL; -void gen_face(struct v3f *cube, int i, int x, int y, int z, int x2, int y2, - int z2, int *j, int is_text, struct chunk dat, int ci, int a3) { +void cubes_face(struct v3f *cube, int i, int x, int y, int z, int x2, int y2, + int z2, int *j, int is_text, struct chunk dat, int ci, int a3) { struct v3i a = {{x, y, z}}; struct v3f a2 = {{x, y, z}}; if (is_text) { a.pos[i]--; int exists = 0; - int type = cube_exists(x, y, z, dat, ci); - int typeB = cube_exists(a.pos[0], a.pos[1], a.pos[2], dat, ci); + int type = gen_cube(x, y, z, dat, ci); + int typeB = gen_cube(a.pos[0], a.pos[1], a.pos[2], dat, ci); exists = ((!!type) != (!!typeB)); a2.pos[0] = exists ? TEXT_GAP_H * (type ? (type - 1) : (typeB - 1)) : -1.0; @@ -67,7 +67,7 @@ void gen_face(struct v3f *cube, int i, int x, int y, int z, int x2, int y2, cube[*j + 5] = d; } -void *gen_chunk(void *args) { +void *cubes_chunk(void *args) { struct args args2 = ((struct args *)args)[0]; @@ -95,10 +95,10 @@ void *gen_chunk(void *args) { // int is_text = args2.is_text; - int the_j = a2; + int the_j = a2; - struct chunk chunk = fetch_chunk(x2 / CHUNK_LENGTH, y2 / CHUNK_LENGTH, - z2 / CHUNK_LENGTH, a, 0); + struct chunk chunk = + gen_chunk(x2 / CHUNK_LENGTH, y2 / CHUNK_LENGTH, z2 / CHUNK_LENGTH, a, 0); if (chunk.exists != 0 && the_j > -1) chunk_old[the_j] = chunk; @@ -117,8 +117,8 @@ void *gen_chunk(void *args) { int z3 = z2 + z4; for (int m = 0; m < 3; m++) { - gen_face(cube, m, x3, y3, z3, x4, y4, z4, &i, 0, chunk, a, a3); - gen_face(text, m, x3, y3, z3, x4, y4, z4, &i, 1, chunk, a, a3); + cubes_face(cube, m, x3, y3, z3, x4, y4, z4, &i, 0, chunk, a, a3); + cubes_face(text, m, x3, y3, z3, x4, y4, z4, &i, 1, chunk, a, a3); i += 6 * a3; if (i > CBLOCK_ALL * 18) return (void *)i; @@ -134,10 +134,10 @@ void *gen_chunk(void *args) { return (void *)i; } -void free_chunks_old() { free(chunk_old); } +void cubes_free() { free(chunk_old); } -int gen_cubes(struct v3f *cube, struct v3f *text, struct v3f *cubeO, - struct v3f *textO, int x, int y, int z, int is_purge, int *i2) { +int cubes_vert(struct v3f *cube, struct v3f *text, struct v3f *cubeO, + struct v3f *textO, int x, int y, int z, int is_purge, int *i2) { struct v3f noth = {{-1, -1, -1}}; for (int i = 0; i < CBLOCK_ALL * 18; i++) { cube[i] = noth; @@ -149,17 +149,12 @@ int gen_cubes(struct v3f *cube, struct v3f *text, struct v3f *cubeO, y *= CHUNK_LENGTH; z *= CHUNK_LENGTH; int a3 = CHUNK_DIAMETER_H; - int a = - 0; //(z % CHUNK_DIAMETER_H) + (x % CHUNK_DIAMETER_H) * CHUNK_DIAMETER_H + - //(y % CHUNK_DIAMETER_V) * CHUNK_DIAMETER_H * CHUNK_DIAMETER_H; - // a = a % a3; - // if (a < 0) a = -a; - + int a = 0; struct args args[a3]; int thread_return[a3]; if (is_purge) { for (int k = 0; k < a3; k++) { - purge_chunks(k); + gen_init(); } } @@ -211,7 +206,7 @@ int gen_cubes(struct v3f *cube, struct v3f *text, struct v3f *cubeO, thread_return[a2] = -1; thread_id[a2] = -1; } else { - pthread_create(&(thread_id[a2]), NULL, gen_chunk, + pthread_create(&(thread_id[a2]), NULL, cubes_chunk, (void *)&(args[a2])); } diff --git a/cubes.h b/cubes.h index 30a8800..4242247 100644 --- a/cubes.h +++ b/cubes.h @@ -38,8 +38,8 @@ struct v2f { vec2 pos; }; -int gen_cubes(struct v3f *cube, struct v3f *text, struct v3f *cubeO, +int cubes_vert(struct v3f *cube, struct v3f *text, struct v3f *cubeO, struct v3f *textO, int x, int y, int z, int is_purge, int *i2); -void free_chunks_old(); +void cubes_free(); #endif \ No newline at end of file diff --git a/gen.c b/gen.c index 6fe5d8d..39cb5f6 100644 --- a/gen.c +++ b/gen.c @@ -1,64 +1,14 @@ #include "cubes.h" -#include +#include "noise.h" #include #include #include struct chunk *chunks = NULL; int lastI = 0; -int seed = 69420; int prevExists = 0; -double interpolate(double a0, double a1, double w) { - return (a1 - a0) * (3.0 - w * 2.0) * w * w + a0; -} -int hash_combine(int a, int b) { return b + 0x9e3779b9 + (a << 6) + (a >> 2); } - -struct v2f perlin_grad(int x, int y) { - int x_hash = hash_combine(x, seed); - int y_hash = hash_combine(seed, y); - - double random = hash_combine(x_hash, y_hash) * (M_PI / ~(~0u >> 1)); - struct v2f out = {cos(random), sin(random)}; - return out; -} - -double perlin_dot(double ix, double iy, double x, double y) { - struct v2f grad = perlin_grad(ix, iy); - - double dx = x - (double)ix; - double dy = y - (double)iy; - return (dx * grad.pos[0] + dy * grad.pos[1]); -} - -double perlin_calc(double x, double y, double s) { - x /= s; - y /= s; - - int x0 = (int)floor(x); - int x1 = x0 + 1; - int y0 = (int)floor(y); - int y1 = y0 + 1; - - float sx = x - (float)x0; - float sy = y - (float)y0; - - float n0, n1, ix0, ix1, value; - - n0 = perlin_dot(x0, y0, x, y); - n1 = perlin_dot(x1, y0, x, y); - ix0 = interpolate(n0, n1, sx); - - n0 = perlin_dot(x0, y1, x, y); - n1 = perlin_dot(x1, y1, x, y); - ix1 = interpolate(n0, n1, sx); - - value = interpolate(ix0, ix1, sy); - - return value; -} - -struct chunk fetch_chunk(int x, int y, int z, int ci, int h) { +struct chunk gen_chunk(int x, int y, int z, int ci, int h) { struct chunk *chunks2 = chunks; // &chunks[CBUF_ALL * ci]; @@ -128,22 +78,7 @@ struct chunk fetch_chunk(int x, int y, int z, int ci, int h) { int c = 0; - for (int x2 = 0; x2 < CHUNK_LENGTH; x2++) { - int x3 = x2 + x * CHUNK_LENGTH; - for (int z2 = 0; z2 < CHUNK_LENGTH; z2++) { - int z3 = z2 + z * CHUNK_LENGTH; - double hp = perlin_calc(x3, z3, 128.0); - hp = ((hp > 0.0) ? -1.0 : 1.0) * (pow(fabs(hp), 0.7)); - hp *= 32.0; - int h = hp + 32; - - for (int y2 = 0; y2 < CHUNK_LENGTH; y2++) { - int y3 = y2 + y * CHUNK_LENGTH; - chunk.blocks[c] = (y3 < h) ? (((int)((hp + 64.0) * 2.98) % 3) + 1) : 0; - c++; - } - } - } + chunk = noise_chunk(chunk, x, y, z); chunks2[i] = chunk; @@ -157,21 +92,21 @@ struct chunk fetch_chunk(int x, int y, int z, int ci, int h) { return chunk; } -void purge_chunks(int ci) { +void gen_init() { if (chunks == NULL) { chunks = calloc(CHUNK_ALL, sizeof(struct chunk)); } } -void free_chunks() { free(chunks); } +void gen_free() { free(chunks); } -int cube_exists(int x, int y, int z, struct chunk dat, int ci) { +int gen_cube(int x, int y, int z, struct chunk dat, int ci) { if (x < 0 || y < 0 || z < 0) return 0; if (dat.exists == 0 || dat.x != (x / CHUNK_LENGTH) || dat.y != (y / CHUNK_LENGTH) || dat.z != (z / CHUNK_LENGTH)) { - dat = fetch_chunk((x / CHUNK_LENGTH), (y / CHUNK_LENGTH), + dat = gen_chunk((x / CHUNK_LENGTH), (y / CHUNK_LENGTH), (z / CHUNK_LENGTH), ci, dat.exists); prevExists = dat.exists; } diff --git a/gen.h b/gen.h index 61e6119..9504e0d 100644 --- a/gen.h +++ b/gen.h @@ -2,8 +2,8 @@ #define V_GEN_H #include "cubes.h" -int cube_exists(int x, int y, int z, struct chunk dat, int ci); -struct chunk fetch_chunk(int x, int y, int z, int ci, int h); -void purge_chunks(int ci); -void free_chunks(); +int gen_cube(int x, int y, int z, struct chunk dat, int ci); +struct chunk gen_chunk(int x, int y, int z, int ci, int h); +void gen_init(); +void gen_free(); #endif \ No newline at end of file diff --git a/main.c b/main.c index fc485b4..4d9e64e 100644 --- a/main.c +++ b/main.c @@ -98,7 +98,7 @@ void *render_chunks(void *args) { *args2.is_render = 0; *cube_count = - gen_cubes(*args2.cube, *args2.text, *args2.cubeO, *args2.textO, + cubes_vert(*args2.cube, *args2.text, *args2.cubeO, *args2.textO, args2.pos[0] / CHUNK_LENGTH, args2.pos[1] / CHUNK_LENGTH, args2.pos[2] / CHUNK_LENGTH, 0, args2.i2); @@ -134,7 +134,7 @@ int main(void) { int bleh = (CHUNK_DIAMETER_H) * (CHUNK_DIAMETER_V); int *i2 = calloc(bleh, sizeof(int)); - int cube_count = gen_cubes(cube, text, cubeO, textO, 10240 / CHUNK_LENGTH, + int cube_count = cubes_vert(cube, text, cubeO, textO, 10240 / CHUNK_LENGTH, 64 / CHUNK_LENGTH, 10240 / CHUNK_LENGTH, 1, i2); GLuint vertex_buffer[2]; @@ -189,10 +189,10 @@ int main(void) { vec3 oldPos = {0, 0, 0}; struct chunk ch7; ch7.exists = 0; - int state = cube_exists(pos[0], pos[1], pos[2], ch7, 0); + int state = gen_cube(pos[0], pos[1], pos[2], ch7, 0); while (1) { - if (state != cube_exists(pos[0], pos[1], pos[2], ch7, 0)) + if (state != gen_cube(pos[0], pos[1], pos[2], ch7, 0)) break; pos[1] += (state ? 1 : -1); } @@ -208,7 +208,7 @@ int main(void) { int last_render = 0; - struct chunk chunk = fetch_chunk(pos[0] / CHUNK_LENGTH, pos[1] / CHUNK_LENGTH, + struct chunk chunk = gen_chunk(pos[0] / CHUNK_LENGTH, pos[1] / CHUNK_LENGTH, pos[2] / CHUNK_LENGTH, 0, 0); vec3 dir_temp = {0, 0, 0}; @@ -232,7 +232,7 @@ int main(void) { vec3 direction; - vec3_dup(direction,controlHandler(cx, cy, pos, dir_temp, + vec3_dup(direction,control_handler(cx, cy, pos, dir_temp, window, chunk).pos); vec3 dir_pos; @@ -292,7 +292,7 @@ int main(void) { cubeO); // cube); if (thread_id != 0) { pthread_join(thread_id, NULL); - chunk = fetch_chunk(pos[0] / CHUNK_LENGTH, pos[1] / CHUNK_LENGTH, + chunk = gen_chunk(pos[0] / CHUNK_LENGTH, pos[1] / CHUNK_LENGTH, pos[2] / CHUNK_LENGTH, 0, 0); } thread_id = 0; @@ -320,8 +320,8 @@ int main(void) { free(cubeO); free(textO); free(i2); - free_chunks(); - free_chunks_old(); + gen_free(); + cubes_free(); glfwDestroyWindow(window); diff --git a/noise.c b/noise.c new file mode 100644 index 0000000..7a271d0 --- /dev/null +++ b/noise.c @@ -0,0 +1,75 @@ +#include "cubes.h" +#include + +int default_seed = 69420; + +double noise_interpolate(double a0, double a1, double w) { + return (a1 - a0) * (3.0 - w * 2.0) * w * w + a0; +} + +int noise_hash(int a, int b) { return b + 0x9e3779b9 + (a << 6) + (a >> 2); } + +struct v2f noise_perlin_grad(int x, int y, int seed) { + int x_hash = noise_hash(x, seed); + int y_hash = noise_hash(seed, y); + + double random = noise_hash(x_hash, y_hash) * (M_PI / ~(~0u >> 1)); + struct v2f out = {cos(random), sin(random)}; + return out; +} + +double noise_perlin_dot(double ix, double iy, double x, double y, int seed) { + struct v2f grad = noise_perlin_grad(ix, iy, seed); + + double dx = x - (double)ix; + double dy = y - (double)iy; + return (dx * grad.pos[0] + dy * grad.pos[1]); +} + +double noise_perlin(double x, double y, double s, int seed) { + x /= s; + y /= s; + + int x0 = (int)floor(x); + int x1 = x0 + 1; + int y0 = (int)floor(y); + int y1 = y0 + 1; + + float sx = x - (float)x0; + float sy = y - (float)y0; + + float n0, n1, ix0, ix1, value; + + n0 = noise_perlin_dot(x0, y0, x, y, seed); + n1 = noise_perlin_dot(x1, y0, x, y, seed); + ix0 = noise_interpolate(n0, n1, sx); + + n0 = noise_perlin_dot(x0, y1, x, y, seed); + n1 = noise_perlin_dot(x1, y1, x, y, seed); + ix1 = noise_interpolate(n0, n1, sx); + + value = noise_interpolate(ix0, ix1, sy); + + return value; +} + +struct chunk noise_chunk(struct chunk chunk, int x, int y, int z) { + int c = 0; + for (int x2 = 0; x2 < CHUNK_LENGTH; x2++) { + int x3 = x2 + x * CHUNK_LENGTH; + for (int z2 = 0; z2 < CHUNK_LENGTH; z2++) { + int z3 = z2 + z * CHUNK_LENGTH; + double hp = noise_perlin(x3, z3, 128.0, default_seed); + hp = ((hp > 0.0) ? -1.0 : 1.0) * (pow(fabs(hp), 0.7)); + hp *= 32.0; + int h = hp + 32; + + for (int y2 = 0; y2 < CHUNK_LENGTH; y2++) { + int y3 = y2 + y * CHUNK_LENGTH; + chunk.blocks[c] = (y3 < h) ? (((int)((hp + 64.0) * 2.98) % 3) + 1) : 0; + c++; + } + } + } + return chunk; +} \ No newline at end of file diff --git a/noise.h b/noise.h new file mode 100644 index 0000000..e3beb15 --- /dev/null +++ b/noise.h @@ -0,0 +1,12 @@ + +#ifndef V_NOISE_H +#define V_NOISE_H +#include "cubes.h" +#include +double noise_interpolate(double a0, double a1, double w); +int noise_hash(int a, int b); +struct v2f noise_perlin_grad(int x, int y, int seed); +double noise_perlin_dot(double ix, double iy, double x, double y, int seed); +double noise_perlin(double x, double y, double s, int seed); +struct chunk noise_chunk(struct chunk chunk, int x, int y, int z); +#endif \ No newline at end of file