2 #include "mapblock_meshgen.h"
14 static Array make_vertices(MapBlock *block)
16 Array vertices = array_create(sizeof(GLfloat));
22 MapNode node = block->data[x][y][z];
23 BlockDef *def = block->getDef();
27 vec3 pos_from_mesh_origin = vec3(bpos) - vec3(SIZE / 2 + 0.5);
28 for (int facenr = 0; facenr < 6; facenr++) {
29 ivec3 npos = bpos + face_dir[facenr];
30 const Block *neighbor_own, *neighbor;
31 neighbor_own = neighbor = getBlockNoEx(npos);
33 neighbor = map->getBlock(pos * SIZE + npos);
34 if (neighbor && ! neighbor->getDef()->drawable)
35 any_drawable_block = true;
36 if (! mesh_created_before)
37 neighbor = neighbor_own;
38 if (! mesh_created_before && ! neighbor || neighbor && ! neighbor->getDef()->drawable) {
39 textures.push_back(def->tile_def.get(facenr));
40 for (int vertex_index = 0; vertex_index < 6; vertex_index++) {
41 for (int attribute_index = 0; attribute_index < 5; attribute_index++) {
42 GLdouble value = box_vertices[facenr][vertex_index][attribute_index];
43 switch (attribute_index) {
45 value += pos_from_mesh_origin.x;
48 value += pos_from_mesh_origin.y;
51 value += pos_from_mesh_origin.z;
54 vertices.push_back(value);
65 static void *meshgen_thread(void *unused)
69 while (! meshgen.cancel) {
70 ListPair **lptr = &meshgen.queue.first;
72 MapBlock *block = map_get_block(meshgen.map, *(v3s32 *)(*lptr)->key, false);
74 pthread_mutex_lock(&meshgen.mtx);
76 *lptr = (*lptr)->next;
77 pthread_mutex_unlock(&meshgen.mtx);
79 Array vertices = make_vertices(block);
82 if (vertices.siz > 0) {
83 mesh = mesh_create(vertices.ptr, vertices.siz);
85 scene_add_mesh(meshgen.scene, mesh);
100 static void enqueue_block(MapBlock *block)
102 v3s32 *posptr = malloc(sizeof(v3s32));
103 *posptr = block->pos;
104 pthread_mutex_lock(&meshgen.mtx);
105 if (! list_put(&meshgen.queue, posptr, NULL))
107 pthread_mutex_unlock(&meshgen.mtx);
110 static bool compare_positions(void *p1, void *p2)
114 return pos1->x == pos2->x && pos1->y == pos2->y && pos1->z == pos2->z;
117 void mapblock_meshgen_init(Map *map, Scene *scene)
120 meshgen.scene = scene;
121 meshgen.queue = list_create(&compare_positions);
122 pthread_mutex_init(&meshgen.mtx, NULL);
123 map->on_block_add = &enqueue_block;
124 map->on_block_change = &enqueue_block;
125 pthread_create(&meshgen.thread, NULL, &meshgen_thread, NULL);
128 void mapblock_meshgen_stop()
130 meshgen.cancel = true;
131 pthread_join(meshgen.thread, NULL);
132 pthread_mutex_destroy(&meshgen.mtx);
133 ITERATE_LIST(&meshgen.queue, pair) free(pair->key);
134 list_clear(&meshgen.queue);