1 #include <math.h>
2 #include "cube.h"
3 #include "item.h"
4 #include "matrix.h"
5 #include "util.h"
6
make_cube_faces(float * data,float ao[6][4],float light[6][4],int left,int right,int top,int bottom,int front,int back,int wleft,int wright,int wtop,int wbottom,int wfront,int wback,float x,float y,float z,float n)7 void make_cube_faces(
8 float *data, float ao[6][4], float light[6][4],
9 int left, int right, int top, int bottom, int front, int back,
10 int wleft, int wright, int wtop, int wbottom, int wfront, int wback,
11 float x, float y, float z, float n)
12 {
13 static const float positions[6][4][3] = {
14 {{-1, -1, -1}, {-1, -1, +1}, {-1, +1, -1}, {-1, +1, +1}},
15 {{+1, -1, -1}, {+1, -1, +1}, {+1, +1, -1}, {+1, +1, +1}},
16 {{-1, +1, -1}, {-1, +1, +1}, {+1, +1, -1}, {+1, +1, +1}},
17 {{-1, -1, -1}, {-1, -1, +1}, {+1, -1, -1}, {+1, -1, +1}},
18 {{-1, -1, -1}, {-1, +1, -1}, {+1, -1, -1}, {+1, +1, -1}},
19 {{-1, -1, +1}, {-1, +1, +1}, {+1, -1, +1}, {+1, +1, +1}}
20 };
21 static const float normals[6][3] = {
22 {-1, 0, 0},
23 {+1, 0, 0},
24 {0, +1, 0},
25 {0, -1, 0},
26 {0, 0, -1},
27 {0, 0, +1}
28 };
29 static const float uvs[6][4][2] = {
30 {{0, 0}, {1, 0}, {0, 1}, {1, 1}},
31 {{1, 0}, {0, 0}, {1, 1}, {0, 1}},
32 {{0, 1}, {0, 0}, {1, 1}, {1, 0}},
33 {{0, 0}, {0, 1}, {1, 0}, {1, 1}},
34 {{0, 0}, {0, 1}, {1, 0}, {1, 1}},
35 {{1, 0}, {1, 1}, {0, 0}, {0, 1}}
36 };
37 static const float indices[6][6] = {
38 {0, 3, 2, 0, 1, 3},
39 {0, 3, 1, 0, 2, 3},
40 {0, 3, 2, 0, 1, 3},
41 {0, 3, 1, 0, 2, 3},
42 {0, 3, 2, 0, 1, 3},
43 {0, 3, 1, 0, 2, 3}
44 };
45 static const float flipped[6][6] = {
46 {0, 1, 2, 1, 3, 2},
47 {0, 2, 1, 2, 3, 1},
48 {0, 1, 2, 1, 3, 2},
49 {0, 2, 1, 2, 3, 1},
50 {0, 1, 2, 1, 3, 2},
51 {0, 2, 1, 2, 3, 1}
52 };
53 float *d = data;
54 float s = 0.0625;
55 float a = 0 + 1 / 2048.0;
56 float b = s - 1 / 2048.0;
57 int faces[6] = {left, right, top, bottom, front, back};
58 int tiles[6] = {wleft, wright, wtop, wbottom, wfront, wback};
59 for (int i = 0; i < 6; i++) {
60 if (faces[i] == 0) {
61 continue;
62 }
63 float du = (tiles[i] % 16) * s;
64 float dv = (tiles[i] / 16) * s;
65 int flip = ao[i][0] + ao[i][3] > ao[i][1] + ao[i][2];
66 for (int v = 0; v < 6; v++) {
67 int j = flip ? flipped[i][v] : indices[i][v];
68 *(d++) = x + n * positions[i][j][0];
69 *(d++) = y + n * positions[i][j][1];
70 *(d++) = z + n * positions[i][j][2];
71 *(d++) = normals[i][0];
72 *(d++) = normals[i][1];
73 *(d++) = normals[i][2];
74 *(d++) = du + (uvs[i][j][0] ? b : a);
75 *(d++) = dv + (uvs[i][j][1] ? b : a);
76 *(d++) = ao[i][j];
77 *(d++) = light[i][j];
78 }
79 }
80 }
81
make_cube(float * data,float ao[6][4],float light[6][4],int left,int right,int top,int bottom,int front,int back,float x,float y,float z,float n,int w)82 void make_cube(
83 float *data, float ao[6][4], float light[6][4],
84 int left, int right, int top, int bottom, int front, int back,
85 float x, float y, float z, float n, int w)
86 {
87 int wleft = blocks[w][0];
88 int wright = blocks[w][1];
89 int wtop = blocks[w][2];
90 int wbottom = blocks[w][3];
91 int wfront = blocks[w][4];
92 int wback = blocks[w][5];
93 make_cube_faces(
94 data, ao, light,
95 left, right, top, bottom, front, back,
96 wleft, wright, wtop, wbottom, wfront, wback,
97 x, y, z, n);
98 }
99
make_plant(float * data,float ao,float light,float px,float py,float pz,float n,int w,float rotation)100 void make_plant(
101 float *data, float ao, float light,
102 float px, float py, float pz, float n, int w, float rotation)
103 {
104 static const float positions[4][4][3] = {
105 {{ 0, -1, -1}, { 0, -1, +1}, { 0, +1, -1}, { 0, +1, +1}},
106 {{ 0, -1, -1}, { 0, -1, +1}, { 0, +1, -1}, { 0, +1, +1}},
107 {{-1, -1, 0}, {-1, +1, 0}, {+1, -1, 0}, {+1, +1, 0}},
108 {{-1, -1, 0}, {-1, +1, 0}, {+1, -1, 0}, {+1, +1, 0}}
109 };
110 static const float normals[4][3] = {
111 {-1, 0, 0},
112 {+1, 0, 0},
113 {0, 0, -1},
114 {0, 0, +1}
115 };
116 static const float uvs[4][4][2] = {
117 {{0, 0}, {1, 0}, {0, 1}, {1, 1}},
118 {{1, 0}, {0, 0}, {1, 1}, {0, 1}},
119 {{0, 0}, {0, 1}, {1, 0}, {1, 1}},
120 {{1, 0}, {1, 1}, {0, 0}, {0, 1}}
121 };
122 static const float indices[4][6] = {
123 {0, 3, 2, 0, 1, 3},
124 {0, 3, 1, 0, 2, 3},
125 {0, 3, 2, 0, 1, 3},
126 {0, 3, 1, 0, 2, 3}
127 };
128 float *d = data;
129 float s = 0.0625;
130 float a = 0;
131 float b = s;
132 float du = (plants[w] % 16) * s;
133 float dv = (plants[w] / 16) * s;
134 for (int i = 0; i < 4; i++) {
135 for (int v = 0; v < 6; v++) {
136 int j = indices[i][v];
137 *(d++) = n * positions[i][j][0];
138 *(d++) = n * positions[i][j][1];
139 *(d++) = n * positions[i][j][2];
140 *(d++) = normals[i][0];
141 *(d++) = normals[i][1];
142 *(d++) = normals[i][2];
143 *(d++) = du + (uvs[i][j][0] ? b : a);
144 *(d++) = dv + (uvs[i][j][1] ? b : a);
145 *(d++) = ao;
146 *(d++) = light;
147 }
148 }
149 float ma[16];
150 float mb[16];
151 mat_identity(ma);
152 mat_rotate(mb, 0, 1, 0, RADIANS(rotation));
153 mat_multiply(ma, mb, ma);
154 mat_apply(data, ma, 24, 3, 10);
155 mat_translate(mb, px, py, pz);
156 mat_multiply(ma, mb, ma);
157 mat_apply(data, ma, 24, 0, 10);
158 }
159
make_player(float * data,float x,float y,float z,float rx,float ry)160 void make_player(
161 float *data,
162 float x, float y, float z, float rx, float ry)
163 {
164 float ao[6][4] = {0};
165 float light[6][4] = {
166 {0.8, 0.8, 0.8, 0.8},
167 {0.8, 0.8, 0.8, 0.8},
168 {0.8, 0.8, 0.8, 0.8},
169 {0.8, 0.8, 0.8, 0.8},
170 {0.8, 0.8, 0.8, 0.8},
171 {0.8, 0.8, 0.8, 0.8}
172 };
173 make_cube_faces(
174 data, ao, light,
175 1, 1, 1, 1, 1, 1,
176 226, 224, 241, 209, 225, 227,
177 0, 0, 0, 0.4);
178 float ma[16];
179 float mb[16];
180 mat_identity(ma);
181 mat_rotate(mb, 0, 1, 0, rx);
182 mat_multiply(ma, mb, ma);
183 mat_rotate(mb, cosf(rx), 0, sinf(rx), -ry);
184 mat_multiply(ma, mb, ma);
185 mat_apply(data, ma, 36, 3, 10);
186 mat_translate(mb, x, y, z);
187 mat_multiply(ma, mb, ma);
188 mat_apply(data, ma, 36, 0, 10);
189 }
190
make_cube_wireframe(float * data,float x,float y,float z,float n)191 void make_cube_wireframe(float *data, float x, float y, float z, float n) {
192 static const float positions[8][3] = {
193 {-1, -1, -1},
194 {-1, -1, +1},
195 {-1, +1, -1},
196 {-1, +1, +1},
197 {+1, -1, -1},
198 {+1, -1, +1},
199 {+1, +1, -1},
200 {+1, +1, +1}
201 };
202 static const int indices[24] = {
203 0, 1, 0, 2, 0, 4, 1, 3,
204 1, 5, 2, 3, 2, 6, 3, 7,
205 4, 5, 4, 6, 5, 7, 6, 7
206 };
207 float *d = data;
208 for (int i = 0; i < 24; i++) {
209 int j = indices[i];
210 *(d++) = x + n * positions[j][0];
211 *(d++) = y + n * positions[j][1];
212 *(d++) = z + n * positions[j][2];
213 }
214 }
215
make_character(float * data,float x,float y,float n,float m,char c)216 void make_character(
217 float *data,
218 float x, float y, float n, float m, char c)
219 {
220 float *d = data;
221 float s = 0.0625;
222 float a = s;
223 float b = s * 2;
224 int w = c - 32;
225 float du = (w % 16) * a;
226 float dv = 1 - (w / 16) * b - b;
227 *(d++) = x - n; *(d++) = y - m;
228 *(d++) = du + 0; *(d++) = dv;
229 *(d++) = x + n; *(d++) = y - m;
230 *(d++) = du + a; *(d++) = dv;
231 *(d++) = x + n; *(d++) = y + m;
232 *(d++) = du + a; *(d++) = dv + b;
233 *(d++) = x - n; *(d++) = y - m;
234 *(d++) = du + 0; *(d++) = dv;
235 *(d++) = x + n; *(d++) = y + m;
236 *(d++) = du + a; *(d++) = dv + b;
237 *(d++) = x - n; *(d++) = y + m;
238 *(d++) = du + 0; *(d++) = dv + b;
239 }
240
make_character_3d(float * data,float x,float y,float z,float n,int face,char c)241 void make_character_3d(
242 float *data, float x, float y, float z, float n, int face, char c)
243 {
244 static const float positions[8][6][3] = {
245 {{0, -2, -1}, {0, +2, +1}, {0, +2, -1},
246 {0, -2, -1}, {0, -2, +1}, {0, +2, +1}},
247 {{0, -2, -1}, {0, +2, +1}, {0, -2, +1},
248 {0, -2, -1}, {0, +2, -1}, {0, +2, +1}},
249 {{-1, -2, 0}, {+1, +2, 0}, {+1, -2, 0},
250 {-1, -2, 0}, {-1, +2, 0}, {+1, +2, 0}},
251 {{-1, -2, 0}, {+1, -2, 0}, {+1, +2, 0},
252 {-1, -2, 0}, {+1, +2, 0}, {-1, +2, 0}},
253 {{-1, 0, +2}, {+1, 0, +2}, {+1, 0, -2},
254 {-1, 0, +2}, {+1, 0, -2}, {-1, 0, -2}},
255 {{-2, 0, +1}, {+2, 0, -1}, {-2, 0, -1},
256 {-2, 0, +1}, {+2, 0, +1}, {+2, 0, -1}},
257 {{+1, 0, +2}, {-1, 0, -2}, {-1, 0, +2},
258 {+1, 0, +2}, {+1, 0, -2}, {-1, 0, -2}},
259 {{+2, 0, -1}, {-2, 0, +1}, {+2, 0, +1},
260 {+2, 0, -1}, {-2, 0, -1}, {-2, 0, +1}}
261 };
262 static const float uvs[8][6][2] = {
263 {{0, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}, {1, 1}},
264 {{1, 0}, {0, 1}, {0, 0}, {1, 0}, {1, 1}, {0, 1}},
265 {{1, 0}, {0, 1}, {0, 0}, {1, 0}, {1, 1}, {0, 1}},
266 {{0, 0}, {1, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 1}},
267 {{0, 0}, {1, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 1}},
268 {{0, 1}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}},
269 {{0, 1}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}},
270 {{0, 1}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}}
271 };
272 static const float offsets[8][3] = {
273 {-1, 0, 0}, {+1, 0, 0}, {0, 0, -1}, {0, 0, +1},
274 {0, +1, 0}, {0, +1, 0}, {0, +1, 0}, {0, +1, 0},
275 };
276 float *d = data;
277 float s = 0.0625;
278 float pu = s / 5;
279 float pv = s / 2.5;
280 float u1 = pu;
281 float v1 = pv;
282 float u2 = s - pu;
283 float v2 = s * 2 - pv;
284 float p = 0.5;
285 int w = c - 32;
286 float du = (w % 16) * s;
287 float dv = 1 - (w / 16 + 1) * s * 2;
288 x += p * offsets[face][0];
289 y += p * offsets[face][1];
290 z += p * offsets[face][2];
291 for (int i = 0; i < 6; i++) {
292 *(d++) = x + n * positions[face][i][0];
293 *(d++) = y + n * positions[face][i][1];
294 *(d++) = z + n * positions[face][i][2];
295 *(d++) = du + (uvs[face][i][0] ? u2 : u1);
296 *(d++) = dv + (uvs[face][i][1] ? v2 : v1);
297 }
298 }
299
_make_sphere(float * data,float r,int detail,float * a,float * b,float * c,float * ta,float * tb,float * tc)300 int _make_sphere(
301 float *data, float r, int detail,
302 float *a, float *b, float *c,
303 float *ta, float *tb, float *tc)
304 {
305 if (detail == 0) {
306 float *d = data;
307 *(d++) = a[0] * r; *(d++) = a[1] * r; *(d++) = a[2] * r;
308 *(d++) = a[0]; *(d++) = a[1]; *(d++) = a[2];
309 *(d++) = ta[0]; *(d++) = ta[1];
310 *(d++) = b[0] * r; *(d++) = b[1] * r; *(d++) = b[2] * r;
311 *(d++) = b[0]; *(d++) = b[1]; *(d++) = b[2];
312 *(d++) = tb[0]; *(d++) = tb[1];
313 *(d++) = c[0] * r; *(d++) = c[1] * r; *(d++) = c[2] * r;
314 *(d++) = c[0]; *(d++) = c[1]; *(d++) = c[2];
315 *(d++) = tc[0]; *(d++) = tc[1];
316 return 1;
317 }
318 else {
319 float ab[3], ac[3], bc[3];
320 for (int i = 0; i < 3; i++) {
321 ab[i] = (a[i] + b[i]) / 2;
322 ac[i] = (a[i] + c[i]) / 2;
323 bc[i] = (b[i] + c[i]) / 2;
324 }
325 normalize(ab + 0, ab + 1, ab + 2);
326 normalize(ac + 0, ac + 1, ac + 2);
327 normalize(bc + 0, bc + 1, bc + 2);
328 float tab[2], tac[2], tbc[2];
329 tab[0] = 0; tab[1] = 1 - acosf(ab[1]) / PI;
330 tac[0] = 0; tac[1] = 1 - acosf(ac[1]) / PI;
331 tbc[0] = 0; tbc[1] = 1 - acosf(bc[1]) / PI;
332 int total = 0;
333 int n;
334 n = _make_sphere(data, r, detail - 1, a, ab, ac, ta, tab, tac);
335 total += n; data += n * 24;
336 n = _make_sphere(data, r, detail - 1, b, bc, ab, tb, tbc, tab);
337 total += n; data += n * 24;
338 n = _make_sphere(data, r, detail - 1, c, ac, bc, tc, tac, tbc);
339 total += n; data += n * 24;
340 n = _make_sphere(data, r, detail - 1, ab, bc, ac, tab, tbc, tac);
341 total += n; data += n * 24;
342 return total;
343 }
344 }
345
make_sphere(float * data,float r,int detail)346 void make_sphere(float *data, float r, int detail) {
347 // detail, triangles, floats
348 // 0, 8, 192
349 // 1, 32, 768
350 // 2, 128, 3072
351 // 3, 512, 12288
352 // 4, 2048, 49152
353 // 5, 8192, 196608
354 // 6, 32768, 786432
355 // 7, 131072, 3145728
356 static int indices[8][3] = {
357 {4, 3, 0}, {1, 4, 0},
358 {3, 4, 5}, {4, 1, 5},
359 {0, 3, 2}, {0, 2, 1},
360 {5, 2, 3}, {5, 1, 2}
361 };
362 static float positions[6][3] = {
363 { 0, 0,-1}, { 1, 0, 0},
364 { 0,-1, 0}, {-1, 0, 0},
365 { 0, 1, 0}, { 0, 0, 1}
366 };
367 static float uvs[6][3] = {
368 {0, 0.5}, {0, 0.5},
369 {0, 0}, {0, 0.5},
370 {0, 1}, {0, 0.5}
371 };
372 int total = 0;
373 for (int i = 0; i < 8; i++) {
374 int n = _make_sphere(
375 data, r, detail,
376 positions[indices[i][0]],
377 positions[indices[i][1]],
378 positions[indices[i][2]],
379 uvs[indices[i][0]],
380 uvs[indices[i][1]],
381 uvs[indices[i][2]]);
382 total += n; data += n * 24;
383 }
384 }
385