55 #define VOX_MALLOC(sz) malloc(sz)
58 #define VOX_CALLOC(n,sz) calloc(n,sz)
61 #define VOX_REALLOC(n,sz) realloc(n,sz)
64 #define VOX_FREE(p) free(p)
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_TOO_OLD (-3)
74 unsigned char r, g, b,
a;
134#if defined(__cplusplus)
156#ifdef VOX_LOADER_IMPLEMENTATION
165static void initArrayUShort(
ArrayUShort* a,
int initialSize)
169 a->
size = initialSize;
172static void insertArrayUShort(
ArrayUShort* a,
unsigned short element)
194static void initArrayVector3(
ArrayVector3* a,
int initialSize)
198 a->
size = initialSize;
222static void initArrayColor(
ArrayColor* a,
int initialSize)
226 a->
size = initialSize;
252#define CHUNKSIZE_OPSHIFT 4
253#define CHUNK_FLATTENOFFSET_OPSHIFT 8
275const int fv[6][4] = {
296static void Vox_AllocArray(
VoxArray3D* pvoxarray,
int _sx,
int _sy,
int _sz)
298 int sx = _sx + ((CHUNKSIZE - (_sx % CHUNKSIZE)) % CHUNKSIZE);
299 int sy = _sy + ((CHUNKSIZE - (_sy % CHUNKSIZE)) % CHUNKSIZE);
300 int sz = _sz + ((CHUNKSIZE - (_sz % CHUNKSIZE)) % CHUNKSIZE);
302 int chx = sx >> CHUNKSIZE_OPSHIFT;
303 int chy = sy >> CHUNKSIZE_OPSHIFT;
304 int chz = sz >> CHUNKSIZE_OPSHIFT;
307 pvoxarray->sizeX = sx;
308 pvoxarray->sizeY = sy;
309 pvoxarray->sizeZ = sz;
311 pvoxarray->chunksSizeX = chx;
312 pvoxarray->chunksSizeY = chy;
313 pvoxarray->chunksSizeZ = chz;
315 pvoxarray->ChunkFlattenOffset = (chy * chz);
320 pvoxarray->arrayChunksSize = size;
323 size = chx * chy * chz;
324 pvoxarray->chunksTotal = size;
325 pvoxarray->chunksAllocated = 0;
327 for (
int i = 0; i < size; i++)
329 pvoxarray->m_arrayChunks[i].m_array = 0;
330 pvoxarray->m_arrayChunks[i].arraySize = 0;
335static void Vox_SetVoxel(
VoxArray3D* pvoxarray,
int x,
int y,
int z,
unsigned char id)
338 int chX = x >> CHUNKSIZE_OPSHIFT;
339 int chY = y >> CHUNKSIZE_OPSHIFT;
340 int chZ = z >> CHUNKSIZE_OPSHIFT;
351 chX = x - (chX << CHUNKSIZE_OPSHIFT);
352 chY = y - (chY << CHUNKSIZE_OPSHIFT);
353 chZ = z - (chZ << CHUNKSIZE_OPSHIFT);
357 int size = CHUNKSIZE * CHUNKSIZE * CHUNKSIZE;
360 memset(chunk->
m_array, 0, size);
365 offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY;
376static unsigned char Vox_GetVoxel(
VoxArray3D* pvoxarray,
int x,
int y,
int z)
378 if (x < 0 || y < 0 || z < 0)
return 0;
380 if (x >= pvoxarray->
sizeX || y >= pvoxarray->
sizeY || z >= pvoxarray->
sizeZ)
return 0;
383 int chX = x >> CHUNKSIZE_OPSHIFT;
384 int chY = y >> CHUNKSIZE_OPSHIFT;
385 int chZ = z >> CHUNKSIZE_OPSHIFT;
396 chX = x - (chX << CHUNKSIZE_OPSHIFT);
397 chY = y - (chY << CHUNKSIZE_OPSHIFT);
398 chZ = z - (chZ << CHUNKSIZE_OPSHIFT);
405 offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY;
416static unsigned char Vox_CalcFacesVisible(
VoxArray3D* pvoxArray,
int cx,
int cy,
int cz)
418 unsigned char idXm1 = Vox_GetVoxel(pvoxArray, cx - 1, cy, cz);
419 unsigned char idXp1 = Vox_GetVoxel(pvoxArray, cx + 1, cy, cz);
421 unsigned char idYm1 = Vox_GetVoxel(pvoxArray, cx, cy - 1, cz);
422 unsigned char idYp1 = Vox_GetVoxel(pvoxArray, cx, cy + 1, cz);
424 unsigned char idZm1 = Vox_GetVoxel(pvoxArray, cx, cy, cz - 1);
425 unsigned char idZp1 = Vox_GetVoxel(pvoxArray, cx, cy, cz + 1);
427 unsigned char byVFMask = 0;
430 if (idXm1 == 0) byVFMask |= (1 << 0);
433 if (idXp1 == 0) byVFMask |= (1 << 1);
436 if (idYm1 == 0) byVFMask |= (1 << 2);
439 if (idYp1 == 0) byVFMask |= (1 << 3);
442 if (idZm1 == 0) byVFMask |= (1 << 4);
445 if (idZp1 == 0) byVFMask |= (1 << 5);
451static VoxVector3 Vox_GetVertexPosition(
int _wcx,
int _wcy,
int _wcz,
int _nNumVertex)
456 vtx.
x = (vtx.
x + _wcx) * scale;
457 vtx.
y = (vtx.
y + _wcy) * scale;
458 vtx.
z = (vtx.
z + _wcz) * scale;
464static void Vox_Build_Voxel(
VoxArray3D* pvoxArray,
int x,
int y,
int z,
int matID)
466 unsigned char byVFMask = Vox_CalcFacesVisible(pvoxArray, x, y, z);
468 if (byVFMask == 0)
return;
472 int bVertexComputed[8];
473 memset(vertComputed, 0,
sizeof(vertComputed));
474 memset(bVertexComputed, 0,
sizeof(bVertexComputed));
477 for (i = 0; i < 6; i++)
479 if ((byVFMask & (1 << i)) != 0)
481 for (j = 0; j < 4; j++)
483 int nNumVertex = fv[i][j];
484 if (bVertexComputed[nNumVertex] == 0)
486 bVertexComputed[nNumVertex] = 1;
487 vertComputed[nNumVertex] = Vox_GetVertexPosition(x, y, z, nNumVertex);
494 for (i = 0; i < 6; i++)
496 if ((byVFMask & (1 << i)) == 0)
506 insertArrayVector3(&pvoxArray->
vertices, vertComputed[v0]);
507 insertArrayVector3(&pvoxArray->
vertices, vertComputed[v1]);
508 insertArrayVector3(&pvoxArray->
vertices, vertComputed[v2]);
509 insertArrayVector3(&pvoxArray->
vertices, vertComputed[v3]);
513 insertArrayColor(&pvoxArray->
colors, col);
514 insertArrayColor(&pvoxArray->
colors, col);
515 insertArrayColor(&pvoxArray->
colors, col);
516 insertArrayColor(&pvoxArray->
colors, col);
520 insertArrayUShort(&pvoxArray->
indices, idx + 0);
521 insertArrayUShort(&pvoxArray->
indices, idx + 2);
522 insertArrayUShort(&pvoxArray->
indices, idx + 1);
524 insertArrayUShort(&pvoxArray->
indices, idx + 0);
525 insertArrayUShort(&pvoxArray->
indices, idx + 3);
526 insertArrayUShort(&pvoxArray->
indices, idx + 2);
541 unsigned char signature[4] = { 0 };
543 unsigned char* fileData = pvoxData;
544 unsigned char* fileDataPtr = fileData;
545 unsigned char* endfileDataPtr = fileData + voxDataSize;
547 signature[0] = fileDataPtr[0];
548 signature[1] = fileDataPtr[1];
549 signature[2] = fileDataPtr[2];
550 signature[3] = fileDataPtr[3];
553 if ((signature[0] !=
'V') && (signature[0] !=
'O') && (signature[0] !=
'X') && (signature[0] !=
' '))
559 unsigned int version = 0;
560 version = ((
unsigned int*)fileDataPtr)[0];
580 unsigned int sizeX, sizeY, sizeZ;
581 sizeX = sizeY = sizeZ = 0;
582 unsigned int numVoxels = 0;
584 while (fileDataPtr < endfileDataPtr)
587 memcpy(szChunkName, fileDataPtr, 4);
591 unsigned int chunkSize = *((
unsigned int*)fileDataPtr);
592 fileDataPtr +=
sizeof(
unsigned int);
595 fileDataPtr +=
sizeof(
unsigned int);
597 if (strcmp(szChunkName,
"SIZE") == 0)
600 sizeX = *((
unsigned int*)fileDataPtr);
601 fileDataPtr +=
sizeof(
unsigned int);
603 sizeY = *((
unsigned int*)fileDataPtr);
604 fileDataPtr +=
sizeof(
unsigned int);
606 sizeZ = *((
unsigned int*)fileDataPtr);
607 fileDataPtr +=
sizeof(
unsigned int);
610 Vox_AllocArray(pvoxarray, sizeX, sizeZ, sizeY);
612 else if (strcmp(szChunkName,
"XYZI") == 0)
614 unsigned char vx, vy, vz, vi;
618 numVoxels = *((
unsigned int*)fileDataPtr);
619 fileDataPtr +=
sizeof(
unsigned int);
621 while (numVoxels > 0)
623 vx = *((
unsigned char*)fileDataPtr++);
624 vy = *((
unsigned char*)fileDataPtr++);
625 vz = *((
unsigned char*)fileDataPtr++);
626 vi = *((
unsigned char*)fileDataPtr++);
628 Vox_SetVoxel(pvoxarray, vx, vz, pvoxarray->
sizeZ-vy-1, vi);
633 else if (strcmp(szChunkName,
"RGBA") == 0)
638 for (
int i = 0; i < 256 - 1; i++)
640 col.
r = *((
unsigned char*)fileDataPtr++);
641 col.
g = *((
unsigned char*)fileDataPtr++);
642 col.
b = *((
unsigned char*)fileDataPtr++);
643 col.
a = *((
unsigned char*)fileDataPtr++);
645 pvoxarray->
palette[i + 1] = col;
651 fileDataPtr += chunkSize;
660 initArrayVector3(&pvoxarray->
vertices, 3 * 1024);
661 initArrayUShort(&pvoxarray->
indices, 3 * 1024);
662 initArrayColor(&pvoxarray->
colors, 3 * 1024);
667 for (x = 0; x <= pvoxarray->
sizeX; x++)
669 for (z = 0; z <= pvoxarray->
sizeZ; z++)
671 for (y = 0; y <= pvoxarray->
sizeY; y++)
673 unsigned char matID = Vox_GetVoxel(pvoxarray, x, y, z);
675 Vox_Build_Voxel(pvoxarray, x, y, z, matID);
710 freeArrayVector3(&voxarray->
vertices);
711 freeArrayUShort(&voxarray->
indices);
712 freeArrayColor(&voxarray->
colors);
CubeChunk3D * m_arrayChunks
#define VOX_ERROR_INVALID_FORMAT
int Vox_LoadFromMemory(unsigned char *pvoxData, unsigned int voxDataSize, VoxArray3D *pvoxarray)
#define VOX_ERROR_FILE_VERSION_TOO_OLD
#define VOX_REALLOC(n, sz)
void Vox_FreeArrays(VoxArray3D *voxarray)