aboutsummaryrefslogtreecommitdiffstats
path: root/raylib/src/external/vox_loader.h
diff options
context:
space:
mode:
Diffstat (limited to 'raylib/src/external/vox_loader.h')
-rw-r--r--raylib/src/external/vox_loader.h715
1 files changed, 715 insertions, 0 deletions
diff --git a/raylib/src/external/vox_loader.h b/raylib/src/external/vox_loader.h
new file mode 100644
index 0000000..a7a161c
--- /dev/null
+++ b/raylib/src/external/vox_loader.h
@@ -0,0 +1,715 @@
+/*
+ The MIT License (MIT)
+
+ Copyright (c) 2021 Johann Nadalutti.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+
+ vox_loader - v1.01
+ no warranty implied; use at your own risk
+
+ Do this:
+ #define VOX_LOADER_INCLUDE__H
+ before you include this file in* one* C or C++ file to create the implementation.
+
+ // i.e. it should look like this:
+ #include ...
+ #include ...
+ #include ...
+ #define VOX_LOADER_INCLUDE__H
+ #include "vox_loader.h"
+
+revision history:
+ 1.00 (2021-09-03) first released version
+ 1.01 (2021-09-07) Support custom memory allocators
+ Removed Raylib dependencies
+ Changed Vox_LoadFileName to Vox_LoadFromMemory
+ 1.02 (2021-09-10) @raysan5: Reviewed some formating
+ 1.03 (2021-10-02) @catmanl: Reduce warnings on gcc
+ 1.04 (2021-10-17) @warzes: Fixing the error of loading VOX models
+
+*/
+
+#ifndef VOX_LOADER_H
+#define VOX_LOADER_H
+
+// Allow custom memory allocators
+#ifndef VOX_MALLOC
+ #define VOX_MALLOC(sz) malloc(sz)
+#endif
+#ifndef VOX_CALLOC
+ #define VOX_CALLOC(n,sz) calloc(n,sz)
+#endif
+#ifndef VOX_REALLOC
+ #define VOX_REALLOC(n,sz) realloc(n,sz)
+#endif
+#ifndef VOX_FREE
+ #define VOX_FREE(p) free(p)
+#endif
+
+#define VOX_SUCCESS (0)
+#define VOX_ERROR_FILE_NOT_FOUND (-1)
+#define VOX_ERROR_INVALID_FORMAT (-2)
+#define VOX_ERROR_FILE_VERSION_TOO_OLD (-3)
+
+// VoxColor, 4 components, R8G8B8A8 (32bit)
+typedef struct {
+ unsigned char r, g, b, a;
+} VoxColor;
+
+// VoxVector3, 3 components
+typedef struct {
+ float x, y, z;
+} VoxVector3;
+
+typedef struct {
+ VoxVector3* array;
+ int used, size;
+} ArrayVector3;
+
+typedef struct {
+ VoxColor* array;
+ int used, size;
+} ArrayColor;
+
+typedef struct {
+ unsigned short* array;
+ int used, size;
+} ArrayUShort;
+
+// A chunk that contain voxels
+typedef struct {
+ unsigned char* m_array; //If Sparse != null
+ int arraySize; //Size for m_array in bytes (DEBUG ONLY)
+} CubeChunk3D;
+
+// Array for voxels
+// Array is divised into chunks of CHUNKSIZE*CHUNKSIZE*CHUNKSIZE voxels size
+typedef struct {
+ // Array size in voxels
+ int sizeX;
+ int sizeY;
+ int sizeZ;
+
+ // Chunks size into array (array is divised into chunks)
+ int chunksSizeX;
+ int chunksSizeY;
+ int chunksSizeZ;
+
+ // Chunks array
+ CubeChunk3D* m_arrayChunks;
+ int arrayChunksSize; // Size for m_arrayChunks in bytes (DEBUG ONLY)
+
+ int ChunkFlattenOffset;
+ int chunksAllocated;
+ int chunksTotal;
+
+ // Arrays for mesh build
+ ArrayVector3 vertices;
+ ArrayUShort indices;
+ ArrayColor colors;
+
+ //Palette for voxels
+ VoxColor palette[256];
+
+} VoxArray3D;
+
+#if defined(__cplusplus)
+extern "C" { // Prevents name mangling of functions
+#endif
+
+// Functions
+int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArray3D* pvoxarray);
+void Vox_FreeArrays(VoxArray3D* voxarray);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // VOX_LOADER_H
+//// end header file /////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////
+// Implementation
+/////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef VOX_LOADER_IMPLEMENTATION
+
+#include <string.h>
+#include <stdlib.h>
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// ArrayUShort helper
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+static void initArrayUShort(ArrayUShort* a, int initialSize)
+{
+ a->array = VOX_MALLOC(initialSize * sizeof(unsigned short));
+ a->used = 0;
+ a->size = initialSize;
+}
+
+static void insertArrayUShort(ArrayUShort* a, unsigned short element)
+{
+ if (a->used == a->size)
+ {
+ a->size *= 2;
+ a->array = VOX_REALLOC(a->array, a->size * sizeof(unsigned short));
+ }
+ a->array[a->used++] = element;
+}
+
+static void freeArrayUShort(ArrayUShort* a)
+{
+ VOX_FREE(a->array);
+ a->array = NULL;
+ a->used = a->size = 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// ArrayVector3 helper
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+static void initArrayVector3(ArrayVector3* a, int initialSize)
+{
+ a->array = VOX_MALLOC(initialSize * sizeof(VoxVector3));
+ a->used = 0;
+ a->size = initialSize;
+}
+
+static void insertArrayVector3(ArrayVector3* a, VoxVector3 element)
+{
+ if (a->used == a->size)
+ {
+ a->size *= 2;
+ a->array = VOX_REALLOC(a->array, a->size * sizeof(VoxVector3));
+ }
+ a->array[a->used++] = element;
+}
+
+static void freeArrayVector3(ArrayVector3* a)
+{
+ VOX_FREE(a->array);
+ a->array = NULL;
+ a->used = a->size = 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// ArrayColor helper
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+static void initArrayColor(ArrayColor* a, int initialSize)
+{
+ a->array = VOX_MALLOC(initialSize * sizeof(VoxColor));
+ a->used = 0;
+ a->size = initialSize;
+}
+
+static void insertArrayColor(ArrayColor* a, VoxColor element)
+{
+ if (a->used == a->size)
+ {
+ a->size *= 2;
+ a->array = VOX_REALLOC(a->array, a->size * sizeof(VoxColor));
+ }
+ a->array[a->used++] = element;
+}
+
+static void freeArrayColor(ArrayColor* a)
+{
+ VOX_FREE(a->array);
+ a->array = NULL;
+ a->used = a->size = 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// Vox Loader
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+#define CHUNKSIZE 16 // chunk size (CHUNKSIZE*CHUNKSIZE*CHUNKSIZE) in voxels
+#define CHUNKSIZE_OPSHIFT 4 // 1<<4=16 -> Warning depend of CHUNKSIZE
+#define CHUNK_FLATTENOFFSET_OPSHIFT 8 // Warning depend of CHUNKSIZE
+
+//
+// used right handed system and CCW face
+//
+// indexes for voxelcoords, per face orientation
+//
+
+//# Y
+//# |
+//# o----X
+//# /
+//# Z 2------------3
+//# /| /|
+//# 6------------7 |
+//# | | | |
+//# |0 ----------|- 1
+//# |/ |/
+//# 4------------5
+
+//
+// CCW
+const int fv[6][4] = {
+ {0, 2, 6, 4 }, //-X
+ {5, 7, 3, 1 }, //+X
+ {0, 4, 5, 1 }, //-y
+ {6, 2, 3, 7 }, //+y
+ {1, 3, 2, 0 }, //-Z
+ {4, 6, 7, 5 } //+Z
+};
+
+const VoxVector3 SolidVertex[] = {
+ {0, 0, 0}, //0
+ {1, 0, 0}, //1
+ {0, 1, 0}, //2
+ {1, 1, 0}, //3
+ {0, 0, 1}, //4
+ {1, 0, 1}, //5
+ {0, 1, 1}, //6
+ {1, 1, 1} //7
+ };
+
+// Allocated VoxArray3D size
+static void Vox_AllocArray(VoxArray3D* pvoxarray, int _sx, int _sy, int _sz)
+{
+ int sx = _sx + ((CHUNKSIZE - (_sx % CHUNKSIZE)) % CHUNKSIZE);
+ int sy = _sy + ((CHUNKSIZE - (_sy % CHUNKSIZE)) % CHUNKSIZE);
+ int sz = _sz + ((CHUNKSIZE - (_sz % CHUNKSIZE)) % CHUNKSIZE);
+
+ int chx = sx >> CHUNKSIZE_OPSHIFT; //Chunks Count in X
+ int chy = sy >> CHUNKSIZE_OPSHIFT; //Chunks Count in Y
+ int chz = sz >> CHUNKSIZE_OPSHIFT; //Chunks Count in Z
+
+ //VoxArray3D* parray = (VoxArray3D*)VOX_MALLOC(sizeof(VoxArray3D));
+ pvoxarray->sizeX = sx;
+ pvoxarray->sizeY = sy;
+ pvoxarray->sizeZ = sz;
+
+ pvoxarray->chunksSizeX = chx;
+ pvoxarray->chunksSizeY = chy;
+ pvoxarray->chunksSizeZ = chz;
+
+ pvoxarray->ChunkFlattenOffset = (chy * chz); //m_arrayChunks[(x * (sy*sz)) + (z * sy) + y]
+
+ // Alloc chunks array
+ int size = sizeof(CubeChunk3D) * chx * chy * chz;
+ pvoxarray->m_arrayChunks = VOX_MALLOC(size);
+ pvoxarray->arrayChunksSize = size;
+
+ // Init chunks array
+ size = chx * chy * chz;
+ pvoxarray->chunksTotal = size;
+ pvoxarray->chunksAllocated = 0;
+
+ for (int i = 0; i < size; i++)
+ {
+ pvoxarray->m_arrayChunks[i].m_array = 0;
+ pvoxarray->m_arrayChunks[i].arraySize = 0;
+ }
+}
+
+// Set voxel ID from its position into VoxArray3D
+static void Vox_SetVoxel(VoxArray3D* pvoxarray, int x, int y, int z, unsigned char id)
+{
+ // Get chunk from array pos
+ int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
+ int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
+ int chZ = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE;
+ int offset = (chX * pvoxarray->ChunkFlattenOffset) + (chZ * pvoxarray->chunksSizeY) + chY;
+
+ //if (offset > voxarray->arrayChunksSize)
+ //{
+ // TraceLog(LOG_ERROR, "Out of array");
+ //}
+
+ CubeChunk3D* chunk = &pvoxarray->m_arrayChunks[offset];
+
+ // Set Chunk
+ chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE);
+ chY = y - (chY << CHUNKSIZE_OPSHIFT); //y - (by * CHUNKSIZE);
+ chZ = z - (chZ << CHUNKSIZE_OPSHIFT); //z - (bz * CHUNKSIZE);
+
+ if (chunk->m_array == 0)
+ {
+ int size = CHUNKSIZE * CHUNKSIZE * CHUNKSIZE;
+ chunk->m_array = VOX_MALLOC(size);
+ chunk->arraySize = size;
+ memset(chunk->m_array, 0, size);
+
+ pvoxarray->chunksAllocated++;
+ }
+
+ offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY;
+
+ //if (offset > chunk->arraySize)
+ //{
+ // TraceLog(LOG_ERROR, "Out of array");
+ //}
+
+ chunk->m_array[offset] = id;
+}
+
+// Get voxel ID from its position into VoxArray3D
+static unsigned char Vox_GetVoxel(VoxArray3D* pvoxarray, int x, int y, int z)
+{
+ if (x < 0 || y < 0 || z < 0) return 0;
+
+ if (x >= pvoxarray->sizeX || y >= pvoxarray->sizeY || z >= pvoxarray->sizeZ) return 0;
+
+ // Get chunk from array pos
+ int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
+ int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
+ int chZ = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE;
+ int offset = (chX * pvoxarray->ChunkFlattenOffset) + (chZ * pvoxarray->chunksSizeY) + chY;
+
+ //if (offset > voxarray->arrayChunksSize)
+ //{
+ // TraceLog(LOG_ERROR, "Out of array");
+ //}
+
+ CubeChunk3D* chunk = &pvoxarray->m_arrayChunks[offset];
+
+ // Set Chunk
+ chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE);
+ chY = y - (chY << CHUNKSIZE_OPSHIFT); //y - (by * CHUNKSIZE);
+ chZ = z - (chZ << CHUNKSIZE_OPSHIFT); //z - (bz * CHUNKSIZE);
+
+ if (chunk->m_array == 0)
+ {
+ return 0;
+ }
+
+ offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY;
+
+ //if (offset > chunk->arraySize)
+ //{
+ // TraceLog(LOG_ERROR, "Out of array");
+ //}
+ return chunk->m_array[offset];
+
+}
+
+// Calc visibles faces from a voxel position
+static unsigned char Vox_CalcFacesVisible(VoxArray3D* pvoxArray, int cx, int cy, int cz)
+{
+ unsigned char idXm1 = Vox_GetVoxel(pvoxArray, cx - 1, cy, cz);
+ unsigned char idXp1 = Vox_GetVoxel(pvoxArray, cx + 1, cy, cz);
+
+ unsigned char idYm1 = Vox_GetVoxel(pvoxArray, cx, cy - 1, cz);
+ unsigned char idYp1 = Vox_GetVoxel(pvoxArray, cx, cy + 1, cz);
+
+ unsigned char idZm1 = Vox_GetVoxel(pvoxArray, cx, cy, cz - 1);
+ unsigned char idZp1 = Vox_GetVoxel(pvoxArray, cx, cy, cz + 1);
+
+ unsigned char byVFMask = 0;
+
+ //#-x
+ if (idXm1 == 0) byVFMask |= (1 << 0);
+
+ //#+x
+ if (idXp1 == 0) byVFMask |= (1 << 1);
+
+ //#-y
+ if (idYm1 == 0) byVFMask |= (1 << 2);
+
+ //#+y
+ if (idYp1 == 0) byVFMask |= (1 << 3);
+
+ //#-z
+ if (idZm1 == 0) byVFMask |= (1 << 4);
+
+ //#+z
+ if (idZp1 == 0) byVFMask |= (1 << 5);
+
+ return byVFMask;
+}
+
+// Get a vertex position from a voxel's corner
+static VoxVector3 Vox_GetVertexPosition(int _wcx, int _wcy, int _wcz, int _nNumVertex)
+{
+ float scale = 0.25;
+
+ VoxVector3 vtx = SolidVertex[_nNumVertex];
+ vtx.x = (vtx.x + _wcx) * scale;
+ vtx.y = (vtx.y + _wcy) * scale;
+ vtx.z = (vtx.z + _wcz) * scale;
+
+ return vtx;
+}
+
+// Build a voxel vertices/colors/indices
+static void Vox_Build_Voxel(VoxArray3D* pvoxArray, int x, int y, int z, int matID)
+{
+ unsigned char byVFMask = Vox_CalcFacesVisible(pvoxArray, x, y, z);
+
+ if (byVFMask == 0) return;
+
+ int i, j;
+ VoxVector3 vertComputed[8];
+ int bVertexComputed[8];
+ memset(vertComputed, 0, sizeof(vertComputed));
+ memset(bVertexComputed, 0, sizeof(bVertexComputed));
+
+ //For each Cube's faces
+ for (i = 0; i < 6; i++) // 6 faces
+ {
+ if ((byVFMask & (1 << i)) != 0) //If face is visible
+ {
+ for (j = 0; j < 4; j++) // 4 corners
+ {
+ int nNumVertex = fv[i][j]; //Face,Corner
+ if (bVertexComputed[nNumVertex] == 0) //if never calc
+ {
+ bVertexComputed[nNumVertex] = 1;
+ vertComputed[nNumVertex] = Vox_GetVertexPosition(x, y, z, nNumVertex);
+ }
+ }
+ }
+ }
+
+ //Add face
+ for (i = 0; i < 6; i++)// 6 faces
+ {
+ if ((byVFMask & (1 << i)) == 0)
+ continue; //Face invisible
+
+ int v0 = fv[i][0]; //Face, Corner
+ int v1 = fv[i][1]; //Face, Corner
+ int v2 = fv[i][2]; //Face, Corner
+ int v3 = fv[i][3]; //Face, Corner
+
+ //Arrays
+ int idx = pvoxArray->vertices.used;
+ insertArrayVector3(&pvoxArray->vertices, vertComputed[v0]);
+ insertArrayVector3(&pvoxArray->vertices, vertComputed[v1]);
+ insertArrayVector3(&pvoxArray->vertices, vertComputed[v2]);
+ insertArrayVector3(&pvoxArray->vertices, vertComputed[v3]);
+
+ VoxColor col = pvoxArray->palette[matID];
+
+ insertArrayColor(&pvoxArray->colors, col);
+ insertArrayColor(&pvoxArray->colors, col);
+ insertArrayColor(&pvoxArray->colors, col);
+ insertArrayColor(&pvoxArray->colors, col);
+
+
+ //v0 - v1 - v2, v0 - v2 - v3
+ insertArrayUShort(&pvoxArray->indices, idx + 0);
+ insertArrayUShort(&pvoxArray->indices, idx + 2);
+ insertArrayUShort(&pvoxArray->indices, idx + 1);
+
+ insertArrayUShort(&pvoxArray->indices, idx + 0);
+ insertArrayUShort(&pvoxArray->indices, idx + 3);
+ insertArrayUShort(&pvoxArray->indices, idx + 2);
+ }
+}
+
+// MagicaVoxel *.vox file format Loader
+int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArray3D* pvoxarray)
+{
+ //////////////////////////////////////////////////
+ // Read VOX file
+ // 4 bytes: magic number ('V' 'O' 'X' 'space')
+ // 4 bytes: version number (current version is 150)
+
+ // @raysan5: Reviewed (unsigned long) -> (unsigned int), possible issue with Ubuntu 18.04 64bit
+
+ // @raysan5: reviewed signature loading
+ unsigned char signature[4] = { 0 };
+
+ unsigned char* fileData = pvoxData;
+ unsigned char* fileDataPtr = fileData;
+ unsigned char* endfileDataPtr = fileData + voxDataSize;
+
+ signature[0] = fileDataPtr[0];
+ signature[1] = fileDataPtr[1];
+ signature[2] = fileDataPtr[2];
+ signature[3] = fileDataPtr[3];
+ fileDataPtr += 4;
+
+ if ((signature[0] != 'V') && (signature[0] != 'O') && (signature[0] != 'X') && (signature[0] != ' '))
+ {
+ return VOX_ERROR_INVALID_FORMAT; //"Not an MagicaVoxel File format"
+ }
+
+ // @raysan5: reviewed version loading
+ unsigned int version = 0;
+ version = ((unsigned int*)fileDataPtr)[0];
+ fileDataPtr += 4;
+
+ if (version < 150)
+ {
+ return VOX_ERROR_FILE_VERSION_TOO_OLD; //"MagicaVoxel version too old"
+ }
+
+
+ // header
+ //4 bytes: chunk id
+ //4 bytes: size of chunk contents (n)
+ //4 bytes: total size of children chunks(m)
+
+ //// chunk content
+ //n bytes: chunk contents
+
+ //// children chunks : m bytes
+ //{ child chunk 0 }
+ //{ child chunk 1 }
+ unsigned int sizeX, sizeY, sizeZ;
+ sizeX = sizeY = sizeZ = 0;
+ unsigned int numVoxels = 0;
+
+ while (fileDataPtr < endfileDataPtr)
+ {
+ char szChunkName[5];
+ memcpy(szChunkName, fileDataPtr, 4);
+ szChunkName[4] = 0;
+ fileDataPtr += 4;
+
+ unsigned int chunkSize = *((unsigned int*)fileDataPtr);
+ fileDataPtr += sizeof(unsigned int);
+
+ //unsigned long chunkTotalChildSize = *((unsigned long*)fileDataPtr);
+ fileDataPtr += sizeof(unsigned int);
+
+ if (strcmp(szChunkName, "SIZE") == 0)
+ {
+ //(4 bytes x 3 : x, y, z )
+ sizeX = *((unsigned int*)fileDataPtr);
+ fileDataPtr += sizeof(unsigned int);
+
+ sizeY = *((unsigned int*)fileDataPtr);
+ fileDataPtr += sizeof(unsigned int);
+
+ sizeZ = *((unsigned int*)fileDataPtr);
+ fileDataPtr += sizeof(unsigned int);
+
+ //Alloc vox array
+ Vox_AllocArray(pvoxarray, sizeX, sizeZ, sizeY); //Reverse Y<>Z for left to right handed system
+ }
+ else if (strcmp(szChunkName, "XYZI") == 0)
+ {
+ unsigned char vx, vy, vz, vi;
+
+ //(numVoxels : 4 bytes )
+ //(each voxel: 1 byte x 4 : x, y, z, colorIndex ) x numVoxels
+ numVoxels = *((unsigned int*)fileDataPtr);
+ fileDataPtr += sizeof(unsigned int);
+
+ while (numVoxels > 0)
+ {
+ vx = *((unsigned char*)fileDataPtr++);
+ vy = *((unsigned char*)fileDataPtr++);
+ vz = *((unsigned char*)fileDataPtr++);
+ vi = *((unsigned char*)fileDataPtr++);
+
+ Vox_SetVoxel(pvoxarray, vx, vz, pvoxarray->sizeZ-vy-1, vi); //Reverse Y<>Z for left to right handed system
+
+ numVoxels--;
+ }
+ }
+ else if (strcmp(szChunkName, "RGBA") == 0)
+ {
+ VoxColor col;
+
+ //(each pixel: 1 byte x 4 : r, g, b, a ) x 256
+ for (int i = 0; i < 256 - 1; i++)
+ {
+ col.r = *((unsigned char*)fileDataPtr++);
+ col.g = *((unsigned char*)fileDataPtr++);
+ col.b = *((unsigned char*)fileDataPtr++);
+ col.a = *((unsigned char*)fileDataPtr++);
+
+ pvoxarray->palette[i + 1] = col;
+ }
+
+ }
+ else
+ {
+ fileDataPtr += chunkSize;
+ }
+ }
+
+ //////////////////////////////////////////////////////////
+ // Building Mesh
+ // TODO compute globals indices array
+
+ // Init Arrays
+ initArrayVector3(&pvoxarray->vertices, 3 * 1024);
+ initArrayUShort(&pvoxarray->indices, 3 * 1024);
+ initArrayColor(&pvoxarray->colors, 3 * 1024);
+
+ // Create vertices and indices buffers
+ int x, y, z;
+
+ for (x = 0; x <= pvoxarray->sizeX; x++)
+ {
+ for (z = 0; z <= pvoxarray->sizeZ; z++)
+ {
+ for (y = 0; y <= pvoxarray->sizeY; y++)
+ {
+ unsigned char matID = Vox_GetVoxel(pvoxarray, x, y, z);
+ if (matID != 0)
+ Vox_Build_Voxel(pvoxarray, x, y, z, matID);
+ }
+ }
+ }
+
+ return VOX_SUCCESS;
+}
+
+void Vox_FreeArrays(VoxArray3D* voxarray)
+{
+ // Free chunks
+ if (voxarray->m_arrayChunks != 0)
+ {
+ for (int i = 0; i < voxarray->chunksTotal; i++)
+ {
+ CubeChunk3D* chunk = &voxarray->m_arrayChunks[i];
+ if (chunk->m_array != 0)
+ {
+ chunk->arraySize = 0;
+ VOX_FREE(chunk->m_array);
+ }
+ }
+
+ VOX_FREE(voxarray->m_arrayChunks);
+ voxarray->m_arrayChunks = 0;
+ voxarray->arrayChunksSize = 0;
+
+ voxarray->chunksSizeX = voxarray->chunksSizeY = voxarray->chunksSizeZ = 0;
+ voxarray->chunksTotal = 0;
+ voxarray->chunksAllocated = 0;
+ voxarray->ChunkFlattenOffset = 0;
+ voxarray->sizeX = voxarray->sizeY = voxarray->sizeZ = 0;
+ }
+
+ // Free arrays
+ freeArrayVector3(&voxarray->vertices);
+ freeArrayUShort(&voxarray->indices);
+ freeArrayColor(&voxarray->colors);
+}
+
+#endif //VOX_LOADER_IMPLEMENTATION