GCC Code Coverage Report


Directory: ./
File: submodules/raylib/src/external/vox_loader.h
Date: 2023-09-29 04:53:15
Exec Total Coverage
Lines: 0 185 0.0%
Branches: 0 78 0.0%

Line Branch Exec Source
1 /*
2 The MIT License (MIT)
3
4 Copyright (c) 2021 Johann Nadalutti.
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23
24
25 vox_loader - v1.01
26 no warranty implied; use at your own risk
27
28 Do this:
29 #define VOX_LOADER_INCLUDE__H
30 before you include this file in* one* C or C++ file to create the implementation.
31
32 // i.e. it should look like this:
33 #include ...
34 #include ...
35 #include ...
36 #define VOX_LOADER_INCLUDE__H
37 #include "vox_loader.h"
38
39 revision history:
40 1.00 (2021-09-03) first released version
41 1.01 (2021-09-07) Support custom memory allocators
42 Removed Raylib dependencies
43 Changed Vox_LoadFileName to Vox_LoadFromMemory
44 1.02 (2021-09-10) @raysan5: Reviewed some formating
45 1.03 (2021-10-02) @catmanl: Reduce warnings on gcc
46 1.04 (2021-10-17) @warzes: Fixing the error of loading VOX models
47
48 */
49
50 #ifndef VOX_LOADER_H
51 #define VOX_LOADER_H
52
53 // Allow custom memory allocators
54 #ifndef VOX_MALLOC
55 #define VOX_MALLOC(sz) malloc(sz)
56 #endif
57 #ifndef VOX_CALLOC
58 #define VOX_CALLOC(n,sz) calloc(n,sz)
59 #endif
60 #ifndef VOX_REALLOC
61 #define VOX_REALLOC(n,sz) realloc(n,sz)
62 #endif
63 #ifndef VOX_FREE
64 #define VOX_FREE(p) free(p)
65 #endif
66
67 #define VOX_SUCCESS (0)
68 #define VOX_ERROR_FILE_NOT_FOUND (-1)
69 #define VOX_ERROR_INVALID_FORMAT (-2)
70 #define VOX_ERROR_FILE_VERSION_NOT_MATCH (-3)
71
72 // VoxColor, 4 components, R8G8B8A8 (32bit)
73 typedef struct {
74 unsigned char r, g, b, a;
75 } VoxColor;
76
77 // VoxVector3, 3 components
78 typedef struct {
79 float x, y, z;
80 } VoxVector3;
81
82 typedef struct {
83 VoxVector3* array;
84 int used, size;
85 } ArrayVector3;
86
87 typedef struct {
88 VoxColor* array;
89 int used, size;
90 } ArrayColor;
91
92 typedef struct {
93 unsigned short* array;
94 int used, size;
95 } ArrayUShort;
96
97 // A chunk that contain voxels
98 typedef struct {
99 unsigned char* m_array; //If Sparse != null
100 int arraySize; //Size for m_array in bytes (DEBUG ONLY)
101 } CubeChunk3D;
102
103 // Array for voxels
104 // Array is divised into chunks of CHUNKSIZE*CHUNKSIZE*CHUNKSIZE voxels size
105 typedef struct {
106 // Array size in voxels
107 int sizeX;
108 int sizeY;
109 int sizeZ;
110
111 // Chunks size into array (array is divised into chunks)
112 int chunksSizeX;
113 int chunksSizeY;
114 int chunksSizeZ;
115
116 // Chunks array
117 CubeChunk3D* m_arrayChunks;
118 int arrayChunksSize; // Size for m_arrayChunks in bytes (DEBUG ONLY)
119
120 int ChunkFlattenOffset;
121 int chunksAllocated;
122 int chunksTotal;
123
124 // Arrays for mesh build
125 ArrayVector3 vertices;
126 ArrayUShort indices;
127 ArrayColor colors;
128
129 //Palette for voxels
130 VoxColor palette[256];
131
132 } VoxArray3D;
133
134 #if defined(__cplusplus)
135 extern "C" { // Prevents name mangling of functions
136 #endif
137
138 // Functions
139 int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArray3D* pvoxarray);
140 void Vox_FreeArrays(VoxArray3D* voxarray);
141
142 #ifdef __cplusplus
143 }
144 #endif
145
146 #endif // VOX_LOADER_H
147 //// end header file /////////////////////////////////////////////////////
148
149
150 /////////////////////////////////////////////////////////////////////////////////////////////
151 /////////////////////////////////////////////////////////////////////////////////////////////
152 // Implementation
153 /////////////////////////////////////////////////////////////////////////////////////////////
154 /////////////////////////////////////////////////////////////////////////////////////////////
155
156 #ifdef VOX_LOADER_IMPLEMENTATION
157
158 #include <string.h>
159 #include <stdlib.h>
160
161 /////////////////////////////////////////////////////////////////////////////////////////////
162 // ArrayUShort helper
163 /////////////////////////////////////////////////////////////////////////////////////////////
164
165 static void initArrayUShort(ArrayUShort* a, int initialSize)
166 {
167 ✗ a->array = VOX_MALLOC(initialSize * sizeof(unsigned short));
168 ✗ a->used = 0;
169 ✗ a->size = initialSize;
170 }
171
172 ✗ static void insertArrayUShort(ArrayUShort* a, unsigned short element)
173 {
174 ✗ if (a->used == a->size)
175 {
176 ✗ a->size *= 2;
177 ✗ a->array = VOX_REALLOC(a->array, a->size * sizeof(unsigned short));
178 }
179 ✗ a->array[a->used++] = element;
180 }
181
182 static void freeArrayUShort(ArrayUShort* a)
183 {
184 ✗ VOX_FREE(a->array);
185 ✗ a->array = NULL;
186 ✗ a->used = a->size = 0;
187 }
188
189
190 /////////////////////////////////////////////////////////////////////////////////////////////
191 // ArrayVector3 helper
192 /////////////////////////////////////////////////////////////////////////////////////////////
193
194 static void initArrayVector3(ArrayVector3* a, int initialSize)
195 {
196 ✗ a->array = VOX_MALLOC(initialSize * sizeof(VoxVector3));
197 ✗ a->used = 0;
198 ✗ a->size = initialSize;
199 }
200
201 ✗ static void insertArrayVector3(ArrayVector3* a, VoxVector3 element)
202 {
203 ✗ if (a->used == a->size)
204 {
205 ✗ a->size *= 2;
206 ✗ a->array = VOX_REALLOC(a->array, a->size * sizeof(VoxVector3));
207 }
208 ✗ a->array[a->used++] = element;
209 }
210
211 static void freeArrayVector3(ArrayVector3* a)
212 {
213 ✗ VOX_FREE(a->array);
214 ✗ a->array = NULL;
215 ✗ a->used = a->size = 0;
216 }
217
218 /////////////////////////////////////////////////////////////////////////////////////////////
219 // ArrayColor helper
220 /////////////////////////////////////////////////////////////////////////////////////////////
221
222 static void initArrayColor(ArrayColor* a, int initialSize)
223 {
224 ✗ a->array = VOX_MALLOC(initialSize * sizeof(VoxColor));
225 ✗ a->used = 0;
226 ✗ a->size = initialSize;
227 }
228
229 ✗ static void insertArrayColor(ArrayColor* a, VoxColor element)
230 {
231 ✗ if (a->used == a->size)
232 {
233 ✗ a->size *= 2;
234 ✗ a->array = VOX_REALLOC(a->array, a->size * sizeof(VoxColor));
235 }
236 ✗ a->array[a->used++] = element;
237 }
238
239 static void freeArrayColor(ArrayColor* a)
240 {
241 ✗ VOX_FREE(a->array);
242 ✗ a->array = NULL;
243 ✗ a->used = a->size = 0;
244 }
245
246
247 /////////////////////////////////////////////////////////////////////////////////////////////
248 // Vox Loader
249 /////////////////////////////////////////////////////////////////////////////////////////////
250
251 #define CHUNKSIZE 16 // chunk size (CHUNKSIZE*CHUNKSIZE*CHUNKSIZE) in voxels
252 #define CHUNKSIZE_OPSHIFT 4 // 1<<4=16 -> Warning depend of CHUNKSIZE
253 #define CHUNK_FLATTENOFFSET_OPSHIFT 8 // Warning depend of CHUNKSIZE
254
255 //
256 // used right handed system and CCW face
257 //
258 // indexes for voxelcoords, per face orientation
259 //
260
261 //# Y
262 //# |
263 //# o----X
264 //# /
265 //# Z 2------------3
266 //# /| /|
267 //# 6------------7 |
268 //# | | | |
269 //# |0 ----------|- 1
270 //# |/ |/
271 //# 4------------5
272
273 //
274 // CCW
275 const int fv[6][4] = {
276 {0, 2, 6, 4 }, //-X
277 {5, 7, 3, 1 }, //+X
278 {0, 4, 5, 1 }, //-y
279 {6, 2, 3, 7 }, //+y
280 {1, 3, 2, 0 }, //-Z
281 {4, 6, 7, 5 } //+Z
282 };
283
284 const VoxVector3 SolidVertex[] = {
285 {0, 0, 0}, //0
286 {1, 0, 0}, //1
287 {0, 1, 0}, //2
288 {1, 1, 0}, //3
289 {0, 0, 1}, //4
290 {1, 0, 1}, //5
291 {0, 1, 1}, //6
292 {1, 1, 1} //7
293 };
294
295 // Allocated VoxArray3D size
296 ✗ static void Vox_AllocArray(VoxArray3D* pvoxarray, int _sx, int _sy, int _sz)
297 {
298 ✗ int sx = _sx + ((CHUNKSIZE - (_sx % CHUNKSIZE)) % CHUNKSIZE);
299 ✗ int sy = _sy + ((CHUNKSIZE - (_sy % CHUNKSIZE)) % CHUNKSIZE);
300 ✗ int sz = _sz + ((CHUNKSIZE - (_sz % CHUNKSIZE)) % CHUNKSIZE);
301
302 ✗ int chx = sx >> CHUNKSIZE_OPSHIFT; //Chunks Count in X
303 ✗ int chy = sy >> CHUNKSIZE_OPSHIFT; //Chunks Count in Y
304 ✗ int chz = sz >> CHUNKSIZE_OPSHIFT; //Chunks Count in Z
305
306 //VoxArray3D* parray = (VoxArray3D*)VOX_MALLOC(sizeof(VoxArray3D));
307 ✗ pvoxarray->sizeX = sx;
308 ✗ pvoxarray->sizeY = sy;
309 ✗ pvoxarray->sizeZ = sz;
310
311 ✗ pvoxarray->chunksSizeX = chx;
312 ✗ pvoxarray->chunksSizeY = chy;
313 ✗ pvoxarray->chunksSizeZ = chz;
314
315 ✗ pvoxarray->ChunkFlattenOffset = (chy * chz); //m_arrayChunks[(x * (sy*sz)) + (z * sy) + y]
316
317 // Alloc chunks array
318 ✗ int size = sizeof(CubeChunk3D) * chx * chy * chz;
319 ✗ pvoxarray->m_arrayChunks = VOX_MALLOC(size);
320 ✗ pvoxarray->arrayChunksSize = size;
321
322 // Init chunks array
323 ✗ size = chx * chy * chz;
324 ✗ pvoxarray->chunksTotal = size;
325 ✗ pvoxarray->chunksAllocated = 0;
326
327 ✗ for (int i = 0; i < size; i++)
328 {
329 ✗ pvoxarray->m_arrayChunks[i].m_array = 0;
330 ✗ pvoxarray->m_arrayChunks[i].arraySize = 0;
331 }
332 }
333
334 // Set voxel ID from its position into VoxArray3D
335 ✗ static void Vox_SetVoxel(VoxArray3D* pvoxarray, int x, int y, int z, unsigned char id)
336 {
337 // Get chunk from array pos
338 ✗ int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
339 ✗ int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
340 ✗ int chZ = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE;
341 ✗ int offset = (chX * pvoxarray->ChunkFlattenOffset) + (chZ * pvoxarray->chunksSizeY) + chY;
342
343 //if (offset > voxarray->arrayChunksSize)
344 //{
345 // TraceLog(LOG_ERROR, "Out of array");
346 //}
347
348 ✗ CubeChunk3D* chunk = &pvoxarray->m_arrayChunks[offset];
349
350 // Set Chunk
351 chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE);
352 chY = y - (chY << CHUNKSIZE_OPSHIFT); //y - (by * CHUNKSIZE);
353 chZ = z - (chZ << CHUNKSIZE_OPSHIFT); //z - (bz * CHUNKSIZE);
354
355 ✗ if (chunk->m_array == 0)
356 {
357 int size = CHUNKSIZE * CHUNKSIZE * CHUNKSIZE;
358 ✗ chunk->m_array = VOX_MALLOC(size);
359 ✗ chunk->arraySize = size;
360 memset(chunk->m_array, 0, size);
361
362 ✗ pvoxarray->chunksAllocated++;
363 }
364
365 ✗ offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY;
366
367 //if (offset > chunk->arraySize)
368 //{
369 // TraceLog(LOG_ERROR, "Out of array");
370 //}
371
372 ✗ chunk->m_array[offset] = id;
373 }
374
375 // Get voxel ID from its position into VoxArray3D
376 ✗ static unsigned char Vox_GetVoxel(VoxArray3D* pvoxarray, int x, int y, int z)
377 {
378 ✗ if (x < 0 || y < 0 || z < 0) return 0;
379
380 ✗ if (x >= pvoxarray->sizeX || y >= pvoxarray->sizeY || z >= pvoxarray->sizeZ) return 0;
381
382 // Get chunk from array pos
383 ✗ int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
384 ✗ int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
385 ✗ int chZ = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE;
386 ✗ int offset = (chX * pvoxarray->ChunkFlattenOffset) + (chZ * pvoxarray->chunksSizeY) + chY;
387
388 //if (offset > voxarray->arrayChunksSize)
389 //{
390 // TraceLog(LOG_ERROR, "Out of array");
391 //}
392
393 ✗ CubeChunk3D* chunk = &pvoxarray->m_arrayChunks[offset];
394
395 // Set Chunk
396 chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE);
397 chY = y - (chY << CHUNKSIZE_OPSHIFT); //y - (by * CHUNKSIZE);
398 chZ = z - (chZ << CHUNKSIZE_OPSHIFT); //z - (bz * CHUNKSIZE);
399
400 ✗ if (chunk->m_array == 0)
401 {
402 return 0;
403 }
404
405 ✗ offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY;
406
407 //if (offset > chunk->arraySize)
408 //{
409 // TraceLog(LOG_ERROR, "Out of array");
410 //}
411 ✗ return chunk->m_array[offset];
412
413 }
414
415 // Calc visibles faces from a voxel position
416 ✗ static unsigned char Vox_CalcFacesVisible(VoxArray3D* pvoxArray, int cx, int cy, int cz)
417 {
418 ✗ unsigned char idXm1 = Vox_GetVoxel(pvoxArray, cx - 1, cy, cz);
419 ✗ unsigned char idXp1 = Vox_GetVoxel(pvoxArray, cx + 1, cy, cz);
420
421 ✗ unsigned char idYm1 = Vox_GetVoxel(pvoxArray, cx, cy - 1, cz);
422 ✗ unsigned char idYp1 = Vox_GetVoxel(pvoxArray, cx, cy + 1, cz);
423
424 ✗ unsigned char idZm1 = Vox_GetVoxel(pvoxArray, cx, cy, cz - 1);
425 ✗ unsigned char idZp1 = Vox_GetVoxel(pvoxArray, cx, cy, cz + 1);
426
427 unsigned char byVFMask = 0;
428
429 //#-x
430 ✗ if (idXm1 == 0) byVFMask |= (1 << 0);
431
432 //#+x
433 ✗ if (idXp1 == 0) byVFMask |= (1 << 1);
434
435 //#-y
436 ✗ if (idYm1 == 0) byVFMask |= (1 << 2);
437
438 //#+y
439 ✗ if (idYp1 == 0) byVFMask |= (1 << 3);
440
441 //#-z
442 ✗ if (idZm1 == 0) byVFMask |= (1 << 4);
443
444 //#+z
445 ✗ if (idZp1 == 0) byVFMask |= (1 << 5);
446
447 ✗ return byVFMask;
448 }
449
450 // Get a vertex position from a voxel's corner
451 static VoxVector3 Vox_GetVertexPosition(int _wcx, int _wcy, int _wcz, int _nNumVertex)
452 {
453 float scale = 0.25;
454
455 ✗ VoxVector3 vtx = SolidVertex[_nNumVertex];
456 ✗ vtx.x = (vtx.x + _wcx) * scale;
457 ✗ vtx.y = (vtx.y + _wcy) * scale;
458 ✗ vtx.z = (vtx.z + _wcz) * scale;
459
460 return vtx;
461 }
462
463 // Build a voxel vertices/colors/indices
464 ✗ static void Vox_Build_Voxel(VoxArray3D* pvoxArray, int x, int y, int z, int matID)
465 {
466 ✗ unsigned char byVFMask = Vox_CalcFacesVisible(pvoxArray, x, y, z);
467
468 ✗ if (byVFMask == 0) return;
469
470 int i, j;
471 VoxVector3 vertComputed[8];
472 int bVertexComputed[8];
473 memset(vertComputed, 0, sizeof(vertComputed));
474 memset(bVertexComputed, 0, sizeof(bVertexComputed));
475
476 //For each Cube's faces
477 ✗ for (i = 0; i < 6; i++) // 6 faces
478 {
479 ✗ if ((byVFMask & (1 << i)) != 0) //If face is visible
480 {
481 ✗ for (j = 0; j < 4; j++) // 4 corners
482 {
483 ✗ int nNumVertex = fv[i][j]; //Face,Corner
484 ✗ if (bVertexComputed[nNumVertex] == 0) //if never calc
485 {
486 ✗ bVertexComputed[nNumVertex] = 1;
487 ✗ vertComputed[nNumVertex] = Vox_GetVertexPosition(x, y, z, nNumVertex);
488 }
489 }
490 }
491 }
492
493 //Add face
494 ✗ for (i = 0; i < 6; i++)// 6 faces
495 {
496 ✗ if ((byVFMask & (1 << i)) == 0)
497 ✗ continue; //Face invisible
498
499 ✗ int v0 = fv[i][0]; //Face, Corner
500 ✗ int v1 = fv[i][1]; //Face, Corner
501 ✗ int v2 = fv[i][2]; //Face, Corner
502 ✗ int v3 = fv[i][3]; //Face, Corner
503
504 //Arrays
505 ✗ int idx = pvoxArray->vertices.used;
506 ✗ insertArrayVector3(&pvoxArray->vertices, vertComputed[v0]);
507 ✗ insertArrayVector3(&pvoxArray->vertices, vertComputed[v1]);
508 ✗ insertArrayVector3(&pvoxArray->vertices, vertComputed[v2]);
509 ✗ insertArrayVector3(&pvoxArray->vertices, vertComputed[v3]);
510
511 ✗ VoxColor col = pvoxArray->palette[matID];
512
513 ✗ insertArrayColor(&pvoxArray->colors, col);
514 ✗ insertArrayColor(&pvoxArray->colors, col);
515 ✗ insertArrayColor(&pvoxArray->colors, col);
516 ✗ insertArrayColor(&pvoxArray->colors, col);
517
518
519 //v0 - v1 - v2, v0 - v2 - v3
520 ✗ insertArrayUShort(&pvoxArray->indices, idx + 0);
521 ✗ insertArrayUShort(&pvoxArray->indices, idx + 2);
522 ✗ insertArrayUShort(&pvoxArray->indices, idx + 1);
523
524 ✗ insertArrayUShort(&pvoxArray->indices, idx + 0);
525 ✗ insertArrayUShort(&pvoxArray->indices, idx + 3);
526 ✗ insertArrayUShort(&pvoxArray->indices, idx + 2);
527 }
528 }
529
530 // MagicaVoxel *.vox file format Loader
531 ✗ int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArray3D* pvoxarray)
532 {
533 //////////////////////////////////////////////////
534 // Read VOX file
535 // 4 bytes: magic number ('V' 'O' 'X' 'space')
536 // 4 bytes: version number (current version is 150)
537
538 // @raysan5: Reviewed (unsigned long) -> (unsigned int), possible issue with Ubuntu 18.04 64bit
539
540 // @raysan5: reviewed signature loading
541
542 unsigned char* fileData = pvoxData;
543 unsigned char* fileDataPtr = fileData;
544 ✗ unsigned char* endfileDataPtr = fileData + voxDataSize;
545
546 ✗ if (strncmp((char*)fileDataPtr, "VOX ", 4) != 0)
547 {
548 return VOX_ERROR_INVALID_FORMAT; //"Not an MagicaVoxel File format"
549 }
550
551 fileDataPtr += 4;
552
553 // @raysan5: reviewed version loading
554 unsigned int version = 0;
555 ✗ version = ((unsigned int*)fileDataPtr)[0];
556 ✗ fileDataPtr += 4;
557
558 ✗ if (version != 150 && version != 200)
559 {
560 return VOX_ERROR_FILE_VERSION_NOT_MATCH; //"MagicaVoxel version doesn't match"
561 }
562
563
564 // header
565 //4 bytes: chunk id
566 //4 bytes: size of chunk contents (n)
567 //4 bytes: total size of children chunks(m)
568
569 //// chunk content
570 //n bytes: chunk contents
571
572 //// children chunks : m bytes
573 //{ child chunk 0 }
574 //{ child chunk 1 }
575 unsigned int sizeX, sizeY, sizeZ;
576 sizeX = sizeY = sizeZ = 0;
577 unsigned int numVoxels = 0;
578
579 ✗ while (fileDataPtr < endfileDataPtr)
580 {
581 char szChunkName[5];
582 memcpy(szChunkName, fileDataPtr, 4);
583 ✗ szChunkName[4] = 0;
584 fileDataPtr += 4;
585
586 ✗ unsigned int chunkSize = *((unsigned int*)fileDataPtr);
587 fileDataPtr += sizeof(unsigned int);
588
589 //unsigned long chunkTotalChildSize = *((unsigned long*)fileDataPtr);
590 ✗ fileDataPtr += sizeof(unsigned int);
591
592 ✗ if (strcmp(szChunkName, "SIZE") == 0)
593 {
594 //(4 bytes x 3 : x, y, z )
595 ✗ sizeX = *((unsigned int*)fileDataPtr);
596 fileDataPtr += sizeof(unsigned int);
597
598 ✗ sizeY = *((unsigned int*)fileDataPtr);
599 fileDataPtr += sizeof(unsigned int);
600
601 ✗ sizeZ = *((unsigned int*)fileDataPtr);
602 ✗ fileDataPtr += sizeof(unsigned int);
603
604 //Alloc vox array
605 ✗ Vox_AllocArray(pvoxarray, sizeX, sizeZ, sizeY); //Reverse Y<>Z for left to right handed system
606 }
607 ✗ else if (strcmp(szChunkName, "XYZI") == 0)
608 {
609 unsigned char vx, vy, vz, vi;
610
611 //(numVoxels : 4 bytes )
612 //(each voxel: 1 byte x 4 : x, y, z, colorIndex ) x numVoxels
613 ✗ numVoxels = *((unsigned int*)fileDataPtr);
614 ✗ fileDataPtr += sizeof(unsigned int);
615
616 ✗ while (numVoxels > 0)
617 {
618 ✗ vx = *((unsigned char*)fileDataPtr++);
619 ✗ vy = *((unsigned char*)fileDataPtr++);
620 ✗ vz = *((unsigned char*)fileDataPtr++);
621 ✗ vi = *((unsigned char*)fileDataPtr++);
622
623 ✗ Vox_SetVoxel(pvoxarray, vx, vz, pvoxarray->sizeZ-vy-1, vi); //Reverse Y<>Z for left to right handed system
624
625 ✗ numVoxels--;
626 }
627 }
628 ✗ else if (strcmp(szChunkName, "RGBA") == 0)
629 {
630 VoxColor col;
631
632 //(each pixel: 1 byte x 4 : r, g, b, a ) x 256
633 ✗ for (int i = 0; i < 256 - 1; i++)
634 {
635 ✗ col.r = *((unsigned char*)fileDataPtr++);
636 ✗ col.g = *((unsigned char*)fileDataPtr++);
637 ✗ col.b = *((unsigned char*)fileDataPtr++);
638 ✗ col.a = *((unsigned char*)fileDataPtr++);
639
640 ✗ pvoxarray->palette[i + 1] = col;
641 }
642
643 }
644 else
645 {
646 ✗ fileDataPtr += chunkSize;
647 }
648 }
649
650 //////////////////////////////////////////////////////////
651 // Building Mesh
652 // TODO compute globals indices array
653
654 // Init Arrays
655 initArrayVector3(&pvoxarray->vertices, 3 * 1024);
656 initArrayUShort(&pvoxarray->indices, 3 * 1024);
657 initArrayColor(&pvoxarray->colors, 3 * 1024);
658
659 // Create vertices and indices buffers
660 int x, y, z;
661
662 ✗ for (x = 0; x <= pvoxarray->sizeX; x++)
663 {
664 ✗ for (z = 0; z <= pvoxarray->sizeZ; z++)
665 {
666 ✗ for (y = 0; y <= pvoxarray->sizeY; y++)
667 {
668 ✗ unsigned char matID = Vox_GetVoxel(pvoxarray, x, y, z);
669 ✗ if (matID != 0)
670 ✗ Vox_Build_Voxel(pvoxarray, x, y, z, matID);
671 }
672 }
673 }
674
675 return VOX_SUCCESS;
676 }
677
678 ✗ void Vox_FreeArrays(VoxArray3D* voxarray)
679 {
680 // Free chunks
681 ✗ if (voxarray->m_arrayChunks != 0)
682 {
683 ✗ for (int i = 0; i < voxarray->chunksTotal; i++)
684 {
685 ✗ CubeChunk3D* chunk = &voxarray->m_arrayChunks[i];
686 ✗ if (chunk->m_array != 0)
687 {
688 ✗ chunk->arraySize = 0;
689 ✗ VOX_FREE(chunk->m_array);
690 }
691 }
692
693 ✗ VOX_FREE(voxarray->m_arrayChunks);
694 ✗ voxarray->m_arrayChunks = 0;
695 ✗ voxarray->arrayChunksSize = 0;
696
697 ✗ voxarray->chunksSizeX = voxarray->chunksSizeY = voxarray->chunksSizeZ = 0;
698 ✗ voxarray->chunksTotal = 0;
699 ✗ voxarray->chunksAllocated = 0;
700 ✗ voxarray->ChunkFlattenOffset = 0;
701 ✗ voxarray->sizeX = voxarray->sizeY = voxarray->sizeZ = 0;
702 }
703
704 // Free arrays
705 freeArrayVector3(&voxarray->vertices);
706 freeArrayUShort(&voxarray->indices);
707 freeArrayColor(&voxarray->colors);
708 }
709
710 #endif //VOX_LOADER_IMPLEMENTATION
711