Browse Source

Vox loaded (#1981)

* new models_magicavoxel_loading example

* Portable header-only file "magicavoxel_loader.h" for MagicaVoxel loader example.

* models_magicavoxel_loading example added to CMakeLists.txt and Makefile

* fix models_magicavoxel_loading example for linux.

* * vox_loader into "src/external/vox_loader.h"
 * vox file support for "models.c"
 * updated example "models/models_magicavoxel_loading.c"

* * Fix Vox_FreeArrays (removed memory leak)

* * removed magicavoxel_loader.h

* * Revert vs2019 solution

* * vox_loader.h -> Support custom memory allocators
* vox_loader.h -> Reverse Y<>Z for left to right handed system
* models/models_magicavoxel_loading.c -> fix model center

* * vox_loader.h -> Removed Raylib dependencies

* * Changed Vox_LoadFileName to Vox_LoadFromMemory
procfxgen 4 years ago
parent
commit
a422d2fc8b
3 changed files with 125 additions and 92 deletions
  1. 5 7
      examples/models/models_magicavoxel_loading.c
  2. 88 81
      src/external/vox_loader.h
  3. 32 4
      src/models.c

+ 5 - 7
examples/models/models_magicavoxel_loading.c

@@ -51,16 +51,14 @@ int main(void)
 		t1 = GetTime() * 1000.0;
 		TraceLog(LOG_INFO, TextFormat("Vox <%s> loaded in %f ms", GetFileName(szVoxFiles[i]), t1 - t0));
 
-		//Compute model matrix
+		//Compute model's center matrix 
 		BoundingBox  bb = GetModelBoundingBox(models[i]);
 		Vector3 center;
-		center.x = -(((bb.max.x - bb.min.x) / 2));
-		center.y = -(((bb.max.y - bb.min.y) / 2));
-		center.z = -(((bb.max.z - bb.min.z) / 2));
+		center.x = bb.min.x  + (((bb.max.x - bb.min.x) / 2));
+		center.z = bb.min.z  + (((bb.max.z - bb.min.z) / 2));
 
-		Matrix matP = MatrixTranslate(center.x, center.z, 0);
-		Matrix matR = MatrixRotateX(90 * DEG2RAD);
-		models[i].transform = MatrixMultiply(matP, matR);
+		Matrix matP = MatrixTranslate(-center.x, 0, -center.z);
+		models[i].transform = matP;
 
 
 	}

+ 88 - 81
src/external/vox_loader.h

@@ -22,7 +22,7 @@
    THE SOFTWARE.
 
 
-	vox_loader - v1.00
+	vox_loader - v1.01
 			 no warranty implied; use at your own risk
 
 	Do this:
@@ -34,10 +34,13 @@
 	#include ...
 	#include ...
 	#define VOX_LOADER_INCLUDE__H
-	#include "magicavoxel_loader.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
 
 */
 
@@ -53,10 +56,21 @@ revision history:
 extern "C" {
 #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)
+	#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
 	{
@@ -66,13 +80,13 @@ extern "C" {
 
 	typedef struct
 	{
-		Vector3* array;
+		VoxVector3* array;
 		int used, size;
 	} ArrayVector3;
 
 	typedef struct
 	{
-		Color* array;
+		VoxColor* array;
 		int used, size;
 	} ArrayColor;
 
@@ -118,13 +132,13 @@ extern "C" {
 		ArrayColor colors;
 
 		//Palette for voxels
-		Color palette[256];
+		VoxColor palette[256];
 
 	} VoxArray3D;
 
 
 	// Functions
-	extern int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray);
+	extern int Vox_LoadFromMemory(const unsigned char* pvoxData, unsigned int voxDataSize, VoxArray3D* pvoxarray);
 	extern void Vox_FreeArrays(VoxArray3D* voxarray);
 
 
@@ -155,7 +169,7 @@ extern "C" {
 
 void initArrayInt(ArrayInt* a, int initialSize)
 {
-	a->array = MemAlloc(initialSize * sizeof(int));
+	a->array = VOX_MALLOC(initialSize * sizeof(int));
 	a->used = 0;
 	a->size = initialSize;
 }
@@ -165,14 +179,14 @@ void insertArrayInt(ArrayInt* a, int element)
 	if (a->used == a->size)
 	{
 		a->size *= 2;
-		a->array = MemRealloc(a->array, a->size * sizeof(int));
+		a->array = VOX_REALLOC(a->array, a->size * sizeof(int));
 	}
 	a->array[a->used++] = element;
 }
 
 void freeArrayInt(ArrayInt* a)
 {
-	MemFree(a->array);
+	VOX_FREE(a->array);
 	a->array = NULL;
 	a->used = a->size = 0;
 }
@@ -183,7 +197,7 @@ void freeArrayInt(ArrayInt* a)
 
 void initArrayUShort(ArrayUShort* a, int initialSize)
 {
-	a->array = MemAlloc(initialSize * sizeof(unsigned short));
+	a->array = VOX_MALLOC(initialSize * sizeof(unsigned short));
 	a->used = 0;
 	a->size = initialSize;
 }
@@ -193,14 +207,14 @@ void insertArrayUShort(ArrayUShort* a, unsigned short element)
 	if (a->used == a->size)
 	{
 		a->size *= 2;
-		a->array = MemRealloc(a->array, a->size * sizeof(unsigned short));
+		a->array = VOX_REALLOC(a->array, a->size * sizeof(unsigned short));
 	}
 	a->array[a->used++] = element;
 }
 
 void freeArrayUShort(ArrayUShort* a)
 {
-	MemFree(a->array);
+	VOX_FREE(a->array);
 	a->array = NULL;
 	a->used = a->size = 0;
 }
@@ -212,24 +226,24 @@ void freeArrayUShort(ArrayUShort* a)
 
 void initArrayVector3(ArrayVector3* a, int initialSize)
 {
-	a->array = MemAlloc(initialSize * sizeof(Vector3));
+	a->array = VOX_MALLOC(initialSize * sizeof(VoxVector3));
 	a->used = 0;
 	a->size = initialSize;
 }
 
-void insertArrayVector3(ArrayVector3* a, Vector3 element)
+void insertArrayVector3(ArrayVector3* a, VoxVector3 element)
 {
 	if (a->used == a->size)
 	{
 		a->size *= 2;
-		a->array = MemRealloc(a->array, a->size * sizeof(Vector3));
+		a->array = VOX_REALLOC(a->array, a->size * sizeof(VoxVector3));
 	}
 	a->array[a->used++] = element;
 }
 
 void freeArrayVector3(ArrayVector3* a)
 {
-	MemFree(a->array);
+	VOX_FREE(a->array);
 	a->array = NULL;
 	a->used = a->size = 0;
 }
@@ -240,24 +254,24 @@ void freeArrayVector3(ArrayVector3* a)
 
 void initArrayColor(ArrayColor* a, int initialSize)
 {
-	a->array = MemAlloc(initialSize * sizeof(Color));
+	a->array = VOX_MALLOC(initialSize * sizeof(VoxColor));
 	a->used = 0;
 	a->size = initialSize;
 }
 
-void insertArrayColor(ArrayColor* a, Color element)
+void insertArrayColor(ArrayColor* a, VoxColor element)
 {
 	if (a->used == a->size)
 	{
 		a->size *= 2;
-		a->array = MemRealloc(a->array, a->size * sizeof(Color));
+		a->array = VOX_REALLOC(a->array, a->size * sizeof(VoxColor));
 	}
 	a->array[a->used++] = element;
 }
 
 void freeArrayColor(ArrayColor* a)
 {
-	MemFree(a->array);
+	VOX_FREE(a->array);
 	a->array = NULL;
 	a->used = a->size = 0;
 }
@@ -300,7 +314,7 @@ const int fv[6][4] = {
 	{4, 6, 7, 5 } };//+Z
 
 
-const Vector3 SolidVertex[] = {
+const VoxVector3 SolidVertex[] = {
 	{0, 0, 0},   //0
 	{1, 0, 0},   //1
 	{0, 1, 0},   //2
@@ -315,7 +329,7 @@ const Vector3 SolidVertex[] = {
 
 
 // Allocated VoxArray3D size
-void Vox_AllocArray(VoxArray3D* voxarray, int _sx, int _sy, int _sz)
+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);
@@ -325,50 +339,50 @@ void Vox_AllocArray(VoxArray3D* voxarray, int _sx, int _sy, int _sz)
 	int chy = sy >> CHUNKSIZE_OPSHIFT; //Chunks Count in Y
 	int chz = sz >> CHUNKSIZE_OPSHIFT; //Chunks Count in Z
 
-	//VoxArray3D* parray = (VoxArray3D*)MemAlloc(sizeof(VoxArray3D));
-	voxarray->sizeX = sx;
-	voxarray->sizeY = sy;
-	voxarray->sizeZ = sz;
+	//VoxArray3D* parray = (VoxArray3D*)VOX_MALLOC(sizeof(VoxArray3D));
+	pvoxarray->sizeX = sx;
+	pvoxarray->sizeY = sy;
+	pvoxarray->sizeZ = sz;
 
-	voxarray->chunksSizeX = chx;
-	voxarray->chunksSizeY = chy;
-	voxarray->chunksSizeZ = chz;
+	pvoxarray->chunksSizeX = chx;
+	pvoxarray->chunksSizeY = chy;
+	pvoxarray->chunksSizeZ = chz;
 
-	voxarray->ChunkFlattenOffset = (chy * chz); //m_arrayChunks[(x * (sy*sz)) + (z * sy) + y]
+	pvoxarray->ChunkFlattenOffset = (chy * chz); //m_arrayChunks[(x * (sy*sz)) + (z * sy) + y]
 
 	//Alloc chunks array
 	int size = sizeof(CubeChunk3D) * chx * chy * chz;
-	voxarray->m_arrayChunks = MemAlloc(size);
-	voxarray->arrayChunksSize = size;
+	pvoxarray->m_arrayChunks = VOX_MALLOC(size);
+	pvoxarray->arrayChunksSize = size;
 
 
 	//Init chunks array
 	size = chx * chy * chz;
-	voxarray->chunksTotal = size;
-	voxarray->chunksAllocated = 0;
+	pvoxarray->chunksTotal = size;
+	pvoxarray->chunksAllocated = 0;
 
 	for (int i = 0; i < size; i++)
 	{
-		voxarray->m_arrayChunks[i].m_array = 0;
-		voxarray->m_arrayChunks[i].arraySize = 0;
+		pvoxarray->m_arrayChunks[i].m_array = 0;
+		pvoxarray->m_arrayChunks[i].arraySize = 0;
 	}
 }
 
 // Set voxel ID from its position into VoxArray3D
-void Vox_SetVoxel(VoxArray3D* voxarray, int x, int y, int z, unsigned char id)
+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 * voxarray->ChunkFlattenOffset) + (chZ * voxarray->chunksSizeY) + chY;
+	int offset = (chX * pvoxarray->ChunkFlattenOffset) + (chZ * pvoxarray->chunksSizeY) + chY;
 
 	//if (offset > voxarray->arrayChunksSize)
 	//{
 	//	TraceLog(LOG_ERROR, "Out of array");
 	//}
 
-	CubeChunk3D* chunk = &voxarray->m_arrayChunks[offset];
+	CubeChunk3D* chunk = &pvoxarray->m_arrayChunks[offset];
 
 	//Set Chunk
 	chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE);
@@ -378,11 +392,11 @@ void Vox_SetVoxel(VoxArray3D* voxarray, int x, int y, int z, unsigned char id)
 	if (chunk->m_array == 0)
 	{
 		int size = CHUNKSIZE * CHUNKSIZE * CHUNKSIZE;
-		chunk->m_array = MemAlloc(size);
+		chunk->m_array = VOX_MALLOC(size);
 		chunk->arraySize = size;
-		//memset(chunk->m_array, 0, size);
+		memset(chunk->m_array, 0, size);
 
-		voxarray->chunksAllocated++;
+		pvoxarray->chunksAllocated++;
 	}
 
 	offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY;
@@ -397,12 +411,12 @@ void Vox_SetVoxel(VoxArray3D* voxarray, int x, int y, int z, unsigned char id)
 }
 
 // Get voxel ID from its position into VoxArray3D
-unsigned char Vox_GetVoxel(VoxArray3D* voxarray, int x, int y, int z)
+unsigned char Vox_GetVoxel(VoxArray3D* pvoxarray, int x, int y, int z)
 {
 	if (x < 0 || y < 0 || z < 0)
 		return 0;
 
-	if (x >= voxarray->sizeX || y >= voxarray->sizeY || z >= voxarray->sizeZ)
+	if (x >= pvoxarray->sizeX || y >= pvoxarray->sizeY || z >= pvoxarray->sizeZ)
 		return 0;
 
 
@@ -410,14 +424,14 @@ unsigned char Vox_GetVoxel(VoxArray3D* voxarray, int x, int y, int z)
 	int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
 	int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
 	int chZ = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE;
-	int offset = (chX * voxarray->ChunkFlattenOffset) + (chZ * voxarray->chunksSizeY) + chY;
+	int offset = (chX * pvoxarray->ChunkFlattenOffset) + (chZ * pvoxarray->chunksSizeY) + chY;
 
 	//if (offset > voxarray->arrayChunksSize)
 	//{
 	//	TraceLog(LOG_ERROR, "Out of array");
 	//}
 
-	CubeChunk3D* chunk = &voxarray->m_arrayChunks[offset];
+	CubeChunk3D* chunk = &pvoxarray->m_arrayChunks[offset];
 
 	//Set Chunk
 	chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE);
@@ -481,10 +495,10 @@ unsigned char Vox_CalcFacesVisible(VoxArray3D* pvoxArray, int cx, int cy, int cz
 }
 
 // Get a vertex position from a voxel's corner
-Vector3 Vox_GetVertexPosition(int _wcx, int _wcy, int _wcz, int _nNumVertex)
+VoxVector3 Vox_GetVertexPosition(int _wcx, int _wcy, int _wcz, int _nNumVertex)
 {
 	float scale = 0.25;
-	Vector3 vtx = SolidVertex[_nNumVertex];
+	VoxVector3 vtx = SolidVertex[_nNumVertex];
 	vtx.x = (vtx.x + _wcx) * scale;
 	vtx.y = (vtx.y + _wcy) * scale;
 	vtx.z = (vtx.z + _wcz) * scale;
@@ -501,7 +515,7 @@ void Vox_Build_Voxel(VoxArray3D* pvoxArray, int x, int y, int z, int matID)
 		return;
 
 	int i, j;
-	Vector3 vertComputed[8];
+	VoxVector3 vertComputed[8];
 	int bVertexComputed[8];
 	memset(vertComputed, 0, sizeof(vertComputed));
 	memset(bVertexComputed, 0, sizeof(bVertexComputed));
@@ -542,7 +556,7 @@ void Vox_Build_Voxel(VoxArray3D* pvoxArray, int x, int y, int z, int matID)
 		insertArrayVector3(&pvoxArray->vertices, vertComputed[v2]);
 		insertArrayVector3(&pvoxArray->vertices, vertComputed[v3]);
 
-		Color col = pvoxArray->palette[matID];
+		VoxColor col = pvoxArray->palette[matID];
 
 		insertArrayColor(&pvoxArray->colors, col);
 		insertArrayColor(&pvoxArray->colors, col);
@@ -566,7 +580,7 @@ void Vox_Build_Voxel(VoxArray3D* pvoxArray, int x, int y, int z, int matID)
 }
 
 // MagicaVoxel *.vox file format Loader
-int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
+int Vox_LoadFromMemory(const unsigned char* pvoxData, unsigned int voxDataSize, VoxArray3D* pvoxarray)
 {
 
 	//////////////////////////////////////////////////
@@ -576,24 +590,17 @@ int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
 
 	unsigned long signature;
 
-	unsigned int readed = 0;
-	unsigned char* fileData;
-	fileData = LoadFileData(pszfileName, &readed);
-	if (fileData == 0)
-	{
-		return VOX_ERROR_FILE_NOT_FOUND;
-	}
+	unsigned char* fileData = pvoxData;
 
 	unsigned char* fileDataPtr = fileData;
-	unsigned char* endfileDataPtr = fileData + readed;
+	unsigned char* endfileDataPtr = fileData + voxDataSize;
 
 	signature = *((unsigned long *)fileDataPtr);
 	fileDataPtr += sizeof(unsigned long);
 
 	if (signature != 0x20584F56) //56 4F 58 20
 	{
-		//TraceLog(LOG_ERROR, "Not an MagicaVoxel File format");
-		return VOX_ERROR_INVALID_FORMAT;
+		return VOX_ERROR_INVALID_FORMAT; //"Not an MagicaVoxel File format"
 	}
 
 	unsigned long version;
@@ -603,8 +610,7 @@ int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
 
 	if (version < 150)
 	{
-		//TraceLog(LOG_ERROR, "MagicaVoxel version too old");
-		return VOX_ERROR_FILE_VERSION_TOO_OLD;
+		return VOX_ERROR_FILE_VERSION_TOO_OLD; //"MagicaVoxel version too old"
 	}
 
 
@@ -651,7 +657,7 @@ int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
 			fileDataPtr += sizeof(unsigned long);
 
 			//Alloc vox array
-			Vox_AllocArray(voxarray, sizeX, sizeY, sizeZ);
+			Vox_AllocArray(pvoxarray, sizeX, sizeZ, sizeY);	//Reverse Y<>Z for left to right handed system
 		}
 		else if (strcmp(szChunkName, "XYZI") == 0)
 		{
@@ -669,14 +675,14 @@ int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
 				vz = *((unsigned char*)fileDataPtr++);
 				vi = *((unsigned char*)fileDataPtr++);
 
-				Vox_SetVoxel(voxarray, vx, vy, vz, vi);
+				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)
 		{
-			Color col;
+			VoxColor col;
 
 			//(each pixel: 1 byte x 4 : r, g, b, a ) x 256
 			for (int i = 0; i < 256 - 1; i++)
@@ -686,7 +692,7 @@ int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
 				col.b = *((unsigned char*)fileDataPtr++);
 				col.a = *((unsigned char*)fileDataPtr++);
 
-				voxarray->palette[i + 1] = col;
+				pvoxarray->palette[i + 1] = col;
 			}
 
 		}
@@ -696,6 +702,7 @@ int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
 		}
 	}
 
+
 	//TraceLog(LOG_INFO, TextFormat("Vox Size : %dx%dx%d", sizeX, sizeY, sizeZ));
 
 	//TraceLog(LOG_INFO, TextFormat("Vox Chunks Count : %d/%d", pvoxArray->chunksAllocated, pvoxArray->chunksTotal));
@@ -708,22 +715,22 @@ int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
 	//TraceLog(LOG_INFO, TextFormat("Building VOX Mesh : %s", pszfileName));
 
 	// Init Arrays
-	initArrayVector3(&voxarray->vertices, 3 * 1024);
-	initArrayUShort(&voxarray->indices, 3 * 1024);
-	initArrayColor(&voxarray->colors, 3 * 1024);
+	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 <= voxarray->sizeX; x++)
+	for (x = 0; x <= pvoxarray->sizeX; x++)
 	{
-		for (z = 0; z <= voxarray->sizeZ; z++)
+		for (z = 0; z <= pvoxarray->sizeZ; z++)
 		{
-			for (y = 0; y <= voxarray->sizeY; y++)
+			for (y = 0; y <= pvoxarray->sizeY; y++)
 			{
-				unsigned char matID = Vox_GetVoxel(voxarray, x, y, z);
+				unsigned char matID = Vox_GetVoxel(pvoxarray, x, y, z);
 				if (matID != 0)
-					Vox_Build_Voxel(voxarray, x, y, z, matID);
+					Vox_Build_Voxel(pvoxarray, x, y, z, matID);
 			}
 		}
 	}
@@ -744,11 +751,11 @@ void Vox_FreeArrays(VoxArray3D* voxarray)
 			if (chunk->m_array != 0)
 			{
 				chunk->arraySize = 0;
-				MemFree(chunk->m_array);
+				VOX_FREE(chunk->m_array);
 			}
 		}
 
-		MemFree(voxarray->m_arrayChunks);
+		VOX_FREE(voxarray->m_arrayChunks);
 		voxarray->m_arrayChunks = 0;
 		voxarray->arrayChunksSize = 0;
 

+ 32 - 4
src/models.c

@@ -74,7 +74,19 @@
 #endif
 
 #if defined(SUPPORT_FILEFORMAT_VOX)
-    // TODO: Support custom memory allocators
+    // Allow custom memory allocators
+    #ifndef VOX_MALLOC
+        #define VOX_MALLOC    RL_MALLOC
+    #endif
+    #ifndef VOX_CALLOC
+        #define VOX_CALLOC    RL_CALLOC
+    #endif
+    #ifndef VOX_REALLOC
+        #define VOX_REALLOC    RL_REALLOC
+    #endif
+    #ifndef VOX_FREE
+        #define VOX_FREE      RL_FREE
+    #endif
 
     #define VOX_LOADER_IMPLEMENTATION
     #include "external/vox_loader.h"    // vox file format loading (MagikaVoxel)
@@ -5529,24 +5541,38 @@ static void GetGLTFPrimitiveCount(cgltf_node *node, int *outCount)
 #endif
 
 #if defined(SUPPORT_FILEFORMAT_VOX)
-// Load VOX (MagikaVoxel) mesh data
+// Load VOX (MagicaVoxel) mesh data
 static Model LoadVOX(const char *fileName)
 {
     Model model = { 0 };
     int nbvertices = 0;
     int meshescount = 0;
+    unsigned int readed = 0;
+    unsigned char* fileData;
     
+    //Read vox file into buffer
+    fileData = LoadFileData(fileName, &readed);
+    if (fileData == 0)
+    {
+        TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load VOX file", fileName);
+        return model;
+    }
+
+    //Read and build voxarray description
     VoxArray3D voxarray = { 0 };
-    int ret = Vox_LoadFileName(fileName, &voxarray);
+    int ret = Vox_LoadFromMemory(fileData, readed, &voxarray);
 
     if (ret != VOX_SUCCESS)
     {
+        // Error
+        UnloadFileData(fileData);
+
         TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load VOX data", fileName);
         return model;
     }
     else
     {
-        // Compute meshes count
+        // Success: Compute meshes count
         nbvertices = voxarray.vertices.used;
         meshescount = 1 + (nbvertices/65536);
 
@@ -5611,7 +5637,9 @@ static Model LoadVOX(const char *fileName)
         pcolors += verticesMax;
     }
 
+    //Free buffers
     Vox_FreeArrays(&voxarray);
+    UnloadFileData(fileData);
 
     return model;
 }