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