12 static Client *client = NULL;
14 static v3f vpos[6][6] = {
16 {-0.5f, -0.5f, -0.5f},
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},
24 {-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},
32 {-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},
40 {+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},
48 {-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},
56 {-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},
65 static v3s8 fdir[6] = {
74 #define GNODDEF(block, x, y, z) node_definitions[block->data[x][y][z].type]
75 #define VALIDPOS(pos) (pos.x >= 0 && pos.x < 16 && pos.y >= 0 && pos.y < 16 && pos.z >= 0 && pos.z < 16)
77 static Array make_vertices(MapBlock *block)
79 Array vertices = array_create(sizeof(Vertex));
82 NodeDefintion *def = &GNODDEF(block, x, y, z);
85 v3f offset = {x + 8.5f, y + 8.5f, z + 8.5f};
86 v3f color = get_node_color(def);
87 for (int f = 0; f < 6; f++) {
88 v3s8 *noff = &fdir[f];
94 if (! VALIDPOS(npos) || ! GNODDEF(block, npos.x, npos.y, npos.z).visible) {
95 for (int v = 0; v < 6; v++) {
97 vpos[f][v].x + offset.x,
98 vpos[f][v].y + offset.y,
99 vpos[f][v].z + offset.z,
104 array_append(&vertices, &vertex);
117 static void *meshgen_thread(void *unused)
121 while (! meshgen.cancel) {
122 ListPair **lptr = &meshgen.queue.first;
124 pthread_mutex_lock(&meshgen.mtx);
125 MapBlock *block = (*lptr)->key;
126 block->state = MBS_READY;
127 ListPair *next = (*lptr)->next;
130 pthread_mutex_unlock(&meshgen.mtx);
132 Array vertices = make_vertices(block);
135 if (vertices.siz > 0) {
136 mesh = mesh_create(vertices.ptr, vertices.siz);
137 mesh->pos = (v3f) {block->pos.x * 16.0f - 8.0f, block->pos.y * 16.0f - 8.0f, block->pos.z * 16.0f - 8.0f};
138 mesh_transform(mesh);
139 scene_add_mesh(client->scene, mesh);
143 ((Mesh *) block->extra)->remove = true;
154 void clientmap_init(Client *cli)
157 meshgen.queue = list_create(NULL);
158 pthread_mutex_init(&meshgen.mtx, NULL);
159 pthread_create(&meshgen.thread, NULL, &meshgen_thread, NULL);
162 void clientmap_deinit()
164 meshgen.cancel = true;
165 pthread_join(meshgen.thread, NULL);
166 pthread_mutex_destroy(&meshgen.mtx);
167 list_clear(&meshgen.queue);
170 void clientmap_block_changed(MapBlock *block)
172 pthread_mutex_lock(&meshgen.mtx);
173 if (block->state != MBS_PROCESSING) {
174 block->state = MBS_PROCESSING;
175 list_put(&meshgen.queue, block, NULL);
177 pthread_mutex_unlock(&meshgen.mtx);