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
This commit is contained in:
procfxgen 2021-09-10 15:24:01 +02:00 committed by GitHub
parent 803094f41f
commit a422d2fc8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 125 additions and 92 deletions

View File

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

View File

@ -22,7 +22,7 @@
THE SOFTWARE. THE SOFTWARE.
vox_loader - v1.00 vox_loader - v1.01
no warranty implied; use at your own risk no warranty implied; use at your own risk
Do this: Do this:
@ -34,10 +34,13 @@
#include ... #include ...
#include ... #include ...
#define VOX_LOADER_INCLUDE__H #define VOX_LOADER_INCLUDE__H
#include "magicavoxel_loader.h" #include "vox_loader.h"
revision history: revision history:
1.00 (2021-09-03) first released version 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" { extern "C" {
#endif #endif
#define VOX_SUCCESS (0) #define VOX_SUCCESS (0)
#define VOX_ERROR_FILE_NOT_FOUND (-1) #define VOX_ERROR_FILE_NOT_FOUND (-1)
#define VOX_ERROR_INVALID_FORMAT (-2) #define VOX_ERROR_INVALID_FORMAT (-2)
#define VOX_ERROR_FILE_VERSION_TOO_OLD (-3) #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 typedef struct
{ {
@ -66,13 +80,13 @@ extern "C" {
typedef struct typedef struct
{ {
Vector3* array; VoxVector3* array;
int used, size; int used, size;
} ArrayVector3; } ArrayVector3;
typedef struct typedef struct
{ {
Color* array; VoxColor* array;
int used, size; int used, size;
} ArrayColor; } ArrayColor;
@ -118,13 +132,13 @@ extern "C" {
ArrayColor colors; ArrayColor colors;
//Palette for voxels //Palette for voxels
Color palette[256]; VoxColor palette[256];
} VoxArray3D; } VoxArray3D;
// Functions // 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); extern void Vox_FreeArrays(VoxArray3D* voxarray);
@ -155,7 +169,7 @@ extern "C" {
void initArrayInt(ArrayInt* a, int initialSize) void initArrayInt(ArrayInt* a, int initialSize)
{ {
a->array = MemAlloc(initialSize * sizeof(int)); a->array = VOX_MALLOC(initialSize * sizeof(int));
a->used = 0; a->used = 0;
a->size = initialSize; a->size = initialSize;
} }
@ -165,14 +179,14 @@ void insertArrayInt(ArrayInt* a, int element)
if (a->used == a->size) if (a->used == a->size)
{ {
a->size *= 2; 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; a->array[a->used++] = element;
} }
void freeArrayInt(ArrayInt* a) void freeArrayInt(ArrayInt* a)
{ {
MemFree(a->array); VOX_FREE(a->array);
a->array = NULL; a->array = NULL;
a->used = a->size = 0; a->used = a->size = 0;
} }
@ -183,7 +197,7 @@ void freeArrayInt(ArrayInt* a)
void initArrayUShort(ArrayUShort* a, int initialSize) 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->used = 0;
a->size = initialSize; a->size = initialSize;
} }
@ -193,14 +207,14 @@ void insertArrayUShort(ArrayUShort* a, unsigned short element)
if (a->used == a->size) if (a->used == a->size)
{ {
a->size *= 2; 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; a->array[a->used++] = element;
} }
void freeArrayUShort(ArrayUShort* a) void freeArrayUShort(ArrayUShort* a)
{ {
MemFree(a->array); VOX_FREE(a->array);
a->array = NULL; a->array = NULL;
a->used = a->size = 0; a->used = a->size = 0;
} }
@ -212,24 +226,24 @@ void freeArrayUShort(ArrayUShort* a)
void initArrayVector3(ArrayVector3* a, int initialSize) void initArrayVector3(ArrayVector3* a, int initialSize)
{ {
a->array = MemAlloc(initialSize * sizeof(Vector3)); a->array = VOX_MALLOC(initialSize * sizeof(VoxVector3));
a->used = 0; a->used = 0;
a->size = initialSize; a->size = initialSize;
} }
void insertArrayVector3(ArrayVector3* a, Vector3 element) void insertArrayVector3(ArrayVector3* a, VoxVector3 element)
{ {
if (a->used == a->size) if (a->used == a->size)
{ {
a->size *= 2; 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; a->array[a->used++] = element;
} }
void freeArrayVector3(ArrayVector3* a) void freeArrayVector3(ArrayVector3* a)
{ {
MemFree(a->array); VOX_FREE(a->array);
a->array = NULL; a->array = NULL;
a->used = a->size = 0; a->used = a->size = 0;
} }
@ -240,24 +254,24 @@ void freeArrayVector3(ArrayVector3* a)
void initArrayColor(ArrayColor* a, int initialSize) void initArrayColor(ArrayColor* a, int initialSize)
{ {
a->array = MemAlloc(initialSize * sizeof(Color)); a->array = VOX_MALLOC(initialSize * sizeof(VoxColor));
a->used = 0; a->used = 0;
a->size = initialSize; a->size = initialSize;
} }
void insertArrayColor(ArrayColor* a, Color element) void insertArrayColor(ArrayColor* a, VoxColor element)
{ {
if (a->used == a->size) if (a->used == a->size)
{ {
a->size *= 2; 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; a->array[a->used++] = element;
} }
void freeArrayColor(ArrayColor* a) void freeArrayColor(ArrayColor* a)
{ {
MemFree(a->array); VOX_FREE(a->array);
a->array = NULL; a->array = NULL;
a->used = a->size = 0; a->used = a->size = 0;
} }
@ -300,7 +314,7 @@ const int fv[6][4] = {
{4, 6, 7, 5 } };//+Z {4, 6, 7, 5 } };//+Z
const Vector3 SolidVertex[] = { const VoxVector3 SolidVertex[] = {
{0, 0, 0}, //0 {0, 0, 0}, //0
{1, 0, 0}, //1 {1, 0, 0}, //1
{0, 1, 0}, //2 {0, 1, 0}, //2
@ -315,7 +329,7 @@ const Vector3 SolidVertex[] = {
// Allocated VoxArray3D size // 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 sx = _sx + ((CHUNKSIZE - (_sx % CHUNKSIZE)) % CHUNKSIZE);
int sy = _sy + ((CHUNKSIZE - (_sy % 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 chy = sy >> CHUNKSIZE_OPSHIFT; //Chunks Count in Y
int chz = sz >> CHUNKSIZE_OPSHIFT; //Chunks Count in Z int chz = sz >> CHUNKSIZE_OPSHIFT; //Chunks Count in Z
//VoxArray3D* parray = (VoxArray3D*)MemAlloc(sizeof(VoxArray3D)); //VoxArray3D* parray = (VoxArray3D*)VOX_MALLOC(sizeof(VoxArray3D));
voxarray->sizeX = sx; pvoxarray->sizeX = sx;
voxarray->sizeY = sy; pvoxarray->sizeY = sy;
voxarray->sizeZ = sz; pvoxarray->sizeZ = sz;
voxarray->chunksSizeX = chx; pvoxarray->chunksSizeX = chx;
voxarray->chunksSizeY = chy; pvoxarray->chunksSizeY = chy;
voxarray->chunksSizeZ = chz; 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 //Alloc chunks array
int size = sizeof(CubeChunk3D) * chx * chy * chz; int size = sizeof(CubeChunk3D) * chx * chy * chz;
voxarray->m_arrayChunks = MemAlloc(size); pvoxarray->m_arrayChunks = VOX_MALLOC(size);
voxarray->arrayChunksSize = size; pvoxarray->arrayChunksSize = size;
//Init chunks array //Init chunks array
size = chx * chy * chz; size = chx * chy * chz;
voxarray->chunksTotal = size; pvoxarray->chunksTotal = size;
voxarray->chunksAllocated = 0; pvoxarray->chunksAllocated = 0;
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
voxarray->m_arrayChunks[i].m_array = 0; pvoxarray->m_arrayChunks[i].m_array = 0;
voxarray->m_arrayChunks[i].arraySize = 0; pvoxarray->m_arrayChunks[i].arraySize = 0;
} }
} }
// Set voxel ID from its position into VoxArray3D // 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 //Get chunk from array pos
int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE; int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE; int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
int chZ = z >> CHUNKSIZE_OPSHIFT; //z / 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) //if (offset > voxarray->arrayChunksSize)
//{ //{
// TraceLog(LOG_ERROR, "Out of array"); // TraceLog(LOG_ERROR, "Out of array");
//} //}
CubeChunk3D* chunk = &voxarray->m_arrayChunks[offset]; CubeChunk3D* chunk = &pvoxarray->m_arrayChunks[offset];
//Set Chunk //Set Chunk
chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE); 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) if (chunk->m_array == 0)
{ {
int size = CHUNKSIZE * CHUNKSIZE * CHUNKSIZE; int size = CHUNKSIZE * CHUNKSIZE * CHUNKSIZE;
chunk->m_array = MemAlloc(size); chunk->m_array = VOX_MALLOC(size);
chunk->arraySize = 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; 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 // 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) if (x < 0 || y < 0 || z < 0)
return 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; 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 chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE; int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
int chZ = z >> CHUNKSIZE_OPSHIFT; //z / 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) //if (offset > voxarray->arrayChunksSize)
//{ //{
// TraceLog(LOG_ERROR, "Out of array"); // TraceLog(LOG_ERROR, "Out of array");
//} //}
CubeChunk3D* chunk = &voxarray->m_arrayChunks[offset]; CubeChunk3D* chunk = &pvoxarray->m_arrayChunks[offset];
//Set Chunk //Set Chunk
chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE); 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 // 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; float scale = 0.25;
Vector3 vtx = SolidVertex[_nNumVertex]; VoxVector3 vtx = SolidVertex[_nNumVertex];
vtx.x = (vtx.x + _wcx) * scale; vtx.x = (vtx.x + _wcx) * scale;
vtx.y = (vtx.y + _wcy) * scale; vtx.y = (vtx.y + _wcy) * scale;
vtx.z = (vtx.z + _wcz) * 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; return;
int i, j; int i, j;
Vector3 vertComputed[8]; VoxVector3 vertComputed[8];
int bVertexComputed[8]; int bVertexComputed[8];
memset(vertComputed, 0, sizeof(vertComputed)); memset(vertComputed, 0, sizeof(vertComputed));
memset(bVertexComputed, 0, sizeof(bVertexComputed)); 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[v2]);
insertArrayVector3(&pvoxArray->vertices, vertComputed[v3]); insertArrayVector3(&pvoxArray->vertices, vertComputed[v3]);
Color col = pvoxArray->palette[matID]; VoxColor col = pvoxArray->palette[matID];
insertArrayColor(&pvoxArray->colors, col); insertArrayColor(&pvoxArray->colors, col);
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 // 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 long signature;
unsigned int readed = 0; unsigned char* fileData = pvoxData;
unsigned char* fileData;
fileData = LoadFileData(pszfileName, &readed);
if (fileData == 0)
{
return VOX_ERROR_FILE_NOT_FOUND;
}
unsigned char* fileDataPtr = fileData; unsigned char* fileDataPtr = fileData;
unsigned char* endfileDataPtr = fileData + readed; unsigned char* endfileDataPtr = fileData + voxDataSize;
signature = *((unsigned long *)fileDataPtr); signature = *((unsigned long *)fileDataPtr);
fileDataPtr += sizeof(unsigned long); fileDataPtr += sizeof(unsigned long);
if (signature != 0x20584F56) //56 4F 58 20 if (signature != 0x20584F56) //56 4F 58 20
{ {
//TraceLog(LOG_ERROR, "Not an MagicaVoxel File format"); return VOX_ERROR_INVALID_FORMAT; //"Not an MagicaVoxel File format"
return VOX_ERROR_INVALID_FORMAT;
} }
unsigned long version; unsigned long version;
@ -603,8 +610,7 @@ int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
if (version < 150) if (version < 150)
{ {
//TraceLog(LOG_ERROR, "MagicaVoxel version too old"); return VOX_ERROR_FILE_VERSION_TOO_OLD; //"MagicaVoxel version too old"
return VOX_ERROR_FILE_VERSION_TOO_OLD;
} }
@ -651,7 +657,7 @@ int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
fileDataPtr += sizeof(unsigned long); fileDataPtr += sizeof(unsigned long);
//Alloc vox array //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) else if (strcmp(szChunkName, "XYZI") == 0)
{ {
@ -669,14 +675,14 @@ int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
vz = *((unsigned char*)fileDataPtr++); vz = *((unsigned char*)fileDataPtr++);
vi = *((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--; numVoxels--;
} }
} }
else if (strcmp(szChunkName, "RGBA") == 0) else if (strcmp(szChunkName, "RGBA") == 0)
{ {
Color col; VoxColor col;
//(each pixel: 1 byte x 4 : r, g, b, a ) x 256 //(each pixel: 1 byte x 4 : r, g, b, a ) x 256
for (int i = 0; i < 256 - 1; i++) 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.b = *((unsigned char*)fileDataPtr++);
col.a = *((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 Size : %dx%dx%d", sizeX, sizeY, sizeZ));
//TraceLog(LOG_INFO, TextFormat("Vox Chunks Count : %d/%d", pvoxArray->chunksAllocated, pvoxArray->chunksTotal)); //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)); //TraceLog(LOG_INFO, TextFormat("Building VOX Mesh : %s", pszfileName));
// Init Arrays // Init Arrays
initArrayVector3(&voxarray->vertices, 3 * 1024); initArrayVector3(&pvoxarray->vertices, 3 * 1024);
initArrayUShort(&voxarray->indices, 3 * 1024); initArrayUShort(&pvoxarray->indices, 3 * 1024);
initArrayColor(&voxarray->colors, 3 * 1024); initArrayColor(&pvoxarray->colors, 3 * 1024);
// Create vertices and indices buffers // Create vertices and indices buffers
int x, y, z; 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) 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) if (chunk->m_array != 0)
{ {
chunk->arraySize = 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->m_arrayChunks = 0;
voxarray->arrayChunksSize = 0; voxarray->arrayChunksSize = 0;

View File

@ -74,7 +74,19 @@
#endif #endif
#if defined(SUPPORT_FILEFORMAT_VOX) #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 #define VOX_LOADER_IMPLEMENTATION
#include "external/vox_loader.h" // vox file format loading (MagikaVoxel) #include "external/vox_loader.h" // vox file format loading (MagikaVoxel)
@ -5529,24 +5541,38 @@ static void GetGLTFPrimitiveCount(cgltf_node *node, int *outCount)
#endif #endif
#if defined(SUPPORT_FILEFORMAT_VOX) #if defined(SUPPORT_FILEFORMAT_VOX)
// Load VOX (MagikaVoxel) mesh data // Load VOX (MagicaVoxel) mesh data
static Model LoadVOX(const char *fileName) static Model LoadVOX(const char *fileName)
{ {
Model model = { 0 }; Model model = { 0 };
int nbvertices = 0; int nbvertices = 0;
int meshescount = 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 }; VoxArray3D voxarray = { 0 };
int ret = Vox_LoadFileName(fileName, &voxarray); int ret = Vox_LoadFromMemory(fileData, readed, &voxarray);
if (ret != VOX_SUCCESS) if (ret != VOX_SUCCESS)
{ {
// Error
UnloadFileData(fileData);
TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load VOX data", fileName); TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load VOX data", fileName);
return model; return model;
} }
else else
{ {
// Compute meshes count // Success: Compute meshes count
nbvertices = voxarray.vertices.used; nbvertices = voxarray.vertices.used;
meshescount = 1 + (nbvertices/65536); meshescount = 1 + (nbvertices/65536);
@ -5611,7 +5637,9 @@ static Model LoadVOX(const char *fileName)
pcolors += verticesMax; pcolors += verticesMax;
} }
//Free buffers
Vox_FreeArrays(&voxarray); Vox_FreeArrays(&voxarray);
UnloadFileData(fileData);
return model; return model;
} }