3 #include "mapblock_meshgen.h"
15 static v3f vpos[6][6] = {
17 {-0.5f, -0.5f, -0.5f},
18 {+0.5f, -0.5f, -0.5f},
19 {+0.5f, +0.5f, -0.5f},
20 {+0.5f, +0.5f, -0.5f},
21 {-0.5f, +0.5f, -0.5f},
22 {-0.5f, -0.5f, -0.5f},
25 {-0.5f, -0.5f, +0.5f},
26 {+0.5f, +0.5f, +0.5f},
27 {+0.5f, -0.5f, +0.5f},
28 {+0.5f, +0.5f, +0.5f},
29 {-0.5f, -0.5f, +0.5f},
30 {-0.5f, +0.5f, +0.5f},
33 {-0.5f, +0.5f, +0.5f},
34 {-0.5f, -0.5f, -0.5f},
35 {-0.5f, +0.5f, -0.5f},
36 {-0.5f, -0.5f, -0.5f},
37 {-0.5f, +0.5f, +0.5f},
38 {-0.5f, -0.5f, +0.5f},
41 {+0.5f, +0.5f, +0.5f},
42 {+0.5f, +0.5f, -0.5f},
43 {+0.5f, -0.5f, -0.5f},
44 {+0.5f, -0.5f, -0.5f},
45 {+0.5f, -0.5f, +0.5f},
46 {+0.5f, +0.5f, +0.5f},
49 {-0.5f, -0.5f, -0.5f},
50 {+0.5f, -0.5f, -0.5f},
51 {+0.5f, -0.5f, +0.5f},
52 {+0.5f, -0.5f, +0.5f},
53 {-0.5f, -0.5f, +0.5f},
54 {-0.5f, -0.5f, -0.5f},
57 {-0.5f, +0.5f, -0.5f},
58 {+0.5f, +0.5f, -0.5f},
59 {+0.5f, +0.5f, +0.5f},
60 {+0.5f, +0.5f, +0.5f},
61 {-0.5f, +0.5f, +0.5f},
62 {-0.5f, +0.5f, -0.5f},
66 static v3s8 fdir[6] = {
75 #define GNODDEF(block, x, y, z) node_definitions[block->data[x][y][z].type]
76 #define VALIDPOS(pos) (pos.x >= 0 && pos.x < 16 && pos.y >= 0 && pos.y < 16 && pos.z >= 0 && pos.z < 16)
78 static Array make_vertices(MapBlock *block)
80 Array vertices = array_create(sizeof(Vertex));
83 NodeDefintion *def = &GNODDEF(block, x, y, z);
86 v3f offset = {x + 8.5f, y + 8.5f, z + 8.5f};
87 v3f color = get_node_color(def);
88 for (int f = 0; f < 6; f++) {
89 v3s8 *noff = &fdir[f];
95 if (! VALIDPOS(npos) || ! GNODDEF(block, npos.x, npos.y, npos.z).visible) {
96 for (int v = 0; v < 6; v++) {
98 vpos[f][v].x + offset.x,
99 vpos[f][v].y + offset.y,
100 vpos[f][v].z + offset.z,
105 array_append(&vertices, &vertex);
118 static void *meshgen_thread(void *unused)
122 while (! meshgen.cancel) {
123 ListPair **lptr = &meshgen.queue.first;
125 MapBlock *block = (*lptr)->key;
127 pthread_mutex_lock(&meshgen.mtx);
128 ListPair *next = (*lptr)->next;
131 pthread_mutex_unlock(&meshgen.mtx);
133 Array vertices = make_vertices(block);
136 if (vertices.siz > 0) {
137 mesh = mesh_create(vertices.ptr, vertices.siz);
138 mesh->pos = (v3f) {block->pos.x * 16.0f - 8.0f, block->pos.y * 16.0f - 8.0f, block->pos.z * 16.0f - 8.0f};
139 mesh_transform(mesh);
140 scene_add_mesh(meshgen.scene, mesh);
144 ((Mesh *) block->extra)->remove = true;
155 static void enqueue_block(MapBlock *block)
157 pthread_mutex_lock(&meshgen.mtx);
158 list_put(&meshgen.queue, block, NULL);
159 pthread_mutex_unlock(&meshgen.mtx);
162 void mapblock_meshgen_init(Map *map, Scene *scene)
165 meshgen.scene = scene;
166 meshgen.queue = list_create(NULL);
167 pthread_mutex_init(&meshgen.mtx, NULL);
168 map->on_block_add = &enqueue_block;
169 map->on_block_change = &enqueue_block;
170 pthread_create(&meshgen.thread, NULL, &meshgen_thread, NULL);
173 void mapblock_meshgen_stop()
175 meshgen.cancel = true;
176 pthread_join(meshgen.thread, NULL);
177 pthread_mutex_destroy(&meshgen.mtx);
178 ITERATE_LIST(&meshgen.queue, pair) free(pair->key);
179 list_clear(&meshgen.queue);