github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/tests/raylib/external/vox_loader.h (about)

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