From ce6f67962df05a0bcce9a75212907b0ceede987a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Fri, 9 Jul 2021 20:43:35 +0200 Subject: [PATCH] Optimize MapBlock meshes --- src/blockmesh.c | 20 ++++++++++++-------- src/blockmesh.h | 2 +- src/clientmap.c | 21 ++++++++++++++++++--- src/input.c | 2 +- src/list.c | 2 +- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/blockmesh.c b/src/blockmesh.c index 7ea1368..d590fe0 100644 --- a/src/blockmesh.c +++ b/src/blockmesh.c @@ -61,15 +61,12 @@ static v3s8 fdir[6] = { {+0, +1, +0}, }; -#define VISIBLE(block, x, y, z) node_definitions[block->data[x][y][z].type].visible -#define VALIDPOS(pos) (pos.x >= 0 && pos.x < 16 && pos.y >= 0 && pos.y < 16 && pos.z >= 0 && pos.z < 16) - -static VertexBuffer make_vertices(MapBlock *block) +static VertexBuffer make_vertices(MapBlock *block, Map *map) { VertexBuffer buffer = vertexbuffer_create(); ITERATE_MAPBLOCK { - if (VISIBLE(block, x, y, z)) { + if (node_definitions[block->data[x][y][z].type].visible) { v3f offset = {x + 8.5f, y + 8.5f, z + 8.5f}; vertexbuffer_set_texture(&buffer, client_node_definitions[block->data[x][y][z].type].texture); @@ -81,7 +78,14 @@ static VertexBuffer make_vertices(MapBlock *block) z + fdir[f].z, }; - if (! VALIDPOS(npos) || ! VISIBLE(block, npos.x, npos.y, npos.z)) { + Node neighbor; + + if (npos.x >= 0 && npos.x < 16 && npos.y >= 0 && npos.y < 16 && npos.z >= 0 && npos.z < 16) + neighbor = block->data[npos.x][npos.y][npos.z].type; + else + neighbor = map_get_node(map, (v3s32) {npos.x + block->pos.x * 16, npos.y + block->pos.y * 16, npos.z + block->pos.z * 16}).type; + + if (neighbor != NODE_UNLOADED && ! node_definitions[neighbor].visible) { for (int v = 0; v < 6; v++) { Vertex vertex = cube_vertices[f][v]; vertex.x += offset.x; @@ -101,9 +105,9 @@ static VertexBuffer make_vertices(MapBlock *block) #undef GNODDEF #undef VALIDPOS -void make_block_mesh(MapBlock *block, Scene *scene) +void make_block_mesh(MapBlock *block, Map *map, Scene *scene) { if (block->extra) ((MeshObject *) block->extra)->remove = true; - block->extra = meshobject_create(make_vertices(block), scene, (v3f) {block->pos.x * 16.0f - 8.0f, block->pos.y * 16.0f - 8.0f, block->pos.z * 16.0f - 8.0f}); + block->extra = meshobject_create(make_vertices(block, map), scene, (v3f) {block->pos.x * 16.0f - 8.0f, block->pos.y * 16.0f - 8.0f, block->pos.z * 16.0f - 8.0f}); } diff --git a/src/blockmesh.h b/src/blockmesh.h index 0cefc7e..099caa0 100644 --- a/src/blockmesh.h +++ b/src/blockmesh.h @@ -4,6 +4,6 @@ #include "map.h" #include "scene.h" -void make_block_mesh(MapBlock *block, Scene *scene); +void make_block_mesh(MapBlock *block, Map *map, Scene *scene); #endif diff --git a/src/clientmap.c b/src/clientmap.c index 8c8a62d..dd72ec3 100644 --- a/src/clientmap.c +++ b/src/clientmap.c @@ -22,7 +22,7 @@ static void *meshgen_thread(__attribute__((unused)) void *unused) while (! meshgen.cancel) { MapBlock *block; if ((block = dequeue_callback(meshgen.queue, &set_block_ready))) - make_block_mesh(block, client->scene); + make_block_mesh(block, client->map, client->scene); else sched_yield(); } @@ -49,12 +49,27 @@ void clientmap_deinit() pthread_join(meshgen.thread, NULL); } -void clientmap_block_changed(MapBlock *block) +static void schedule_update_block(MapBlock *block) { + if (! block) + return; + pthread_mutex_lock(&block->mtx); - if (block->state == MBS_MODIFIED) { + if (block->state != MBS_PROCESSING) { block->state = MBS_PROCESSING; enqueue(meshgen.queue, block); } pthread_mutex_unlock(&block->mtx); } + +void clientmap_block_changed(MapBlock *block) +{ + schedule_update_block(block); + + schedule_update_block(map_get_block(client->map, (v3s32) {block->pos.x + 1, block->pos.y + 0, block->pos.z + 0}, false)); + schedule_update_block(map_get_block(client->map, (v3s32) {block->pos.x + 0, block->pos.y + 1, block->pos.z + 0}, false)); + schedule_update_block(map_get_block(client->map, (v3s32) {block->pos.x + 0, block->pos.y + 0, block->pos.z + 1}, false)); + schedule_update_block(map_get_block(client->map, (v3s32) {block->pos.x - 1, block->pos.y - 0, block->pos.z - 0}, false)); + schedule_update_block(map_get_block(client->map, (v3s32) {block->pos.x - 0, block->pos.y - 1, block->pos.z - 0}, false)); + schedule_update_block(map_get_block(client->map, (v3s32) {block->pos.x - 0, block->pos.y - 0, block->pos.z - 1}, false)); +} diff --git a/src/input.c b/src/input.c index 71c0895..5725bcc 100644 --- a/src/input.c +++ b/src/input.c @@ -21,7 +21,7 @@ static void cursor_pos_callback(__attribute__((unused)) GLFWwindow* window, doub input.client->yaw += (float) delta_x * M_PI / 180.0f / 8.0f; input.client->pitch -= (float) delta_y * M_PI / 180.0f / 8.0f; - input.client->pitch = fmax(fmin(input.client->pitch, 90.0f), -90.0f); + input.client->pitch = fmax(fmin(input.client->pitch, 89.0f), -89.0f); set_camera_angle(input.client->yaw, input.client->pitch); } diff --git a/src/list.c b/src/list.c index 8734f4f..7388eaf 100644 --- a/src/list.c +++ b/src/list.c @@ -71,7 +71,7 @@ void list_set(List *list, void *key, void *value) { ListPair **pairptr; for (pairptr = &list->first; *pairptr != NULL; pairptr = &(*pairptr)->next) { - if (strcmp((*pairptr)->key, key) == 0) + if (list->cmp((*pairptr)->key, key)) break; } *pairptr = make_pair(key, value); -- 2.44.0