Wise&mystical  1.0
Project about Europe
Loading...
Searching...
No Matches
vox_loader.h
Go to the documentation of this file.
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
39revision 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_TOO_OLD (-3)
71
72// VoxColor, 4 components, R8G8B8A8 (32bit)
73typedef struct {
74 unsigned char r, g, b, a;
75} VoxColor;
76
77// VoxVector3, 3 components
78typedef struct {
79 float x, y, z;
81
82typedef struct {
84 int used, size;
86
87typedef struct {
89 int used, size;
91
92typedef struct {
93 unsigned short* array;
94 int used, size;
96
97// A chunk that contain voxels
98typedef struct {
99 unsigned char* m_array; //If Sparse != null
100 int arraySize; //Size for m_array in bytes (DEBUG ONLY)
102
103// Array for voxels
104// Array is divised into chunks of CHUNKSIZE*CHUNKSIZE*CHUNKSIZE voxels size
105typedef 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)
115
116 // Chunks array
118 int arrayChunksSize; // Size for m_arrayChunks in bytes (DEBUG ONLY)
119
123
124 // Arrays for mesh build
128
129 //Palette for voxels
130 VoxColor palette[256];
131
132} VoxArray3D;
133
134#if defined(__cplusplus)
135extern "C" { // Prevents name mangling of functions
136#endif
137
138// Functions
139int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArray3D* pvoxarray);
141
142#ifdef __cplusplus
143}
144#endif
145
146#endif // VOX_LOADER_H
148
149
152// Implementation
155
156#ifdef VOX_LOADER_IMPLEMENTATION
157
158#include <string.h>
159#include <stdlib.h>
160
162// ArrayUShort helper
164
165static 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
172static 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
182static void freeArrayUShort(ArrayUShort* a)
183{
184 VOX_FREE(a->array);
185 a->array = NULL;
186 a->used = a->size = 0;
187}
188
189
191// ArrayVector3 helper
193
194static 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
201static 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
211static void freeArrayVector3(ArrayVector3* a)
212{
213 VOX_FREE(a->array);
214 a->array = NULL;
215 a->used = a->size = 0;
216}
217
219// ArrayColor helper
221
222static 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
229static 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
239static void freeArrayColor(ArrayColor* a)
240{
241 VOX_FREE(a->array);
242 a->array = NULL;
243 a->used = a->size = 0;
244}
245
246
248// Vox Loader
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
275const 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
284const 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
296static 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
335static 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
376static 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
416static 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
451static 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
464static 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
531int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArray3D* pvoxarray)
532{
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 unsigned char signature[4] = { 0 };
542
543 unsigned char* fileData = pvoxData;
544 unsigned char* fileDataPtr = fileData;
545 unsigned char* endfileDataPtr = fileData + voxDataSize;
546
547 signature[0] = fileDataPtr[0];
548 signature[1] = fileDataPtr[1];
549 signature[2] = fileDataPtr[2];
550 signature[3] = fileDataPtr[3];
551 fileDataPtr += 4;
552
553 if ((signature[0] != 'V') && (signature[0] != 'O') && (signature[0] != 'X') && (signature[0] != ' '))
554 {
555 return VOX_ERROR_INVALID_FORMAT; //"Not an MagicaVoxel File format"
556 }
557
558 // @raysan5: reviewed version loading
559 unsigned int version = 0;
560 version = ((unsigned int*)fileDataPtr)[0];
561 fileDataPtr += 4;
562
563 if (version < 150)
564 {
565 return VOX_ERROR_FILE_VERSION_TOO_OLD; //"MagicaVoxel version too old"
566 }
567
568
569 // header
570 //4 bytes: chunk id
571 //4 bytes: size of chunk contents (n)
572 //4 bytes: total size of children chunks(m)
573
575 //n bytes: chunk contents
576
578 //{ child chunk 0 }
579 //{ child chunk 1 }
580 unsigned int sizeX, sizeY, sizeZ;
581 sizeX = sizeY = sizeZ = 0;
582 unsigned int numVoxels = 0;
583
584 while (fileDataPtr < endfileDataPtr)
585 {
586 char szChunkName[5];
587 memcpy(szChunkName, fileDataPtr, 4);
588 szChunkName[4] = 0;
589 fileDataPtr += 4;
590
591 unsigned int chunkSize = *((unsigned int*)fileDataPtr);
592 fileDataPtr += sizeof(unsigned int);
593
594 //unsigned long chunkTotalChildSize = *((unsigned long*)fileDataPtr);
595 fileDataPtr += sizeof(unsigned int);
596
597 if (strcmp(szChunkName, "SIZE") == 0)
598 {
599 //(4 bytes x 3 : x, y, z )
600 sizeX = *((unsigned int*)fileDataPtr);
601 fileDataPtr += sizeof(unsigned int);
602
603 sizeY = *((unsigned int*)fileDataPtr);
604 fileDataPtr += sizeof(unsigned int);
605
606 sizeZ = *((unsigned int*)fileDataPtr);
607 fileDataPtr += sizeof(unsigned int);
608
609 //Alloc vox array
610 Vox_AllocArray(pvoxarray, sizeX, sizeZ, sizeY); //Reverse Y<>Z for left to right handed system
611 }
612 else if (strcmp(szChunkName, "XYZI") == 0)
613 {
614 unsigned char vx, vy, vz, vi;
615
616 //(numVoxels : 4 bytes )
617 //(each voxel: 1 byte x 4 : x, y, z, colorIndex ) x numVoxels
618 numVoxels = *((unsigned int*)fileDataPtr);
619 fileDataPtr += sizeof(unsigned int);
620
621 while (numVoxels > 0)
622 {
623 vx = *((unsigned char*)fileDataPtr++);
624 vy = *((unsigned char*)fileDataPtr++);
625 vz = *((unsigned char*)fileDataPtr++);
626 vi = *((unsigned char*)fileDataPtr++);
627
628 Vox_SetVoxel(pvoxarray, vx, vz, pvoxarray->sizeZ-vy-1, vi); //Reverse Y<>Z for left to right handed system
629
630 numVoxels--;
631 }
632 }
633 else if (strcmp(szChunkName, "RGBA") == 0)
634 {
635 VoxColor col;
636
637 //(each pixel: 1 byte x 4 : r, g, b, a ) x 256
638 for (int i = 0; i < 256 - 1; i++)
639 {
640 col.r = *((unsigned char*)fileDataPtr++);
641 col.g = *((unsigned char*)fileDataPtr++);
642 col.b = *((unsigned char*)fileDataPtr++);
643 col.a = *((unsigned char*)fileDataPtr++);
644
645 pvoxarray->palette[i + 1] = col;
646 }
647
648 }
649 else
650 {
651 fileDataPtr += chunkSize;
652 }
653 }
654
656 // Building Mesh
657 // TODO compute globals indices array
658
659 // Init Arrays
660 initArrayVector3(&pvoxarray->vertices, 3 * 1024);
661 initArrayUShort(&pvoxarray->indices, 3 * 1024);
662 initArrayColor(&pvoxarray->colors, 3 * 1024);
663
664 // Create vertices and indices buffers
665 int x, y, z;
666
667 for (x = 0; x <= pvoxarray->sizeX; x++)
668 {
669 for (z = 0; z <= pvoxarray->sizeZ; z++)
670 {
671 for (y = 0; y <= pvoxarray->sizeY; y++)
672 {
673 unsigned char matID = Vox_GetVoxel(pvoxarray, x, y, z);
674 if (matID != 0)
675 Vox_Build_Voxel(pvoxarray, x, y, z, matID);
676 }
677 }
678 }
679
680 return VOX_SUCCESS;
681}
682
683void Vox_FreeArrays(VoxArray3D* voxarray)
684{
685 // Free chunks
686 if (voxarray->m_arrayChunks != 0)
687 {
688 for (int i = 0; i < voxarray->chunksTotal; i++)
689 {
690 CubeChunk3D* chunk = &voxarray->m_arrayChunks[i];
691 if (chunk->m_array != 0)
692 {
693 chunk->arraySize = 0;
694 VOX_FREE(chunk->m_array);
695 }
696 }
697
698 VOX_FREE(voxarray->m_arrayChunks);
699 voxarray->m_arrayChunks = 0;
700 voxarray->arrayChunksSize = 0;
701
702 voxarray->chunksSizeX = voxarray->chunksSizeY = voxarray->chunksSizeZ = 0;
703 voxarray->chunksTotal = 0;
704 voxarray->chunksAllocated = 0;
705 voxarray->ChunkFlattenOffset = 0;
706 voxarray->sizeX = voxarray->sizeY = voxarray->sizeZ = 0;
707 }
708
709 // Free arrays
710 freeArrayVector3(&voxarray->vertices);
711 freeArrayUShort(&voxarray->indices);
712 freeArrayColor(&voxarray->colors);
713}
714
715#endif //VOX_LOADER_IMPLEMENTATION
void * id
#define NULL
Definition: miniaudio.h:3718
VoxColor * array
Definition: vox_loader.h:88
unsigned short * array
Definition: vox_loader.h:93
VoxVector3 * array
Definition: vox_loader.h:83
unsigned char * m_array
Definition: vox_loader.h:99
int chunksTotal
Definition: vox_loader.h:122
ArrayVector3 vertices
Definition: vox_loader.h:125
ArrayUShort indices
Definition: vox_loader.h:126
CubeChunk3D * m_arrayChunks
Definition: vox_loader.h:117
int arrayChunksSize
Definition: vox_loader.h:118
int chunksSizeZ
Definition: vox_loader.h:114
int chunksAllocated
Definition: vox_loader.h:121
ArrayColor colors
Definition: vox_loader.h:127
int chunksSizeY
Definition: vox_loader.h:113
int ChunkFlattenOffset
Definition: vox_loader.h:120
int chunksSizeX
Definition: vox_loader.h:112
VoxColor palette[256]
Definition: vox_loader.h:130
unsigned char r
Definition: vox_loader.h:74
unsigned char b
Definition: vox_loader.h:74
unsigned char g
Definition: vox_loader.h:74
unsigned char a
Definition: vox_loader.h:74
float x
Definition: vox_loader.h:79
float y
Definition: vox_loader.h:79
float z
Definition: vox_loader.h:79
#define VOX_SUCCESS
Definition: vox_loader.h:67
#define VOX_ERROR_INVALID_FORMAT
Definition: vox_loader.h:69
#define VOX_MALLOC(sz)
Definition: vox_loader.h:55
int Vox_LoadFromMemory(unsigned char *pvoxData, unsigned int voxDataSize, VoxArray3D *pvoxarray)
#define VOX_ERROR_FILE_VERSION_TOO_OLD
Definition: vox_loader.h:70
#define VOX_FREE(p)
Definition: vox_loader.h:64
#define VOX_REALLOC(n, sz)
Definition: vox_loader.h:61
void Vox_FreeArrays(VoxArray3D *voxarray)