{+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);
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;
#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});
}
#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
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();
}
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));
+}
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);
}
{
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);