]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/client/facecache.c
f08854d0efe15aa4031b62d43d84da1a0764e7c7
[dragonblocks_alpha.git] / src / client / facecache.c
1 #include <stdlib.h>
2 #include <dragonstd/array.h>
3 #include "client/facecache.h"
4
5 static struct
6 {
7         Array positions;
8         u32 size;
9         pthread_mutex_t mtx;
10 } facecache;
11
12 __attribute((constructor)) static void face_cache_init()
13 {
14         facecache.size = 0;
15         facecache.positions = array_create(sizeof(v3s32));
16         v3s32 pos = {0, 0, 0};
17         array_append(&facecache.positions, &pos);
18         pthread_mutex_init(&facecache.mtx, NULL);
19 }
20
21 __attribute((destructor)) void face_cache_deinit()
22 {
23         if (facecache.positions.ptr)
24                 free(facecache.positions.ptr);
25         pthread_mutex_destroy(&facecache.mtx);
26 }
27
28 static void face_cache_calculate(s32 size)
29 {
30 #define ADDPOS(a, b, c, va, vb, vc) \
31         { \
32                 v3s32 pos; \
33                 *(s32 *) ((char *) &pos + offsetof(v3s32, a)) = va; \
34                 *(s32 *) ((char *) &pos + offsetof(v3s32, b)) = vb; \
35                 *(s32 *) ((char *) &pos + offsetof(v3s32, c)) = vc; \
36                 array_append(&facecache.positions, &pos); \
37         }
38 #define SQUARES(a, b, c) \
39         for (s32 va = -size + 1; va < size; va++) { \
40                 for (s32 vb = -size + 1; vb < size; vb++) { \
41                         ADDPOS(a, b, c, va, vb,  size) \
42                         ADDPOS(a, b, c, va, vb, -size) \
43                 } \
44         }
45         SQUARES(x, z, y)
46         SQUARES(x, y, z)
47         SQUARES(z, y, x)
48 #undef SQUARES
49 #define EDGES(a, b, c) \
50         for (s32 va = -size + 1; va < size; va++) { \
51                 ADDPOS(a, b, c, va,  size,  size) \
52                 ADDPOS(a, b, c, va,  size, -size) \
53                 ADDPOS(a, b, c, va, -size,  size) \
54                 ADDPOS(a, b, c, va, -size, -size) \
55         }
56         EDGES(x, y, z)
57         EDGES(z, x, y)
58         EDGES(y, x, z)
59 #undef EDGES
60         ADDPOS(x, y, z,  size,  size,  size)
61         ADDPOS(x, y, z,  size,  size, -size)
62         ADDPOS(x, y, z,  size, -size,  size)
63         ADDPOS(x, y, z,  size, -size, -size)
64         ADDPOS(x, y, z, -size,  size,  size)
65         ADDPOS(x, y, z, -size,  size, -size)
66         ADDPOS(x, y, z, -size, -size,  size)
67         ADDPOS(x, y, z, -size, -size, -size)
68 #undef ADDPOS
69 }
70
71 v3s32 facecache_face(size_t i, v3s32 *base)
72 {
73         pthread_mutex_lock(&facecache.mtx);
74         while (facecache.positions.siz <= i)
75                 face_cache_calculate(++facecache.size);
76         v3s32 pos = ((v3s32 *) facecache.positions.ptr)[i];
77         pthread_mutex_unlock(&facecache.mtx);
78         if (base) {
79                 pos.x += base->x;
80                 pos.y += base->y;
81                 pos.z += base->z;
82         }
83         return pos;
84 }
85
86 size_t facecache_count(u32 size)
87 {
88         size_t len = 1 + size * 2;
89         return len * len * len;
90 }