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