@ -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 "magica voxel _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 ( 32 bit )
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 ;
VoxV ector3 * array ;
int used , size ;
} ArrayVector3 ;
typedef struct
{
Color * array ;
Vox Color* array ;
int used , size ;
} ArrayColor ;
@ -118,13 +132,13 @@ extern "C" {
ArrayColor colors ;
/ / Palette for voxels
Color palette [ 256 ] ;
Vox Color palette [ 256 ] ;
} VoxArray3D ;
/ / Functions
extern int Vox_LoadFileName ( const char * pszfileNam e , VoxArray3D * voxarray ) ;
extern int Vox_LoadFromMemory ( const unsigned char* pvoxData , unsigned int voxDataSiz e , VoxArray3D * p voxarray) ;
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 ( Vox Vector3) ) ;
a - > used = 0 ;
a - > size = initialSize ;
}
void insertArrayVector3 ( ArrayVector3 * a , Vector3 element )
void insertArrayVector3 ( ArrayVector3 * a , VoxV ector3 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 ( Vox Vector3) ) ;
}
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 ( Vox Color) ) ;
a - > used = 0 ;
a - > size = initialSize ;
}
void insertArrayColor ( ArrayColor * a , Color element )
void insertArrayColor ( ArrayColor * a , Vox Color 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 ( Vox Color) ) ;
}
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 VoxV ector3 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 * p voxarray, 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 ) ) ;
p voxarray- > sizeX = sx ;
p voxarray- > sizeY = sy ;
p voxarray- > sizeZ = sz ;
voxarray - > chunksSizeX = chx ;
voxarray - > chunksSizeY = chy ;
voxarray - > chunksSizeZ = chz ;
p voxarray- > chunksSizeX = chx ;
p voxarray- > chunksSizeY = chy ;
p voxarray- > chunksSizeZ = chz ;
voxarray - > ChunkFlattenOffset = ( chy * chz ) ; / / m_arrayChunks [ ( x * ( sy * sz ) ) + ( z * sy ) + y ]
p voxarray- > 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 ;
p voxarray- > m_arrayChunks = VOX_MALLOC ( size ) ;
p voxarray- > arrayChunksSize = size ;
/ / Init chunks array
size = chx * chy * chz ;
voxarray - > chunksTotal = size ;
voxarray - > chunksAllocated = 0 ;
p voxarray- > chunksTotal = size ;
p voxarray- > chunksAllocated = 0 ;
for ( int i = 0 ; i < size ; i + + )
{
voxarray - > m_arrayChunks [ i ] . m_array = 0 ;
voxarray - > m_arrayChunks [ i ] . arraySize = 0 ;
p voxarray- > m_arrayChunks [ i ] . m_array = 0 ;
p voxarray- > 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 * p voxarray, 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 * p voxarray- > ChunkFlattenOffset ) + ( chZ * p voxarray- > chunksSizeY ) + chY ;
/ / if ( offset > voxarray - > arrayChunksSize )
/ / {
/ / TraceLog ( LOG_ERROR , " Out of array " ) ;
/ / }
CubeChunk3D * chunk = & voxarray - > m_arrayChunks [ offset ] ;
CubeChunk3D * chunk = & p voxarray- > 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 ;
o">/ / memset ( chunk - > m_array , 0 , size ) ;
memset ( chunk - > m_array , 0 , size ) ;
voxarray - > chunksAllocated + + ;
p voxarray- > 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 * p voxarray, 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 > = p voxarray- > sizeX | | y > = p voxarray- > sizeY | | z > = p voxarray- > 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 * p voxarray- > ChunkFlattenOffset ) + ( chZ * p voxarray- > chunksSizeY ) + chY ;
/ / if ( offset > voxarray - > arrayChunksSize )
/ / {
/ / TraceLog ( LOG_ERROR , " Out of array " ) ;
/ / }
CubeChunk3D * chunk = & voxarray - > m_arrayChunks [ offset ] ;
CubeChunk3D * chunk = & p voxarray- > 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 )
VoxV ector3 Vox_GetVertexPosition ( int _wcx , int _wcy , int _wcz , int _nNumVertex )
{
float scale = 0.25 ;
Vector3 vtx = SolidVertex [ _nNumVertex ] ;
VoxV ector3 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 ] ;
VoxV ector3 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 ] ;
Vox Color 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 * pszfileNam e , VoxArray3D * voxarray )
int Vox_LoadFromMemory ( const unsigned char* pvoxData , unsigned int voxDataSiz e , VoxArray3D * p voxarray)
{
/ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
@ -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 ( p voxarray, 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 ( p voxarray, 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 ;
Vox Color 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 ;
p voxarray- > 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 ( & p voxarray- > vertices , 3 * 1024 ) ;
initArrayUShort ( & p voxarray- > indices , 3 * 1024 ) ;
initArrayColor ( & p voxarray- > colors , 3 * 1024 ) ;
/ / Create vertices and indices buffers
int x , y , z ;
for ( x = 0 ; x < = voxarray - > sizeX ; x + + )
for ( x = 0 ; x < = p voxarray- > sizeX ; x + + )
{
for ( z = 0 ; z < = voxarray - > sizeZ ; z + + )
for ( z = 0 ; z < = p voxarray- > sizeZ ; z + + )
{
for ( y = 0 ; y < = voxarray - > sizeY ; y + + )
for ( y = 0 ; y < = p voxarray- > sizeY ; y + + )
{
unsigned char matID = Vox_GetVoxel ( voxarray , x , y , z ) ;
unsigned char matID = Vox_GetVoxel ( p voxarray, x , y , z ) ;
if ( matID ! = 0 )
Vox_Build_Voxel ( voxarray , x , y , z , matID ) ;
Vox_Build_Voxel ( p voxarray, 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 ;