diff --git a/control.c b/control.c index b130a44..fc89c10 100644 --- a/control.c +++ b/control.c @@ -2,6 +2,7 @@ #include "gen.h" #include "linmath.h" #include +#include int is_space; @@ -33,7 +34,7 @@ int collision(struct chunk chunk, vec3 pos, vec3 dir_temp, int col, int n) { } struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp, - GLFWwindow *window, struct chunk chunk) { + GLFWwindow *window, struct chunk chunk) { vec3 direction = {cosf(cy) * sinf(cx) * 0.1, sinf(cy) * 0.1, cosf(cy) * cosf(cx) * 0.1}; vec3 right = {sinf(cx - 3.14f / 2.0f) * 0.1, 0, @@ -52,10 +53,6 @@ struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp, vec3_add(dir_temp, dir_temp, front); } - if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) { - vec3_add(dir_temp, dir_temp, direction); - } - if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { vec3_add(dir_temp, dir_temp, right); } @@ -71,7 +68,7 @@ struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp, for (int a = -2; a < 0; a++) { off[1] = a; col = col || gen_cube(pos[0] + off[0], pos[1] + off[1], pos[2] + off[2], - chunk, 0); + chunk, 0, -1); } vec3_add(pos, pos, dir_temp); @@ -80,8 +77,8 @@ struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp, col = 0; for (int a = -2; a < 0; a++) { off[1] = a; - col = col || gen_cube(pos[0] + off[0], pos[1] + off[1], - pos[2] + off[2], chunk, 0); + col = col || gen_cube(pos[0] + off[0], pos[1] + off[1], pos[2] + off[2], + chunk, 0, -1); } if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) { @@ -101,4 +98,66 @@ struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp, vec3_dup(dirOut.pos, direction); return dirOut; +} + +struct v3f control_rtrace(double cx, double cy, vec3 pos, int mode) { + struct chunk placeChunk; + vec3 direction = {cosf(cy) * sinf(cx) * 0.1, sinf(cy) * 0.1, + cosf(cy) * cosf(cx) * 0.1}; + + vec3 temp_pos; + vec3 temp_dir; + vec3_dup(temp_pos, pos); + + for (int i = 0; i < CHUNK_LENGTH * 4; i++) { + + double xd = + fabs(direction[0]) / (((direction[0] > 0) ? (1.0 - fmod(temp_pos[0], 1)) + : fmod(temp_pos[0], 1)) + + 0.01); + double yd = + fabs(direction[1]) / (((direction[1] > 0) ? (1.0 - fmod(temp_pos[1], 1)) + : fmod(temp_pos[1], 1)) + + 0.01); + double zd = + fabs(direction[2]) / (((direction[2] > 0) ? (1.0 - fmod(temp_pos[2], 1)) + : fmod(temp_pos[2], 1)) + + 0.01); + + if (xd > yd && xd > zd && !isnan(xd)) { + vec3_scale(temp_dir, direction, fabs(1 / xd + 0.01)); + } else if (yd > zd && !isnan(yd)) { + vec3_scale(temp_dir, direction, fabs(1 / yd + 0.01)); + } else if (!isnan(zd)) { + vec3_scale(temp_dir, direction, fabs(1 / zd + 0.01)); + } + + vec3_add(temp_pos, temp_pos, temp_dir); + + if (gen_cube(temp_pos[0],temp_pos[1],temp_pos[2],placeChunk,0,-1) != 0) { + if (mode == 0) vec3_sub(temp_pos,temp_pos,temp_dir); + break; + } + } + + struct v3f out_pos; + vec3_dup(out_pos.pos, temp_pos); + + return out_pos; +} + +void control_lclick(double cx, double cy, vec3 pos) { + struct v3f highlighted = control_rtrace(cx, cy, pos, 1); + struct chunk placeChunk; + int cube = gen_cube(highlighted.pos[0],highlighted.pos[1],highlighted.pos[2],placeChunk,0,-1); + if (cube == 0) return; + gen_cube(highlighted.pos[0],highlighted.pos[1],highlighted.pos[2],placeChunk,0,0); +} + +void control_rclick(double cx, double cy, vec3 pos) { + struct v3f highlighted = control_rtrace(cx, cy, pos, 0); + struct chunk placeChunk; + int cube = gen_cube(highlighted.pos[0],highlighted.pos[1],highlighted.pos[2],placeChunk,0,-1); + if (cube != 0) return; + gen_cube(highlighted.pos[0],highlighted.pos[1],highlighted.pos[2],placeChunk,0,1); } \ No newline at end of file diff --git a/control.h b/control.h index 62aa04f..0b556f2 100644 --- a/control.h +++ b/control.h @@ -5,4 +5,6 @@ #include struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp, GLFWwindow *window, struct chunk chunk); +void control_lclick(double cx, double cy, vec3 pos); +void control_rclick(double cx, double cy, vec3 pos); #endif \ No newline at end of file diff --git a/cubes.c b/cubes.c index 0c4a0c7..205f204 100644 --- a/cubes.c +++ b/cubes.c @@ -30,8 +30,8 @@ void cubes_face(struct v3f *cube, int i, int x, int y, int z, int x2, int y2, if (is_text) { a.pos[i]--; int exists = 0; - int type = gen_cube(x, y, z, dat, ci); - int typeB = gen_cube(a.pos[0], a.pos[1], a.pos[2], dat, ci); + int type = gen_cube(x, y, z, dat, ci, -1); + int typeB = gen_cube(a.pos[0], a.pos[1], a.pos[2], dat, ci, -1); exists = ((!!type) != (!!typeB)); a2.pos[0] = exists ? TEXT_GAP_H * (type ? (type - 1) : (typeB - 1)) : -1.0; @@ -136,6 +136,17 @@ void *cubes_chunk(void *args) { void cubes_free() { free(chunk_old); } +void cubes_refresh(int x, int y, int z, struct chunk dat) { + for (int i = 0; i < CHUNK_ALL; i++) { + if (chunk_old[i].exists != 0 && chunk_old[i].x == x && + chunk_old[i].y == y && chunk_old[i].z == z) { + chunk_old[i].exists = 0; + gen_save(dat); + return; + } + } +} + 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}}; @@ -199,10 +210,9 @@ int cubes_vert(struct v3f *cube, struct v3f *text, struct v3f *cubeO, old_chunk.y == pos.pos[1] / CHUNK_LENGTH && old_chunk.z == pos.pos[2] / CHUNK_LENGTH && old_chunk.exists != 0); if (cached) { - thread_return[a2] = i2[a2 / a3]; + thread_return[a2] = i2[a2 / a3] - 6; thread_id[a2] = -1; - } else if (pos.pos[0] < 0 || pos.pos[1] < 0 || pos.pos[2] < 0 || - pos.pos[1] < ((y - CHUNK_LENGTH * CHUNK_RADIUS_V) * 1.05)) { + } else if (pos.pos[0] < 0 || pos.pos[1] < 0 || pos.pos[2] < 0) { thread_return[a2] = -1; thread_id[a2] = -1; } else { diff --git a/cubes.h b/cubes.h index 4241531..eb2f12d 100644 --- a/cubes.h +++ b/cubes.h @@ -39,7 +39,8 @@ struct v2f { }; 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 *textO, int x, int y, int z, int is_purge, int *i2); void cubes_free(); +void cubes_refresh(int x, int y, int z, struct chunk dat); #endif \ No newline at end of file diff --git a/gen.c b/gen.c index 39cb5f6..3841d00 100644 --- a/gen.c +++ b/gen.c @@ -1,3 +1,4 @@ +#include "gen.h" #include "cubes.h" #include "noise.h" #include @@ -8,6 +9,37 @@ struct chunk *chunks = NULL; int lastI = 0; int prevExists = 0; +void gen_save(struct chunk chunk) { + char fname[1024]; + snprintf(fname, 1023, "./db/chunk_%i_%i_%i.dat", chunk.x, chunk.y, chunk.z); + if (chunk.exists == 0) + return; + + FILE *fp = fopen(fname, "wb"); + if (!fp) { + return; + } + + fwrite(&chunk, sizeof(struct chunk), 1, fp); + fclose(fp); + + return; +} + +struct chunk gen_find(int x, int y, int z) { + struct chunk chunk; + for (int j = 0; j < CBUF_ALL; j++) { + int i = j; + chunk = chunks[i]; + if ((chunk).x == x && (chunk).y == y && (chunk).z == z && + (chunk).exists != 0) { + return chunk; + } + } + chunk = (gen_chunk(x, y, z, 0, 0)); + return chunk; +} + struct chunk gen_chunk(int x, int y, int z, int ci, int h) { struct chunk *chunks2 = chunks; // &chunks[CBUF_ALL * ci]; @@ -47,6 +79,10 @@ struct chunk gen_chunk(int x, int y, int z, int ci, int h) { } } + if (chunk.exists == 1 && chunk.x != x && chunk.y != y && chunk.z != z) { + gen_save(chunk); + } + char fname[1024]; snprintf(fname, 1023, "./db/chunk_%i_%i_%i.dat", x, y, z); @@ -62,9 +98,8 @@ struct chunk gen_chunk(int x, int y, int z, int ci, int h) { chunk.exists = 1; return chunk; } - } - if (!fp) { - fp = fopen(fname, "wb"); + } else if (fp) { + fclose(fp); } lastI = i; @@ -82,12 +117,7 @@ struct chunk gen_chunk(int x, int y, int z, int ci, int h) { chunks2[i] = chunk; - if (!fp) { - return chunk; - } - - fwrite(&chunk, sizeof(struct chunk), 1, fp); - fclose(fp); + gen_save(chunk); return chunk; } @@ -98,21 +128,33 @@ void gen_init() { } } -void gen_free() { free(chunks); } +void gen_free() { + for (int i = 0; i < CHUNK_ALL; i++) { + gen_save(chunks[i]); + } + free(chunks); +} -int gen_cube(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, int val) { if (x < 0 || y < 0 || z < 0) return 0; - if (dat.exists == 0 || dat.x != (x / CHUNK_LENGTH) || + if (val != -1) { + dat = gen_find((x / CHUNK_LENGTH), (y / CHUNK_LENGTH), (z / CHUNK_LENGTH)); + } else if (dat.exists == 0 || dat.x != (x / CHUNK_LENGTH) || dat.y != (y / CHUNK_LENGTH) || dat.z != (z / CHUNK_LENGTH)) { - dat = gen_chunk((x / CHUNK_LENGTH), (y / CHUNK_LENGTH), - (z / CHUNK_LENGTH), ci, dat.exists); + dat = gen_chunk((x / CHUNK_LENGTH), (y / CHUNK_LENGTH), (z / CHUNK_LENGTH), + ci, dat.exists); prevExists = dat.exists; } - int h = dat.blocks[(y % CHUNK_LENGTH) + (z % CHUNK_LENGTH) * CHUNK_LENGTH + - (x % CHUNK_LENGTH) * CHUNK_LENGTH * CHUNK_LENGTH]; + int *h = &dat.blocks[(y % CHUNK_LENGTH) + (z % CHUNK_LENGTH) * CHUNK_LENGTH + + (x % CHUNK_LENGTH) * CHUNK_LENGTH * CHUNK_LENGTH]; - return h; + if (val != -1) { + *h = val; + cubes_refresh(x / CHUNK_LENGTH, y / CHUNK_LENGTH, z / CHUNK_LENGTH, dat); + } + + return *h; } \ No newline at end of file diff --git a/gen.h b/gen.h index 9504e0d..31a04ae 100644 --- a/gen.h +++ b/gen.h @@ -2,8 +2,9 @@ #define V_GEN_H #include "cubes.h" -int gen_cube(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, int val); struct chunk gen_chunk(int x, int y, int z, int ci, int h); void gen_init(); void gen_free(); +void gen_save(struct chunk chunk); #endif \ No newline at end of file diff --git a/main.c b/main.c index 4d9e64e..a8fbace 100644 --- a/main.c +++ b/main.c @@ -9,12 +9,12 @@ #include #include +#include "control.h" #include "cubes.h" #include "gen.h" #include "gl.h" #include "linmath.h" #include "stb_image.h" -#include "control.h" static const char *vertex_shader_text = "#version 330\n" @@ -64,6 +64,21 @@ static void key_callback(GLFWwindow *window, int key, int scancode, int action, double cx = 0; double cy = 0; +int fr = 0; +vec3 pos; + +void mouse_button_callback(GLFWwindow *window, int button, int action, + int mods) { + if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) { + fr = 1; + control_rclick(cx, cy, pos); + } + if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) { + fr = 1; + control_lclick(cx, cy, pos); + } +} + int width, height; static void cursor_position_callback(GLFWwindow *window, double x, double y) { @@ -99,8 +114,8 @@ void *render_chunks(void *args) { *cube_count = 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); + args2.pos[0] / CHUNK_LENGTH, args2.pos[1] / CHUNK_LENGTH, + args2.pos[2] / CHUNK_LENGTH, 0, args2.i2); *args2.is_render = 2; @@ -134,8 +149,6 @@ int main(void) { int bleh = (CHUNK_DIAMETER_H) * (CHUNK_DIAMETER_V); int *i2 = calloc(bleh, sizeof(int)); - int cube_count = cubes_vert(cube, text, cubeO, textO, 10240 / CHUNK_LENGTH, - 64 / CHUNK_LENGTH, 10240 / CHUNK_LENGTH, 1, i2); GLuint vertex_buffer[2]; GLuint vertex_array; @@ -183,16 +196,23 @@ int main(void) { glEnable(GL_DEPTH_TEST); glfwSetKeyCallback(window, key_callback); + glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetCursorPosCallback(window, cursor_position_callback); - vec3 pos = {10240, 48, 10240}; + pos[0] = 10240; + pos[1] = 48; + pos[2] = 10240; + + int cube_count = + cubes_vert(cube, text, cubeO, textO, pos[0] / CHUNK_LENGTH, + pos[1] / CHUNK_LENGTH, pos[2] / CHUNK_LENGTH, 1, i2); vec3 oldPos = {0, 0, 0}; struct chunk ch7; ch7.exists = 0; - int state = gen_cube(pos[0], pos[1], pos[2], ch7, 0); + int state = gen_cube(pos[0], pos[1], pos[2], ch7, 0, -1); while (1) { - if (state != gen_cube(pos[0], pos[1], pos[2], ch7, 0)) + if (state != gen_cube(pos[0], pos[1], pos[2], ch7, 0, -1)) break; pos[1] += (state ? 1 : -1); } @@ -209,12 +229,14 @@ int main(void) { int last_render = 0; struct chunk chunk = gen_chunk(pos[0] / CHUNK_LENGTH, pos[1] / CHUNK_LENGTH, - pos[2] / CHUNK_LENGTH, 0, 0); + pos[2] / CHUNK_LENGTH, 0, 0); vec3 dir_temp = {0, 0, 0}; vec3 direction; + fr = 1; + while (!glfwWindowShouldClose(window)) { glfwGetFramebufferSize(window, &width, &height); @@ -228,12 +250,10 @@ int main(void) { mat4x4_identity(m); mat4x4_perspective(p, 45.0 / 180.0 * M_PI, ratio, 0.1, 1000); - // TODO: make control code its own thing - vec3 direction; - - vec3_dup(direction,control_handler(cx, cy, pos, dir_temp, - window, chunk).pos); + + vec3_dup(direction, + control_handler(cx, cy, pos, dir_temp, window, chunk).pos); vec3 dir_pos; vec3_scale(direction, direction, 100.0); @@ -252,7 +272,8 @@ int main(void) { int ay = (int)(oldPos[1] / CHUNK_LENGTH) - (int)(pos[1] / CHUNK_LENGTH); int az = (int)(oldPos[2] / CHUNK_LENGTH) - (int)(pos[2] / CHUNK_LENGTH); - if ((ax != 0 || ay != 0 || az != 0) && last_render < 0) { + if (((ax != 0 || ay != 0 || az != 0) && last_render < 0) || fr == 1) { + fr = 0; struct args args; args.cube_count = &cube_count; @@ -283,17 +304,17 @@ int main(void) { glfwPollEvents(); if (is_render == 2) { - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[1]); - glBufferSubData(GL_ARRAY_BUFFER, 0, (long)cube_count * sizeof(struct v3f), - textO); // text); - - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[0]); - glBufferSubData(GL_ARRAY_BUFFER, 0, (long)cube_count * sizeof(struct v3f), - cubeO); // cube); if (thread_id != 0) { + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, + (long)cube_count * sizeof(struct v3f), textO); + + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[0]); + glBufferSubData(GL_ARRAY_BUFFER, 0, + (long)cube_count * sizeof(struct v3f), cubeO); pthread_join(thread_id, NULL); chunk = gen_chunk(pos[0] / CHUNK_LENGTH, pos[1] / CHUNK_LENGTH, - pos[2] / CHUNK_LENGTH, 0, 0); + pos[2] / CHUNK_LENGTH, 0, 0); } thread_id = 0; }