Logo

index : raylib-jai

Bindings from https://solarium.technology

  • summary
  • about
  • tree
  • log
  • branches
<< path: root/public/raylib-jai.git/html/Raylib/raylib/src/external/vox_loader.h blob: 6d933907c87d4237eed22cf58fbcf4b6590ee22d [raw] [clear marker]

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