ezEngine  Release 25.03
ogt_vox.h
1 /*
2  opengametools vox file reader/writer - v0.6 - MIT license - Justin Paver, Oct 2019
3 
4  This is a single-header-file library that provides easy-to-use
5  support for reading MagicaVoxel .vox files into structures that
6  are easy to dereference and extract information from. It also
7  supports writing back out to .vox file from those structures.
8 
9  Please see the MIT license information at the end of this file.
10 
11  Also, please consider sharing any improvements you make.
12 
13  For more information and more tools, visit:
14  https://github.com/jpaver/opengametools
15 
16  HOW TO COMPILE THIS LIBRARY
17 
18  1. To compile this library, do this in *one* C or C++ file:
19  #define OGT_VOX_IMPLEMENTATION
20  #include "ogt_vox.h"
21 
22  2. From any other module, it is sufficient to just #include this as usual:
23  #include "ogt_vox.h"
24 
25  HOW TO READ A VOX SCENE (See demo_vox.cpp)
26 
27  1. load a .vox file off disk into a memory buffer.
28 
29  2. construct a scene from the memory buffer:
30  ogt_vox_scene* scene = ogt_vox_read_scene(buffer, buffer_size);
31 
32  3. use the scene members to extract the information you need. eg.
33  printf("# of layers: %u\n", scene->num_layers );
34 
35  4. destroy the scene:
36  ogt_vox_destroy_scene(scene);
37 
38  HOW TO MERGE MULTIPLE VOX SCENES (See merge_vox.cpp)
39 
40  1. construct multiple scenes from files you want to merge.
41 
42  // read buffer1/buffer_size1 from "test1.vox"
43  // read buffer2/buffer_size2 from "test2.vox"
44  // read buffer3/buffer_size3 from "test3.vox"
45  ogt_vox_scene* scene1 = ogt_vox_read_scene(buffer1, buffer_size1);
46  ogt_vox_scene* scene2 = ogt_vox_read_scene(buffer2, buffer_size2);
47  ogt_vox_scene* scene3 = ogt_vox_read_scene(buffer3, buffer_size3);
48 
49  2. construct a merged scene
50 
51  const ogt_vox_scene* scenes[] = {scene1, scene2, scene3};
52  ogt_vox_scene* merged_scene = ogt_vox_merge_scenes(scenes, 3, NULL, 0);
53 
54  3. save out the merged scene
55 
56  uint8_t* out_buffer = ogt_vox_write_scene(merged_scene, &out_buffer_size);
57  // save out_buffer to disk as a .vox file (it has length out_buffer_size)
58 
59  4. destroy the merged scene:
60 
61  ogt_vox_destroy_scene(merged_scene);
62 
63  EXPLANATION OF SCENE ELEMENTS:
64 
65  A ogt_vox_scene comprises primarily a set of instances, models, layers and a palette.
66 
67  A ogt_vox_palette contains a set of 256 colors that is used for the scene.
68  Each color is represented by a 4-tuple called an ogt_vox_rgba which contains red,
69  green, blue and alpha values for the color.
70 
71  A ogt_vox_model is a 3-dimensional grid of voxels, where each of those voxels
72  is represented by an 8-bit color index. Voxels are arranged in order of increasing
73  X then increasing Y then increasing Z.
74 
75  Given the x,y,z values for a voxel within the model dimensions, the voxels index
76  in the grid can be obtained as follows:
77 
78  voxel_index = x + (y * model->size_x) + (z * model->size_x * model->size_y)
79 
80  The index is only valid if the coordinate x,y,z satisfy the following conditions:
81  0 <= x < model->size_x -AND-
82  0 <= y < model->size_y -AND-
83  0 <= z < model->size_z
84 
85  A voxels color index can be obtained as follows:
86 
87  uint8_t color_index = model->voxel_data[voxel_index];
88 
89  If color_index == 0, the voxel is not solid and can be skipped,
90  If color_index != 0, the voxel is solid and can be used to lookup the color in the palette:
91 
92  ogt_vox_rgba color = scene->palette.color[ color_index]
93 
94  A ogt_vox_instance is an individual placement of a voxel model within the scene. Each
95  instance has a transform that determines its position and orientation within the scene,
96  but it also has an index that specifies which model the instance uses for its shape. It
97  is expected that there is a many-to-one mapping of instances to models.
98 
99  An ogt_vox_layer is used to conceptually group instances. Each instance indexes the
100  layer that it belongs to, but the layer itself has its own name and hidden/shown state.
101 
102  EXPLANATION OF MERGED SCENES:
103 
104  A merged scene contains all the models and all the scene instances from
105  each of the scenes that were passed into it.
106 
107  The merged scene will have a combined palette of all the source scene
108  palettes by trying to match existing colors exactly, and falling back
109  to an RGB-distance matched color when all 256 colors in the merged
110  scene palette has been allocated.
111 
112  You can explicitly control up to 255 merge palette colors by providing
113  those colors to ogt_vox_merge_scenes in the required_colors parameters eg.
114 
115  const ogt_vox_palette palette; // load this via .vox or procedurally or whatever
116  const ogt_vox_scene* scenes[] = {scene1, scene2, scene3};
117  // palette.color[0] is always the empty color which is why we pass 255 colors starting from index 1 only:
118  ogt_vox_scene* merged_scene = ogt_vox_merge_scenes(scenes, 3, &palette.color[1], 255);
119 */
120 #ifndef OGT_VOX_H__
121 # define OGT_VOX_H__
122 
123 # if _MSC_VER == 1400
124 // VS2005 doesn't have inttypes or stdint so we just define what we need here.
125 typedef unsigned char uint8_t;
126 typedef signed int int32_t;
127 typedef unsigned int uint32_t;
128 # ifndef UINT32_MAX
129 # define UINT32_MAX ((uint32_t)0xFFFFFFFF)
130 # endif
131 # ifndef INT32_MAX
132 # define INT32_MAX ((int32_t)0x7FFFFFFF)
133 # endif
134 # ifndef UINT8_MAX
135 # define UINT8_MAX ((uint8_t)0xFF)
136 # endif
137 # elif defined(_MSC_VER)
138 // general VS*
139 # include <inttypes.h>
140 # elif __APPLE__
141 // general Apple compiler
142 # elif defined(__GNUC__)
143 // any GCC*
144 # include <inttypes.h>
145 # include <stdlib.h> // for size_t
146 # else
147 # error some fixup needed for this platform?
148 # endif
149 
150 // denotes an invalid group index. Usually this is only applicable to the scene's root group's parent.
151 static const uint32_t k_invalid_group_index = UINT32_MAX;
152 
153 // color
154 typedef struct ogt_vox_rgba
155 {
156  uint8_t r, g, b, a; // red, green, blue and alpha components of a color.
157 } ogt_vox_rgba;
158 
159 // column-major 4x4 matrix
160 typedef struct ogt_vox_transform
161 {
162  float m00, m01, m02, m03; // column 0 of 4x4 matrix, 1st three elements = x axis vector, last element always 0.0
163  float m10, m11, m12, m13; // column 1 of 4x4 matrix, 1st three elements = y axis vector, last element always 0.0
164  float m20, m21, m22, m23; // column 2 of 4x4 matrix, 1st three elements = z axis vector, last element always 0.0
165  float m30, m31, m32, m33; // column 3 of 4x4 matrix. 1st three elements = translation vector, last element always 1.0
167 
168 // a palette of colors
169 typedef struct ogt_vox_palette
170 {
171  ogt_vox_rgba color[256]; // palette of colors. use the voxel indices to lookup color from the palette.
173 
174 // a 3-dimensional model of voxels
175 typedef struct ogt_vox_model
176 {
177  uint32_t size_x; // number of voxels in the local x dimension
178  uint32_t size_y; // number of voxels in the local y dimension
179  uint32_t size_z; // number of voxels in the local z dimension
180  uint32_t voxel_hash; // hash of the content of the grid.
181  const uint8_t* voxel_data; // grid of voxel data comprising color indices in x -> y -> z order. a color index of 0 means empty, all other indices mean solid and can be used to index the scene's palette to obtain the color for the voxel.
182 } ogt_vox_model;
183 
184 // an instance of a model within the scene
185 typedef struct ogt_vox_instance
186 {
187  const char* name; // name of the instance if there is one, will be NULL otherwise.
188  ogt_vox_transform transform; // orientation and position of this instance within the scene. This is relative to its group local transform if group_index is not 0
189  uint32_t model_index; // index of the model used by this instance. used to lookup the model in the scene's models[] array.
190  uint32_t layer_index; // index of the layer used by this instance. used to lookup the layer in the scene's layers[] array.
191  uint32_t group_index; // this will be the index of the group in the scene's groups[] array. If group is zero it will be the scene root group and the instance transform will be a world-space transform, otherwise the transform is relative to the group.
192  bool hidden; // whether this instance is individually hidden or not. Note: the instance can also be hidden when its layer is hidden, or if it belongs to a group that is hidden.
194 
195 // describes a layer within the scene
196 typedef struct ogt_vox_layer
197 {
198  const char* name; // name of this layer if there is one, will be NULL otherwise.
199  bool hidden; // whether this layer is hidden or not.
200 } ogt_vox_layer;
201 
202 // describes a group within the scene
203 typedef struct ogt_vox_group
204 {
205  ogt_vox_transform transform; // transform of this group relative to its parent group (if any), otherwise this will be relative to world-space.
206  uint32_t parent_group_index; // if this group is parented to another group, this will be the index of its parent in the scene's groups[] array, otherwise this group will be the scene root group and this value will be k_invalid_group_index
207  uint32_t layer_index; // which layer this group belongs to. used to lookup the layer in the scene's layers[] array.
208  bool hidden; // whether this group is hidden or not.
209 } ogt_vox_group;
210 
211 // the scene parsed from a .vox file.
212 typedef struct ogt_vox_scene
213 {
214  uint32_t num_models; // number of models within the scene.
215  uint32_t num_instances; // number of instances in the scene
216  uint32_t num_layers; // number of layers in the scene
217  uint32_t num_groups; // number of groups in the scene
218  const ogt_vox_model** models; // array of models. size is num_models
219  const ogt_vox_instance* instances; // array of instances. size is num_instances
220  const ogt_vox_layer* layers; // array of layers. size is num_layers
221  const ogt_vox_group* groups; // array of groups. size is num_groups
222  ogt_vox_palette palette; // the palette for this scene
223 } ogt_vox_scene;
224 
225 // allocate memory function interface. pass in size, and get a pointer to memory with at least that size available.
226 typedef void* (*ogt_vox_alloc_func)(size_t size);
227 
228 // free memory function interface. pass in a pointer previously allocated and it will be released back to the system managing memory.
229 typedef void (*ogt_vox_free_func)(void* ptr);
230 
231 // override the default scene memory allocator if you need to control memory precisely.
232 void ogt_vox_set_memory_allocator(ogt_vox_alloc_func alloc_func, ogt_vox_free_func free_func);
233 void* ogt_vox_malloc(size_t uiSize);
234 void ogt_vox_free(void* pMem);
235 
236 // flags for ogt_vox_read_scene_with_flags
237 static const uint32_t k_read_scene_flags_groups = 1 << 0; // if not specified, all instance transforms will be flattened into world space. If specified, will read group information and keep all transforms as local transform relative to the group they are in.
238 
239 // creates a scene from a vox file within a memory buffer of a given size.
240 // you can destroy the input buffer once you have the scene as this function will allocate separate memory for the scene objecvt.
241 const ogt_vox_scene* ogt_vox_read_scene(const uint8_t* pBuffer, uint32_t buffer_size);
242 
243 // just like ogt_vox_read_scene, but you can additionally pass a union of k_read_scene_flags
244 const ogt_vox_scene* ogt_vox_read_scene_with_flags(const uint8_t* pBuffer, uint32_t buffer_size, uint32_t read_flags);
245 
246 // destroys a scene object to release its memory.
247 void ogt_vox_destroy_scene(const ogt_vox_scene* pScene);
248 
249 // writes the scene to a new buffer and returns the buffer size. free the buffer with ogt_vox_free
250 uint8_t* ogt_vox_write_scene(const ogt_vox_scene* pScene, uint32_t* pBuffer_size);
251 
252 // merges the specified scenes together to create a bigger scene. Merged scene can be destroyed using ogt_vox_destroy_scene
253 // If you require specific colors in the merged scene palette, provide up to and including 255 of them via required_colors/required_color_count.
254 ogt_vox_scene* ogt_vox_merge_scenes(const ogt_vox_scene** pScenes, uint32_t scene_count, const ogt_vox_rgba* pRequired_colors, const uint32_t required_color_count);
255 
256 #endif // OGT_VOX_H__
257 
258 //-----------------------------------------------------------------------------------------------------------------
259 //
260 // If you're only interested in using this library, everything you need is above this point.
261 // If you're interested in how this library works, everything you need is below this point.
262 //
263 //-----------------------------------------------------------------------------------------------------------------
264 #ifdef OGT_VOX_IMPLEMENTATION
265 # include <assert.h>
266 # include <stdio.h>
267 # include <stdlib.h>
268 # include <string.h>
269 
270 // MAKE_VOX_CHUNK_ID: used to construct a literal to describe a chunk in a .vox file.
271 # define MAKE_VOX_CHUNK_ID(c0, c1, c2, c3) ((c0 << 0) | (c1 << 8) | (c2 << 16) | (c3 << 24))
272 
273 static const uint32_t CHUNK_ID_VOX_ = MAKE_VOX_CHUNK_ID('V', 'O', 'X', ' ');
274 static const uint32_t CHUNK_ID_MAIN = MAKE_VOX_CHUNK_ID('M', 'A', 'I', 'N');
275 static const uint32_t CHUNK_ID_SIZE = MAKE_VOX_CHUNK_ID('S', 'I', 'Z', 'E');
276 static const uint32_t CHUNK_ID_XYZI = MAKE_VOX_CHUNK_ID('X', 'Y', 'Z', 'I');
277 static const uint32_t CHUNK_ID_RGBA = MAKE_VOX_CHUNK_ID('R', 'G', 'B', 'A');
278 static const uint32_t CHUNK_ID_nTRN = MAKE_VOX_CHUNK_ID('n', 'T', 'R', 'N');
279 static const uint32_t CHUNK_ID_nGRP = MAKE_VOX_CHUNK_ID('n', 'G', 'R', 'P');
280 static const uint32_t CHUNK_ID_nSHP = MAKE_VOX_CHUNK_ID('n', 'S', 'H', 'P');
281 static const uint32_t CHUNK_ID_IMAP = MAKE_VOX_CHUNK_ID('I', 'M', 'A', 'P');
282 static const uint32_t CHUNK_ID_LAYR = MAKE_VOX_CHUNK_ID('L', 'A', 'Y', 'R');
283 static const uint32_t CHUNK_ID_MATL = MAKE_VOX_CHUNK_ID('M', 'A', 'T', 'L');
284 static const uint32_t CHUNK_ID_MATT = MAKE_VOX_CHUNK_ID('M', 'A', 'T', 'T');
285 static const uint32_t CHUNK_ID_rOBJ = MAKE_VOX_CHUNK_ID('r', 'O', 'B', 'J');
286 
287 // Some older .vox files will not store a palette, in which case the following palette will be used!
288 static const uint8_t k_default_vox_palette[256 * 4] = {
289  0xff,
290  0xff,
291  0xff,
292  0xff,
293  0xff,
294  0xff,
295  0xcc,
296  0xff,
297  0xff,
298  0xff,
299  0x99,
300  0xff,
301  0xff,
302  0xff,
303  0x66,
304  0xff,
305  0xff,
306  0xff,
307  0x33,
308  0xff,
309  0xff,
310  0xff,
311  0x00,
312  0xff,
313  0xff,
314  0xcc,
315  0xff,
316  0xff,
317  0xff,
318  0xcc,
319  0xcc,
320  0xff,
321  0xff,
322  0xcc,
323  0x99,
324  0xff,
325  0xff,
326  0xcc,
327  0x66,
328  0xff,
329  0xff,
330  0xcc,
331  0x33,
332  0xff,
333  0xff,
334  0xcc,
335  0x00,
336  0xff,
337  0xff,
338  0x99,
339  0xff,
340  0xff,
341  0xff,
342  0x99,
343  0xcc,
344  0xff,
345  0xff,
346  0x99,
347  0x99,
348  0xff,
349  0xff,
350  0x99,
351  0x66,
352  0xff,
353  0xff,
354  0x99,
355  0x33,
356  0xff,
357  0xff,
358  0x99,
359  0x00,
360  0xff,
361  0xff,
362  0x66,
363  0xff,
364  0xff,
365  0xff,
366  0x66,
367  0xcc,
368  0xff,
369  0xff,
370  0x66,
371  0x99,
372  0xff,
373  0xff,
374  0x66,
375  0x66,
376  0xff,
377  0xff,
378  0x66,
379  0x33,
380  0xff,
381  0xff,
382  0x66,
383  0x00,
384  0xff,
385  0xff,
386  0x33,
387  0xff,
388  0xff,
389  0xff,
390  0x33,
391  0xcc,
392  0xff,
393  0xff,
394  0x33,
395  0x99,
396  0xff,
397  0xff,
398  0x33,
399  0x66,
400  0xff,
401  0xff,
402  0x33,
403  0x33,
404  0xff,
405  0xff,
406  0x33,
407  0x00,
408  0xff,
409  0xff,
410  0x00,
411  0xff,
412  0xff,
413  0xff,
414  0x00,
415  0xcc,
416  0xff,
417  0xff,
418  0x00,
419  0x99,
420  0xff,
421  0xff,
422  0x00,
423  0x66,
424  0xff,
425  0xff,
426  0x00,
427  0x33,
428  0xff,
429  0xff,
430  0x00,
431  0x00,
432  0xff,
433  0xcc,
434  0xff,
435  0xff,
436  0xff,
437  0xcc,
438  0xff,
439  0xcc,
440  0xff,
441  0xcc,
442  0xff,
443  0x99,
444  0xff,
445  0xcc,
446  0xff,
447  0x66,
448  0xff,
449  0xcc,
450  0xff,
451  0x33,
452  0xff,
453  0xcc,
454  0xff,
455  0x00,
456  0xff,
457  0xcc,
458  0xcc,
459  0xff,
460  0xff,
461  0xcc,
462  0xcc,
463  0xcc,
464  0xff,
465  0xcc,
466  0xcc,
467  0x99,
468  0xff,
469  0xcc,
470  0xcc,
471  0x66,
472  0xff,
473  0xcc,
474  0xcc,
475  0x33,
476  0xff,
477  0xcc,
478  0xcc,
479  0x00,
480  0xff,
481  0xcc,
482  0x99,
483  0xff,
484  0xff,
485  0xcc,
486  0x99,
487  0xcc,
488  0xff,
489  0xcc,
490  0x99,
491  0x99,
492  0xff,
493  0xcc,
494  0x99,
495  0x66,
496  0xff,
497  0xcc,
498  0x99,
499  0x33,
500  0xff,
501  0xcc,
502  0x99,
503  0x00,
504  0xff,
505  0xcc,
506  0x66,
507  0xff,
508  0xff,
509  0xcc,
510  0x66,
511  0xcc,
512  0xff,
513  0xcc,
514  0x66,
515  0x99,
516  0xff,
517  0xcc,
518  0x66,
519  0x66,
520  0xff,
521  0xcc,
522  0x66,
523  0x33,
524  0xff,
525  0xcc,
526  0x66,
527  0x00,
528  0xff,
529  0xcc,
530  0x33,
531  0xff,
532  0xff,
533  0xcc,
534  0x33,
535  0xcc,
536  0xff,
537  0xcc,
538  0x33,
539  0x99,
540  0xff,
541  0xcc,
542  0x33,
543  0x66,
544  0xff,
545  0xcc,
546  0x33,
547  0x33,
548  0xff,
549  0xcc,
550  0x33,
551  0x00,
552  0xff,
553  0xcc,
554  0x00,
555  0xff,
556  0xff,
557  0xcc,
558  0x00,
559  0xcc,
560  0xff,
561  0xcc,
562  0x00,
563  0x99,
564  0xff,
565  0xcc,
566  0x00,
567  0x66,
568  0xff,
569  0xcc,
570  0x00,
571  0x33,
572  0xff,
573  0xcc,
574  0x00,
575  0x00,
576  0xff,
577  0x99,
578  0xff,
579  0xff,
580  0xff,
581  0x99,
582  0xff,
583  0xcc,
584  0xff,
585  0x99,
586  0xff,
587  0x99,
588  0xff,
589  0x99,
590  0xff,
591  0x66,
592  0xff,
593  0x99,
594  0xff,
595  0x33,
596  0xff,
597  0x99,
598  0xff,
599  0x00,
600  0xff,
601  0x99,
602  0xcc,
603  0xff,
604  0xff,
605  0x99,
606  0xcc,
607  0xcc,
608  0xff,
609  0x99,
610  0xcc,
611  0x99,
612  0xff,
613  0x99,
614  0xcc,
615  0x66,
616  0xff,
617  0x99,
618  0xcc,
619  0x33,
620  0xff,
621  0x99,
622  0xcc,
623  0x00,
624  0xff,
625  0x99,
626  0x99,
627  0xff,
628  0xff,
629  0x99,
630  0x99,
631  0xcc,
632  0xff,
633  0x99,
634  0x99,
635  0x99,
636  0xff,
637  0x99,
638  0x99,
639  0x66,
640  0xff,
641  0x99,
642  0x99,
643  0x33,
644  0xff,
645  0x99,
646  0x99,
647  0x00,
648  0xff,
649  0x99,
650  0x66,
651  0xff,
652  0xff,
653  0x99,
654  0x66,
655  0xcc,
656  0xff,
657  0x99,
658  0x66,
659  0x99,
660  0xff,
661  0x99,
662  0x66,
663  0x66,
664  0xff,
665  0x99,
666  0x66,
667  0x33,
668  0xff,
669  0x99,
670  0x66,
671  0x00,
672  0xff,
673  0x99,
674  0x33,
675  0xff,
676  0xff,
677  0x99,
678  0x33,
679  0xcc,
680  0xff,
681  0x99,
682  0x33,
683  0x99,
684  0xff,
685  0x99,
686  0x33,
687  0x66,
688  0xff,
689  0x99,
690  0x33,
691  0x33,
692  0xff,
693  0x99,
694  0x33,
695  0x00,
696  0xff,
697  0x99,
698  0x00,
699  0xff,
700  0xff,
701  0x99,
702  0x00,
703  0xcc,
704  0xff,
705  0x99,
706  0x00,
707  0x99,
708  0xff,
709  0x99,
710  0x00,
711  0x66,
712  0xff,
713  0x99,
714  0x00,
715  0x33,
716  0xff,
717  0x99,
718  0x00,
719  0x00,
720  0xff,
721  0x66,
722  0xff,
723  0xff,
724  0xff,
725  0x66,
726  0xff,
727  0xcc,
728  0xff,
729  0x66,
730  0xff,
731  0x99,
732  0xff,
733  0x66,
734  0xff,
735  0x66,
736  0xff,
737  0x66,
738  0xff,
739  0x33,
740  0xff,
741  0x66,
742  0xff,
743  0x00,
744  0xff,
745  0x66,
746  0xcc,
747  0xff,
748  0xff,
749  0x66,
750  0xcc,
751  0xcc,
752  0xff,
753  0x66,
754  0xcc,
755  0x99,
756  0xff,
757  0x66,
758  0xcc,
759  0x66,
760  0xff,
761  0x66,
762  0xcc,
763  0x33,
764  0xff,
765  0x66,
766  0xcc,
767  0x00,
768  0xff,
769  0x66,
770  0x99,
771  0xff,
772  0xff,
773  0x66,
774  0x99,
775  0xcc,
776  0xff,
777  0x66,
778  0x99,
779  0x99,
780  0xff,
781  0x66,
782  0x99,
783  0x66,
784  0xff,
785  0x66,
786  0x99,
787  0x33,
788  0xff,
789  0x66,
790  0x99,
791  0x00,
792  0xff,
793  0x66,
794  0x66,
795  0xff,
796  0xff,
797  0x66,
798  0x66,
799  0xcc,
800  0xff,
801  0x66,
802  0x66,
803  0x99,
804  0xff,
805  0x66,
806  0x66,
807  0x66,
808  0xff,
809  0x66,
810  0x66,
811  0x33,
812  0xff,
813  0x66,
814  0x66,
815  0x00,
816  0xff,
817  0x66,
818  0x33,
819  0xff,
820  0xff,
821  0x66,
822  0x33,
823  0xcc,
824  0xff,
825  0x66,
826  0x33,
827  0x99,
828  0xff,
829  0x66,
830  0x33,
831  0x66,
832  0xff,
833  0x66,
834  0x33,
835  0x33,
836  0xff,
837  0x66,
838  0x33,
839  0x00,
840  0xff,
841  0x66,
842  0x00,
843  0xff,
844  0xff,
845  0x66,
846  0x00,
847  0xcc,
848  0xff,
849  0x66,
850  0x00,
851  0x99,
852  0xff,
853  0x66,
854  0x00,
855  0x66,
856  0xff,
857  0x66,
858  0x00,
859  0x33,
860  0xff,
861  0x66,
862  0x00,
863  0x00,
864  0xff,
865  0x33,
866  0xff,
867  0xff,
868  0xff,
869  0x33,
870  0xff,
871  0xcc,
872  0xff,
873  0x33,
874  0xff,
875  0x99,
876  0xff,
877  0x33,
878  0xff,
879  0x66,
880  0xff,
881  0x33,
882  0xff,
883  0x33,
884  0xff,
885  0x33,
886  0xff,
887  0x00,
888  0xff,
889  0x33,
890  0xcc,
891  0xff,
892  0xff,
893  0x33,
894  0xcc,
895  0xcc,
896  0xff,
897  0x33,
898  0xcc,
899  0x99,
900  0xff,
901  0x33,
902  0xcc,
903  0x66,
904  0xff,
905  0x33,
906  0xcc,
907  0x33,
908  0xff,
909  0x33,
910  0xcc,
911  0x00,
912  0xff,
913  0x33,
914  0x99,
915  0xff,
916  0xff,
917  0x33,
918  0x99,
919  0xcc,
920  0xff,
921  0x33,
922  0x99,
923  0x99,
924  0xff,
925  0x33,
926  0x99,
927  0x66,
928  0xff,
929  0x33,
930  0x99,
931  0x33,
932  0xff,
933  0x33,
934  0x99,
935  0x00,
936  0xff,
937  0x33,
938  0x66,
939  0xff,
940  0xff,
941  0x33,
942  0x66,
943  0xcc,
944  0xff,
945  0x33,
946  0x66,
947  0x99,
948  0xff,
949  0x33,
950  0x66,
951  0x66,
952  0xff,
953  0x33,
954  0x66,
955  0x33,
956  0xff,
957  0x33,
958  0x66,
959  0x00,
960  0xff,
961  0x33,
962  0x33,
963  0xff,
964  0xff,
965  0x33,
966  0x33,
967  0xcc,
968  0xff,
969  0x33,
970  0x33,
971  0x99,
972  0xff,
973  0x33,
974  0x33,
975  0x66,
976  0xff,
977  0x33,
978  0x33,
979  0x33,
980  0xff,
981  0x33,
982  0x33,
983  0x00,
984  0xff,
985  0x33,
986  0x00,
987  0xff,
988  0xff,
989  0x33,
990  0x00,
991  0xcc,
992  0xff,
993  0x33,
994  0x00,
995  0x99,
996  0xff,
997  0x33,
998  0x00,
999  0x66,
1000  0xff,
1001  0x33,
1002  0x00,
1003  0x33,
1004  0xff,
1005  0x33,
1006  0x00,
1007  0x00,
1008  0xff,
1009  0x00,
1010  0xff,
1011  0xff,
1012  0xff,
1013  0x00,
1014  0xff,
1015  0xcc,
1016  0xff,
1017  0x00,
1018  0xff,
1019  0x99,
1020  0xff,
1021  0x00,
1022  0xff,
1023  0x66,
1024  0xff,
1025  0x00,
1026  0xff,
1027  0x33,
1028  0xff,
1029  0x00,
1030  0xff,
1031  0x00,
1032  0xff,
1033  0x00,
1034  0xcc,
1035  0xff,
1036  0xff,
1037  0x00,
1038  0xcc,
1039  0xcc,
1040  0xff,
1041  0x00,
1042  0xcc,
1043  0x99,
1044  0xff,
1045  0x00,
1046  0xcc,
1047  0x66,
1048  0xff,
1049  0x00,
1050  0xcc,
1051  0x33,
1052  0xff,
1053  0x00,
1054  0xcc,
1055  0x00,
1056  0xff,
1057  0x00,
1058  0x99,
1059  0xff,
1060  0xff,
1061  0x00,
1062  0x99,
1063  0xcc,
1064  0xff,
1065  0x00,
1066  0x99,
1067  0x99,
1068  0xff,
1069  0x00,
1070  0x99,
1071  0x66,
1072  0xff,
1073  0x00,
1074  0x99,
1075  0x33,
1076  0xff,
1077  0x00,
1078  0x99,
1079  0x00,
1080  0xff,
1081  0x00,
1082  0x66,
1083  0xff,
1084  0xff,
1085  0x00,
1086  0x66,
1087  0xcc,
1088  0xff,
1089  0x00,
1090  0x66,
1091  0x99,
1092  0xff,
1093  0x00,
1094  0x66,
1095  0x66,
1096  0xff,
1097  0x00,
1098  0x66,
1099  0x33,
1100  0xff,
1101  0x00,
1102  0x66,
1103  0x00,
1104  0xff,
1105  0x00,
1106  0x33,
1107  0xff,
1108  0xff,
1109  0x00,
1110  0x33,
1111  0xcc,
1112  0xff,
1113  0x00,
1114  0x33,
1115  0x99,
1116  0xff,
1117  0x00,
1118  0x33,
1119  0x66,
1120  0xff,
1121  0x00,
1122  0x33,
1123  0x33,
1124  0xff,
1125  0x00,
1126  0x33,
1127  0x00,
1128  0xff,
1129  0x00,
1130  0x00,
1131  0xff,
1132  0xff,
1133  0x00,
1134  0x00,
1135  0xcc,
1136  0xff,
1137  0x00,
1138  0x00,
1139  0x99,
1140  0xff,
1141  0x00,
1142  0x00,
1143  0x66,
1144  0xff,
1145  0x00,
1146  0x00,
1147  0x33,
1148  0xff,
1149  0xee,
1150  0x00,
1151  0x00,
1152  0xff,
1153  0xdd,
1154  0x00,
1155  0x00,
1156  0xff,
1157  0xbb,
1158  0x00,
1159  0x00,
1160  0xff,
1161  0xaa,
1162  0x00,
1163  0x00,
1164  0xff,
1165  0x88,
1166  0x00,
1167  0x00,
1168  0xff,
1169  0x77,
1170  0x00,
1171  0x00,
1172  0xff,
1173  0x55,
1174  0x00,
1175  0x00,
1176  0xff,
1177  0x44,
1178  0x00,
1179  0x00,
1180  0xff,
1181  0x22,
1182  0x00,
1183  0x00,
1184  0xff,
1185  0x11,
1186  0x00,
1187  0x00,
1188  0xff,
1189  0x00,
1190  0xee,
1191  0x00,
1192  0xff,
1193  0x00,
1194  0xdd,
1195  0x00,
1196  0xff,
1197  0x00,
1198  0xbb,
1199  0x00,
1200  0xff,
1201  0x00,
1202  0xaa,
1203  0x00,
1204  0xff,
1205  0x00,
1206  0x88,
1207  0x00,
1208  0xff,
1209  0x00,
1210  0x77,
1211  0x00,
1212  0xff,
1213  0x00,
1214  0x55,
1215  0x00,
1216  0xff,
1217  0x00,
1218  0x44,
1219  0x00,
1220  0xff,
1221  0x00,
1222  0x22,
1223  0x00,
1224  0xff,
1225  0x00,
1226  0x11,
1227  0x00,
1228  0xff,
1229  0x00,
1230  0x00,
1231  0xee,
1232  0xff,
1233  0x00,
1234  0x00,
1235  0xdd,
1236  0xff,
1237  0x00,
1238  0x00,
1239  0xbb,
1240  0xff,
1241  0x00,
1242  0x00,
1243  0xaa,
1244  0xff,
1245  0x00,
1246  0x00,
1247  0x88,
1248  0xff,
1249  0x00,
1250  0x00,
1251  0x77,
1252  0xff,
1253  0x00,
1254  0x00,
1255  0x55,
1256  0xff,
1257  0x00,
1258  0x00,
1259  0x44,
1260  0xff,
1261  0x00,
1262  0x00,
1263  0x22,
1264  0xff,
1265  0x00,
1266  0x00,
1267  0x11,
1268  0xff,
1269  0xee,
1270  0xee,
1271  0xee,
1272  0xff,
1273  0xdd,
1274  0xdd,
1275  0xdd,
1276  0xff,
1277  0xbb,
1278  0xbb,
1279  0xbb,
1280  0xff,
1281  0xaa,
1282  0xaa,
1283  0xaa,
1284  0xff,
1285  0x88,
1286  0x88,
1287  0x88,
1288  0xff,
1289  0x77,
1290  0x77,
1291  0x77,
1292  0xff,
1293  0x55,
1294  0x55,
1295  0x55,
1296  0xff,
1297  0x44,
1298  0x44,
1299  0x44,
1300  0xff,
1301  0x22,
1302  0x22,
1303  0x22,
1304  0xff,
1305  0x11,
1306  0x11,
1307  0x11,
1308  0xff,
1309  0x00,
1310  0x00,
1311  0x00,
1312  0xff,
1313 };
1314 
1315 // internal math/helper utilities
1316 static inline uint32_t _vox_max(uint32_t a, uint32_t b)
1317 {
1318  return (a > b) ? a : b;
1319 }
1320 static inline uint32_t _vox_min(uint32_t a, uint32_t b)
1321 {
1322  return (a < b) ? a : b;
1323 }
1324 
1325 // string utilities
1326 # ifdef _MSC_VER
1327 # define _vox_str_scanf(str, ...) sscanf_s(str, __VA_ARGS__)
1328 # define _vox_strcpy_static(dst, src) strcpy_s(dst, src)
1329 # define _vox_strcasecmp(a, b) _stricmp(a, b)
1330 # define _vox_strcmp(a, b) strcmp(a, b)
1331 # define _vox_strlen(a) strlen(a)
1332 # define _vox_sprintf(str, str_max, fmt, ...) sprintf_s(str, str_max, fmt, __VA_ARGS__)
1333 # else
1334 # define _vox_str_scanf(str, ...) sscanf(str, __VA_ARGS__)
1335 # define _vox_strcpy_static(dst, src) strcpy(dst, src)
1336 # define _vox_strcasecmp(a, b) strcasecmp(a, b)
1337 # define _vox_strcmp(a, b) strcmp(a, b)
1338 # define _vox_strlen(a) strlen(a)
1339 # define _vox_sprintf(str, str_max, fmt, ...) snprintf(str, str_max, fmt, __VA_ARGS__)
1340 # endif
1341 
1342 // 3d vector utilities
1343 struct vec3
1344 {
1345  float x, y, z;
1346 };
1347 static inline vec3 vec3_make(float x, float y, float z)
1348 {
1349  vec3 v;
1350  v.x = x;
1351  v.y = y;
1352  v.z = z;
1353  return v;
1354 }
1355 static inline vec3 vec3_negate(const vec3& v)
1356 {
1357  vec3 r;
1358  r.x = -v.x;
1359  r.y = -v.y;
1360  r.z = -v.z;
1361  return r;
1362 }
1363 
1364 // API for emulating file transactions on an in-memory buffer of data.
1365 struct _vox_file
1366 {
1367  const uint8_t* buffer; // source buffer data
1368  const uint32_t buffer_size; // size of the data in the buffer
1369  uint32_t offset; // current offset in the buffer data.
1370 };
1371 
1372 static bool _vox_file_read(_vox_file* pFp, void* pData, uint32_t data_size)
1373 {
1374  size_t data_to_read = _vox_min(pFp->buffer_size - pFp->offset, data_size);
1375  memcpy(pData, &pFp->buffer[pFp->offset], data_to_read);
1376  pFp->offset += data_size;
1377  return data_to_read == data_size;
1378 }
1379 
1380 static void _vox_file_seek_forwards(_vox_file* pFp, uint32_t offset)
1381 {
1382  pFp->offset += offset;
1383 }
1384 
1385 static bool _vox_file_eof(const _vox_file* pFp)
1386 {
1387  return pFp->offset >= pFp->buffer_size;
1388 }
1389 
1390 static const void* _vox_file_data_pointer(const _vox_file* pFp)
1391 {
1392  return &pFp->buffer[pFp->offset];
1393 }
1394 
1395 // hash utilities
1396 static uint32_t _vox_hash(const uint8_t* pData, uint32_t data_size)
1397 {
1398  uint32_t hash = 0;
1399  for (uint32_t i = 0; i < data_size; i++)
1400  hash = pData[i] + (hash * 65559);
1401  return hash;
1402 }
1403 
1404 // memory allocation utils.
1405 static void* _ogt_priv_alloc_default(size_t uiSize)
1406 {
1407  return malloc(uiSize);
1408 }
1409 static void _ogt_priv_free_default(void* pPtr)
1410 {
1411  free(pPtr);
1412 }
1413 static ogt_vox_alloc_func g_alloc_func = _ogt_priv_alloc_default; // default function for allocating
1414 static ogt_vox_free_func g_free_func = _ogt_priv_free_default; // default function for freeing.
1415 
1416 // set the provided allocate/free functions if they are non-null, otherwise reset to default allocate/free functions
1417 void ogt_vox_set_memory_allocator(ogt_vox_alloc_func alloc_func, ogt_vox_free_func free_func)
1418 {
1419  assert((alloc_func && free_func) || // both alloc/free must be non-NULL -OR-
1420  (!alloc_func && !free_func)); // both alloc/free must be NULL. No mixing 'n matching.
1421  if (alloc_func && free_func)
1422  {
1423  g_alloc_func = alloc_func;
1424  g_free_func = free_func;
1425  }
1426  else
1427  {
1428  // reset to default allocate/free functions.
1429  g_alloc_func = _ogt_priv_alloc_default;
1430  g_free_func = _ogt_priv_free_default;
1431  }
1432 }
1433 
1434 static void* _vox_malloc(size_t uiSize)
1435 {
1436  return uiSize ? g_alloc_func(uiSize) : NULL;
1437 }
1438 
1439 static void* _vox_calloc(size_t uiSize)
1440 {
1441  void* pMem = _vox_malloc(uiSize);
1442  if (pMem)
1443  memset(pMem, 0, uiSize);
1444  return pMem;
1445 }
1446 
1447 static void _vox_free(void* pOld_ptr)
1448 {
1449  if (pOld_ptr)
1450  g_free_func(pOld_ptr);
1451 }
1452 
1453 static void* _vox_realloc(void* pOld_ptr, size_t uiOld_size, size_t uiNew_size)
1454 {
1455  // early out if new size is non-zero and no resize is required.
1456  if (uiNew_size && uiOld_size >= uiNew_size)
1457  return pOld_ptr;
1458 
1459  // memcpy from the old ptr only if both sides are valid.
1460  void* new_ptr = _vox_malloc(uiNew_size);
1461  if (new_ptr)
1462  {
1463  // copy any existing elements over
1464  if (pOld_ptr && uiOld_size)
1465  memcpy(new_ptr, pOld_ptr, uiOld_size);
1466  // zero out any new tail elements
1467  assert(uiNew_size > uiOld_size); // this should be guaranteed by the _vox_realloc early out case above.
1468  uintptr_t new_tail_ptr = (uintptr_t)new_ptr + uiOld_size;
1469  memset((void*)new_tail_ptr, 0, uiNew_size - uiOld_size);
1470  }
1471  if (pOld_ptr)
1472  _vox_free(pOld_ptr);
1473  return new_ptr;
1474 }
1475 
1476 // std::vector-style allocator, which use client-provided allocation functions.
1477 template <class T>
1478 struct _vox_array
1479 {
1480  _vox_array()
1481  : data(NULL)
1482  , capacity(0)
1483  , count(0)
1484  {
1485  }
1486  ~_vox_array()
1487  {
1488  _vox_free(data);
1489  data = NULL;
1490  count = 0;
1491  capacity = 0;
1492  }
1493  void reserve(size_t uiNew_capacity)
1494  {
1495  data = (T*)_vox_realloc(data, capacity * sizeof(T), uiNew_capacity * sizeof(T));
1496  capacity = uiNew_capacity;
1497  }
1498  void grow_to_fit_index(size_t uiIndex)
1499  {
1500  if (uiIndex >= count)
1501  resize(uiIndex + 1);
1502  }
1503  void resize(size_t uiNew_count)
1504  {
1505  if (uiNew_count > capacity)
1506  reserve(uiNew_count);
1507  count = uiNew_count;
1508  }
1509  void push_back(const T& new_element)
1510  {
1511  if (count == capacity)
1512  {
1513  size_t new_capacity = capacity ? (capacity * 3) >> 1 : 2; // grow by 50% each time, otherwise start at 2 elements.
1514  reserve(new_capacity);
1515  assert(capacity > count);
1516  }
1517  data[count++] = new_element;
1518  }
1519  void push_back_many(const T* pNew_elements, size_t uiNum_elements)
1520  {
1521  if (count + uiNum_elements > capacity)
1522  {
1523  size_t new_capacity = capacity + uiNum_elements;
1524  new_capacity = new_capacity ? (new_capacity * 3) >> 1 : 2; // grow by 50% each time, otherwise start at 2 elements.
1525  reserve(new_capacity);
1526  assert(capacity >= (count + uiNum_elements));
1527  }
1528  for (size_t i = 0; i < uiNum_elements; i++)
1529  data[count + i] = pNew_elements[i];
1530  count += uiNum_elements;
1531  }
1532  size_t size() const
1533  {
1534  return count;
1535  }
1536  T& operator[](size_t uiIndex)
1537  {
1538  assert(uiIndex < count);
1539  return data[uiIndex];
1540  }
1541  const T& operator[](size_t uiIndex) const
1542  {
1543  assert(uiIndex < count);
1544  return data[uiIndex];
1545  }
1546  T* data; // data for the array
1547  size_t capacity; // capacity of the array
1548  size_t count; // size of the array
1549 };
1550 
1551 // matrix utilities
1552 static ogt_vox_transform _vox_transform_identity()
1553 {
1555  t.m00 = 1.0f;
1556  t.m01 = 0.0f;
1557  t.m02 = 0.0f;
1558  t.m03 = 0.0f;
1559  t.m10 = 0.0f;
1560  t.m11 = 1.0f;
1561  t.m12 = 0.0f;
1562  t.m13 = 0.0f;
1563  t.m20 = 0.0f;
1564  t.m21 = 0.0f;
1565  t.m22 = 1.0f;
1566  t.m23 = 0.0f;
1567  t.m30 = 0.0f;
1568  t.m31 = 0.0f;
1569  t.m32 = 0.0f;
1570  t.m33 = 1.0f;
1571  return t;
1572 }
1573 
1574 static ogt_vox_transform _vox_transform_multiply(const ogt_vox_transform& a, const ogt_vox_transform& b)
1575 {
1577  r.m00 = (a.m00 * b.m00) + (a.m01 * b.m10) + (a.m02 * b.m20) + (a.m03 * b.m30);
1578  r.m01 = (a.m00 * b.m01) + (a.m01 * b.m11) + (a.m02 * b.m21) + (a.m03 * b.m31);
1579  r.m02 = (a.m00 * b.m02) + (a.m01 * b.m12) + (a.m02 * b.m22) + (a.m03 * b.m32);
1580  r.m03 = (a.m00 * b.m03) + (a.m01 * b.m13) + (a.m02 * b.m23) + (a.m03 * b.m33);
1581  r.m10 = (a.m10 * b.m00) + (a.m11 * b.m10) + (a.m12 * b.m20) + (a.m13 * b.m30);
1582  r.m11 = (a.m10 * b.m01) + (a.m11 * b.m11) + (a.m12 * b.m21) + (a.m13 * b.m31);
1583  r.m12 = (a.m10 * b.m02) + (a.m11 * b.m12) + (a.m12 * b.m22) + (a.m13 * b.m32);
1584  r.m13 = (a.m10 * b.m03) + (a.m11 * b.m13) + (a.m12 * b.m23) + (a.m13 * b.m33);
1585  r.m20 = (a.m20 * b.m00) + (a.m21 * b.m10) + (a.m22 * b.m20) + (a.m23 * b.m30);
1586  r.m21 = (a.m20 * b.m01) + (a.m21 * b.m11) + (a.m22 * b.m21) + (a.m23 * b.m31);
1587  r.m22 = (a.m20 * b.m02) + (a.m21 * b.m12) + (a.m22 * b.m22) + (a.m23 * b.m32);
1588  r.m23 = (a.m20 * b.m03) + (a.m21 * b.m13) + (a.m22 * b.m23) + (a.m23 * b.m33);
1589  r.m30 = (a.m30 * b.m00) + (a.m31 * b.m10) + (a.m32 * b.m20) + (a.m33 * b.m30);
1590  r.m31 = (a.m30 * b.m01) + (a.m31 * b.m11) + (a.m32 * b.m21) + (a.m33 * b.m31);
1591  r.m32 = (a.m30 * b.m02) + (a.m31 * b.m12) + (a.m32 * b.m22) + (a.m33 * b.m32);
1592  r.m33 = (a.m30 * b.m03) + (a.m31 * b.m13) + (a.m32 * b.m23) + (a.m33 * b.m33);
1593  return r;
1594 }
1595 
1596 // dictionary utilities
1597 static const uint32_t k_vox_max_dict_buffer_size = 4096;
1598 static const uint32_t k_vox_max_dict_key_value_pairs = 256;
1599 struct _vox_dictionary
1600 {
1601  const char* keys[k_vox_max_dict_key_value_pairs];
1602  const char* values[k_vox_max_dict_key_value_pairs];
1603  uint32_t num_key_value_pairs;
1604  char buffer[k_vox_max_dict_buffer_size + 4]; // max 4096, +4 for safety
1605  uint32_t buffer_mem_used;
1606 };
1607 
1608 static bool _vox_file_read_dict(_vox_dictionary* pDict, _vox_file* pFp)
1609 {
1610  uint32_t num_pairs_to_read = 0;
1611  _vox_file_read(pFp, &num_pairs_to_read, sizeof(uint32_t));
1612  assert(num_pairs_to_read <= k_vox_max_dict_key_value_pairs);
1613 
1614  pDict->buffer_mem_used = 0;
1615  pDict->num_key_value_pairs = 0;
1616  for (uint32_t i = 0; i < num_pairs_to_read; i++)
1617  {
1618  // get the size of the key string
1619  uint32_t key_string_size = 0;
1620  _vox_file_read(pFp, &key_string_size, sizeof(uint32_t));
1621  // allocate space for the key, and read it in.
1622  if (pDict->buffer_mem_used + key_string_size > k_vox_max_dict_buffer_size)
1623  return false;
1624  char* key = &pDict->buffer[pDict->buffer_mem_used];
1625  pDict->buffer_mem_used += key_string_size + 1; // + 1 for zero terminator
1626  _vox_file_read(pFp, key, key_string_size);
1627  key[key_string_size] = 0; // zero-terminate
1628  assert(_vox_strlen(key) == key_string_size); // sanity check
1629 
1630  // get the size of the value string
1631  uint32_t value_string_size = 0;
1632  _vox_file_read(pFp, &value_string_size, sizeof(uint32_t));
1633  // allocate space for the value, and read it in.
1634  if (pDict->buffer_mem_used + value_string_size > k_vox_max_dict_buffer_size)
1635  return (false);
1636  char* value = &pDict->buffer[pDict->buffer_mem_used];
1637  pDict->buffer_mem_used += value_string_size + 1; // + 1 for zero terminator
1638  _vox_file_read(pFp, value, value_string_size);
1639  value[value_string_size] = 0; // zero-terminate
1640  assert(_vox_strlen(value) == value_string_size); // sanity check
1641  // now assign it in the dictionary
1642  pDict->keys[pDict->num_key_value_pairs] = key;
1643  pDict->values[pDict->num_key_value_pairs] = value;
1644  pDict->num_key_value_pairs++;
1645  }
1646 
1647  return true;
1648 }
1649 
1650 // helper for looking up in the dictionary
1651 static const char* _vox_dict_get_value_as_string(const _vox_dictionary* pDict, const char* szKey_to_find, const char* szDefault_value = NULL)
1652 {
1653  for (uint32_t i = 0; i < pDict->num_key_value_pairs; i++)
1654  if (_vox_strcasecmp(pDict->keys[i], szKey_to_find) == 0)
1655  return pDict->values[i];
1656  return szDefault_value;
1657 }
1658 
1659 // lookup table for _vox_make_transform_from_dict_strings
1660 static const vec3 k_vectors[4] = {
1661  vec3_make(1.0f, 0.0f, 0.0f),
1662  vec3_make(0.0f, 1.0f, 0.0f),
1663  vec3_make(0.0f, 0.0f, 1.0f),
1664  vec3_make(0.0f, 0.0f, 0.0f) // invalid!
1665 };
1666 
1667 // lookup table for _vox_make_transform_from_dict_strings
1668 static const uint32_t k_row2_index[] = {UINT32_MAX, UINT32_MAX, UINT32_MAX, 2, UINT32_MAX, 1, 0, UINT32_MAX};
1669 
1670 
1671 static ogt_vox_transform _vox_make_transform_from_dict_strings(const char* szRotation_string, const char* szTranslation_string)
1672 {
1673  ogt_vox_transform transform = _vox_transform_identity();
1674 
1675  if (szRotation_string != NULL)
1676  {
1677  // compute the per-row indexes into k_vectors[] array.
1678  // unpack rotation bits.
1679  // bits : meaning
1680  // 0 - 1 : index of the non-zero entry in the first row
1681  // 2 - 3 : index of the non-zero entry in the second row
1682  uint32_t packed_rotation_bits = atoi(szRotation_string);
1683  uint32_t row0_vec_index = (packed_rotation_bits >> 0) & 3;
1684  uint32_t row1_vec_index = (packed_rotation_bits >> 2) & 3;
1685  uint32_t row2_vec_index = k_row2_index[(1 << row0_vec_index) | (1 << row1_vec_index)]; // process of elimination to determine row 2 index based on row0/row1 being one of {0,1,2} choose 2.
1686  assert(row2_vec_index != UINT32_MAX); // if you hit this, you probably have invalid indices for row0_vec_index/row1_vec_index.
1687 
1688  // unpack rotation bits for vector signs
1689  // bits : meaning
1690  // 4 : the sign in the first row (0 : positive; 1 : negative)
1691  // 5 : the sign in the second row (0 : positive; 1 : negative)
1692  // 6 : the sign in the third row (0 : positive; 1 : negative)
1693  vec3 row0 = k_vectors[row0_vec_index];
1694  vec3 row1 = k_vectors[row1_vec_index];
1695  vec3 row2 = k_vectors[row2_vec_index];
1696  if (packed_rotation_bits & (1 << 4))
1697  row0 = vec3_negate(row0);
1698  if (packed_rotation_bits & (1 << 5))
1699  row1 = vec3_negate(row1);
1700  if (packed_rotation_bits & (1 << 6))
1701  row2 = vec3_negate(row2);
1702 
1703  // magicavoxel stores rows, we need columns, so we do the swizzle here into columns
1704  transform.m00 = row0.x;
1705  transform.m01 = row1.x;
1706  transform.m02 = row2.x;
1707  transform.m10 = row0.y;
1708  transform.m11 = row1.y;
1709  transform.m12 = row2.y;
1710  transform.m20 = row0.z;
1711  transform.m21 = row1.z;
1712  transform.m22 = row2.z;
1713  }
1714 
1715  if (szTranslation_string != NULL)
1716  {
1717  int32_t x = 0;
1718  int32_t y = 0;
1719  int32_t z = 0;
1720  _vox_str_scanf(szTranslation_string, "%i %i %i", &x, &y, &z);
1721  transform.m30 = (float)x;
1722  transform.m31 = (float)y;
1723  transform.m32 = (float)z;
1724  }
1725  return transform;
1726 }
1727 
1728 enum _vox_scene_node_type
1729 {
1730  k_nodetype_invalid = 0, // has not been parsed yet.
1731  k_nodetype_group = 1,
1732  k_nodetype_transform = 2,
1733  k_nodetype_shape = 3,
1734 };
1735 
1736 struct _vox_scene_node_
1737 {
1738  _vox_scene_node_type node_type; // only gets assigned when this has been parsed, otherwise will be k_nodetype_invalid
1739  union
1740  {
1741  // used only when node_type == k_nodetype_transform
1742  struct
1743  {
1744  char name[64]; // max name size is 64
1745  ogt_vox_transform transform;
1746  uint32_t child_node_id;
1747  uint32_t layer_id;
1748  bool hidden;
1749  } transform;
1750  // used only when node_type == k_nodetype_group
1751  struct
1752  {
1753  uint32_t first_child_node_id_index; // the index of the first child node ID within the ChildNodeID array
1754  uint32_t num_child_nodes; // number of child node IDs starting at the first index
1755  } group;
1756  // used only when node_type == k_nodetype_shape
1757  struct
1758  {
1759  uint32_t model_id; // will be UINT32_MAX if there is no model. Unlikely, there should always be a model.
1760  } shape;
1761  } u;
1762 };
1763 
1764 static void generate_instances_for_node(
1765  const _vox_array<_vox_scene_node_>& nodes, uint32_t node_index, const _vox_array<uint32_t>& child_id_array, uint32_t layer_index,
1766  const ogt_vox_transform& transform, const _vox_array<ogt_vox_model*>& model_ptrs, const char* szTransform_last_name, bool bTransform_last_hidden,
1767  _vox_array<ogt_vox_instance>& ref_instances, _vox_array<char>& ref_string_data, _vox_array<ogt_vox_group>& ref_groups, uint32_t group_index, bool bGenerate_groups)
1768 {
1769  const _vox_scene_node_* node = &nodes[node_index];
1770  assert(node);
1771  switch (node->node_type)
1772  {
1773  case k_nodetype_transform:
1774  {
1775  ogt_vox_transform new_transform = (bGenerate_groups) ? node->u.transform.transform // don't multiply by the parent transform. caller wants the group-relative transform
1776  : _vox_transform_multiply(node->u.transform.transform, transform); // flatten the transform if we're not generating groups: child transform * parent transform
1777  const char* new_transform_name = node->u.transform.name[0] ? node->u.transform.name : NULL;
1778  szTransform_last_name = new_transform_name ? new_transform_name : szTransform_last_name; // if this node has a name, use it instead of our parent name
1779  generate_instances_for_node(nodes, node->u.transform.child_node_id, child_id_array, node->u.transform.layer_id, new_transform, model_ptrs, szTransform_last_name, node->u.transform.hidden, ref_instances, ref_string_data, ref_groups, group_index, bGenerate_groups);
1780  break;
1781  }
1782  case k_nodetype_group:
1783  {
1784  // create a new group only if we're generating groups.
1785  uint32_t next_group_index = 0;
1786  if (bGenerate_groups)
1787  {
1788  next_group_index = (uint32_t)ref_groups.size();
1789  ogt_vox_group group;
1790  group.parent_group_index = group_index;
1791  group.transform = transform;
1792  group.hidden = bTransform_last_hidden;
1793  group.layer_index = layer_index;
1794  ref_groups.push_back(group);
1795  }
1796  // child nodes will only be hidden if their immediate transform is hidden.
1797  bTransform_last_hidden = false;
1798 
1799  const uint32_t* child_node_ids = (const uint32_t*)&child_id_array[node->u.group.first_child_node_id_index];
1800  for (uint32_t i = 0; i < node->u.group.num_child_nodes; i++)
1801  {
1802  generate_instances_for_node(nodes, child_node_ids[i], child_id_array, layer_index, transform, model_ptrs, szTransform_last_name, bTransform_last_hidden, ref_instances, ref_string_data, ref_groups, next_group_index, bGenerate_groups);
1803  }
1804  break;
1805  }
1806  case k_nodetype_shape:
1807  {
1808  assert(node->u.shape.model_id < model_ptrs.size());
1809  if (node->u.shape.model_id < model_ptrs.size() && // model ID is valid
1810  model_ptrs[node->u.shape.model_id] != NULL) // model is non-NULL.
1811  {
1812  assert(bGenerate_groups || group_index == 0); // if we're not generating groups, group_index should be zero to map to the root group.
1813  ogt_vox_instance new_instance;
1814  new_instance.model_index = node->u.shape.model_id;
1815  new_instance.transform = transform;
1816  new_instance.layer_index = layer_index;
1817  new_instance.group_index = group_index;
1818  new_instance.hidden = bTransform_last_hidden;
1819  // if we got a transform name, allocate space in string_data for it and keep track of the index
1820  // within string data. This will be patched to a real pointer at the very end.
1821  new_instance.name = 0;
1822  if (szTransform_last_name && szTransform_last_name[0])
1823  {
1824  new_instance.name = (const char*)(ref_string_data.size());
1825  size_t name_size = _vox_strlen(szTransform_last_name) + 1; // +1 for terminator
1826  ref_string_data.push_back_many(szTransform_last_name, name_size);
1827  }
1828  // create the instance
1829  ref_instances.push_back(new_instance);
1830  }
1831  break;
1832  }
1833  default:
1834  {
1835  assert(0); // unhandled node type!
1836  }
1837  }
1838 }
1839 
1840 // ensure instances are ordered in order of increasing model_index
1841 static int _vox_ordered_compare_instance(const void* p_lhs, const void* p_rhs)
1842 {
1843  const ogt_vox_instance* lhs = (const ogt_vox_instance*)p_lhs;
1844  const ogt_vox_instance* rhs = (const ogt_vox_instance*)p_rhs;
1845  return lhs->model_index < rhs->model_index ? -1 : lhs->model_index > rhs->model_index ? 1
1846  : 0;
1847 }
1848 
1849 // returns true if the 2 models are content-wise identical.
1850 static bool _vox_models_are_equal(const ogt_vox_model* lhs, const ogt_vox_model* rhs)
1851 {
1852  // early out: if hashes don't match, they can't be equal
1853  // if hashes match, they might be equal OR there might be a hash collision.
1854  if (lhs->voxel_hash != rhs->voxel_hash)
1855  return false;
1856  // early out: if number of voxels in the model's grid don't match, they can't be equal.
1857  uint32_t num_voxels_lhs = lhs->size_x * lhs->size_y * lhs->size_z;
1858  uint32_t num_voxels_rhs = rhs->size_x * rhs->size_y * rhs->size_z;
1859  if (num_voxels_lhs != num_voxels_rhs)
1860  return false;
1861  // Finally, we know their hashes are the same, and their dimensions are the same
1862  // but they are only equal if they have exactly the same voxel data.
1863  return memcmp(lhs->voxel_data, rhs->voxel_data, num_voxels_lhs) == 0 ? true : false;
1864 }
1865 
1866 const ogt_vox_scene* ogt_vox_read_scene_with_flags(const uint8_t* pBuffer, uint32_t buffer_size, uint32_t read_flags)
1867 {
1868  _vox_file file = {pBuffer, buffer_size, 0};
1869  _vox_file* fp = &file;
1870 
1871  // parsing state/context
1872  _vox_array<ogt_vox_model*> model_ptrs;
1873  _vox_array<_vox_scene_node_> nodes;
1874  _vox_array<ogt_vox_instance> instances;
1875  _vox_array<char> string_data;
1876  _vox_array<ogt_vox_layer> layers;
1877  _vox_array<ogt_vox_group> groups;
1878  _vox_array<uint32_t> child_ids;
1879  ogt_vox_palette palette;
1880  _vox_dictionary dict;
1881  uint32_t size_x = 0;
1882  uint32_t size_y = 0;
1883  uint32_t size_z = 0;
1884  uint8_t index_map[256];
1885  bool found_index_map_chunk = false;
1886 
1887  // size some of our arrays to prevent resizing during the parsing for smallish cases.
1888  model_ptrs.reserve(64);
1889  instances.reserve(256);
1890  child_ids.reserve(256);
1891  nodes.reserve(16);
1892  layers.reserve(8);
1893  groups.reserve(0);
1894  string_data.reserve(256);
1895 
1896  // push a sentinel character into these datastructures. This allows us to keep indexes
1897  // rather than pointers into data-structures that grow, and still allow an index of 0
1898  // to means invalid
1899  string_data.push_back('X');
1900  child_ids.push_back(-1);
1901 
1902  // copy the default palette into the scene. It may get overwritten by a palette chunk later
1903  memcpy(&palette, k_default_vox_palette, sizeof(ogt_vox_palette));
1904 
1905  // load and validate fileheader and file version.
1906  uint32_t file_header;
1907  uint32_t file_version;
1908  _vox_file_read(fp, &file_header, sizeof(uint32_t));
1909  _vox_file_read(fp, &file_version, sizeof(uint32_t));
1910  if (file_header != CHUNK_ID_VOX_ || file_version != 150)
1911  return NULL;
1912 
1913  // parse chunks until we reach the end of the file/buffer
1914  while (!_vox_file_eof(fp))
1915  {
1916  // read the fields common to all chunks
1917  uint32_t chunk_id = 0;
1918  uint32_t chunk_size = 0;
1919  uint32_t chunk_child_size = 0;
1920  _vox_file_read(fp, &chunk_id, sizeof(uint32_t));
1921  _vox_file_read(fp, &chunk_size, sizeof(uint32_t));
1922  _vox_file_read(fp, &chunk_child_size, sizeof(uint32_t));
1923 
1924  // process the chunk.
1925  switch (chunk_id)
1926  {
1927  case CHUNK_ID_MAIN:
1928  {
1929  assert(chunk_size == 0);
1930  break;
1931  }
1932  case CHUNK_ID_SIZE:
1933  {
1934  assert(chunk_size == 12 && chunk_child_size == 0);
1935  _vox_file_read(fp, &size_x, sizeof(uint32_t));
1936  _vox_file_read(fp, &size_y, sizeof(uint32_t));
1937  _vox_file_read(fp, &size_z, sizeof(uint32_t));
1938  break;
1939  }
1940  case CHUNK_ID_XYZI:
1941  {
1942  assert(chunk_child_size == 0 && size_x && size_y && size_z); // must have read a SIZE chunk prior to XYZI.
1943  // read the number of voxels to process for this moodel
1944  uint32_t num_voxels_in_chunk = 0;
1945  _vox_file_read(fp, &num_voxels_in_chunk, sizeof(uint32_t));
1946  if (num_voxels_in_chunk != 0)
1947  {
1948  uint32_t voxel_count = size_x * size_y * size_z;
1949  ogt_vox_model* model = (ogt_vox_model*)_vox_calloc(sizeof(ogt_vox_model) + voxel_count); // 1 byte for each voxel
1950  if (!model)
1951  return NULL;
1952  uint8_t* voxel_data = (uint8_t*)&model[1];
1953 
1954  // insert the model into the model array
1955  model_ptrs.push_back(model);
1956 
1957  // now setup the model
1958  model->size_x = size_x;
1959  model->size_y = size_y;
1960  model->size_z = size_z;
1961  model->voxel_data = voxel_data;
1962 
1963  // setup some strides for computing voxel index based on x/y/z
1964  const uint32_t k_stride_x = 1;
1965  const uint32_t k_stride_y = size_x;
1966  const uint32_t k_stride_z = size_x * size_y;
1967 
1968  // read this many voxels and store it in voxel data.
1969  const uint8_t* packed_voxel_data = (const uint8_t*)_vox_file_data_pointer(fp);
1970  for (uint32_t i = 0; i < num_voxels_in_chunk; i++)
1971  {
1972  uint8_t x = packed_voxel_data[i * 4 + 0];
1973  uint8_t y = packed_voxel_data[i * 4 + 1];
1974  uint8_t z = packed_voxel_data[i * 4 + 2];
1975  uint8_t color_index = packed_voxel_data[i * 4 + 3];
1976  assert(x < size_x && y < size_y && z < size_z);
1977  voxel_data[(x * k_stride_x) + (y * k_stride_y) + (z * k_stride_z)] = color_index;
1978  }
1979  _vox_file_seek_forwards(fp, num_voxels_in_chunk * 4);
1980  // compute the hash of the voxels in this model-- used to accelerate duplicate models checking.
1981  model->voxel_hash = _vox_hash(voxel_data, size_x * size_y * size_z);
1982  }
1983  else
1984  {
1985  model_ptrs.push_back(NULL);
1986  }
1987  break;
1988  }
1989  case CHUNK_ID_RGBA:
1990  {
1991  assert(chunk_size == sizeof(palette));
1992  _vox_file_read(fp, &palette, sizeof(palette));
1993  break;
1994  }
1995  case CHUNK_ID_nTRN:
1996  {
1997  uint32_t node_id;
1998  _vox_file_read(fp, &node_id, sizeof(node_id));
1999 
2000  // Parse the node dictionary, which can contain:
2001  // _name: string
2002  // _hidden: 0/1
2003  char node_name[64];
2004  bool hidden = false;
2005  node_name[0] = 0;
2006  {
2007  _vox_file_read_dict(&dict, fp);
2008  const char* name_string = _vox_dict_get_value_as_string(&dict, "_name");
2009  if (name_string)
2010  _vox_strcpy_static(node_name, name_string);
2011  // if we got a hidden attribute - assign it now.
2012  const char* hidden_string = _vox_dict_get_value_as_string(&dict, "_hidden", "0");
2013  if (hidden_string)
2014  hidden = (hidden_string[0] == '1' ? true : false);
2015  }
2016 
2017 
2018  // get other properties.
2019  uint32_t child_node_id, reserved_id, layer_id, num_frames;
2020  _vox_file_read(fp, &child_node_id, sizeof(child_node_id));
2021  _vox_file_read(fp, &reserved_id, sizeof(reserved_id));
2022  _vox_file_read(fp, &layer_id, sizeof(layer_id));
2023  _vox_file_read(fp, &num_frames, sizeof(num_frames));
2024  assert(reserved_id == UINT32_MAX && num_frames == 1); // must be these values according to the spec
2025 
2026  // Parse the frame dictionary that contains:
2027  // _r : int8 ROTATION (c)
2028  // _t : int32x3 translation
2029  // and extract a transform
2030  ogt_vox_transform frame_transform;
2031  {
2032  _vox_file_read_dict(&dict, fp);
2033  const char* rotation_value = _vox_dict_get_value_as_string(&dict, "_r");
2034  const char* translation_value = _vox_dict_get_value_as_string(&dict, "_t");
2035  frame_transform = _vox_make_transform_from_dict_strings(rotation_value, translation_value);
2036  }
2037  // setup the transform node.
2038  {
2039  nodes.grow_to_fit_index(node_id);
2040  _vox_scene_node_* transform_node = &nodes[node_id];
2041  assert(transform_node);
2042  transform_node->node_type = k_nodetype_transform;
2043  transform_node->u.transform.child_node_id = child_node_id;
2044  transform_node->u.transform.layer_id = layer_id;
2045  transform_node->u.transform.transform = frame_transform;
2046  transform_node->u.transform.hidden = hidden;
2047  // assign the name
2048  _vox_strcpy_static(transform_node->u.transform.name, node_name);
2049  }
2050  break;
2051  }
2052  case CHUNK_ID_nGRP:
2053  {
2054  uint32_t node_id;
2055  _vox_file_read(fp, &node_id, sizeof(node_id));
2056 
2057  // parse the node dictionary - data is unused.
2058  _vox_file_read_dict(&dict, fp);
2059 
2060  // setup the group node
2061  nodes.grow_to_fit_index(node_id);
2062  _vox_scene_node_* group_node = &nodes[node_id];
2063  group_node->node_type = k_nodetype_group;
2064  group_node->u.group.first_child_node_id_index = 0;
2065  group_node->u.group.num_child_nodes = 0;
2066 
2067  // setup all child scene nodes to point back to this node.
2068  uint32_t num_child_nodes = 0;
2069  _vox_file_read(fp, &num_child_nodes, sizeof(num_child_nodes));
2070 
2071  // allocate space for all the child node IDs
2072  if (num_child_nodes)
2073  {
2074  size_t prior_size = child_ids.size();
2075  assert(prior_size > 0); // should be guaranteed by the sentinel we reserved at the very beginning.
2076  child_ids.resize(prior_size + num_child_nodes);
2077  _vox_file_read(fp, &child_ids[prior_size], sizeof(uint32_t) * num_child_nodes);
2078  group_node->u.group.first_child_node_id_index = (uint32_t)prior_size;
2079  group_node->u.group.num_child_nodes = num_child_nodes;
2080  }
2081  break;
2082  }
2083  case CHUNK_ID_nSHP:
2084  {
2085  uint32_t node_id;
2086  _vox_file_read(fp, &node_id, sizeof(node_id));
2087 
2088  // setup the shape node
2089  nodes.grow_to_fit_index(node_id);
2090  _vox_scene_node_* shape_node = &nodes[node_id];
2091  shape_node->node_type = k_nodetype_shape;
2092  shape_node->u.shape.model_id = UINT32_MAX;
2093 
2094  // parse the node dictionary - data is unused.
2095  _vox_file_read_dict(&dict, fp);
2096 
2097  uint32_t num_models = 0;
2098  _vox_file_read(fp, &num_models, sizeof(num_models));
2099  assert(num_models == 1); // must be 1 according to the spec.
2100 
2101  // assign instances
2102  _vox_file_read(fp, &shape_node->u.shape.model_id, sizeof(uint32_t));
2103  assert(shape_node->u.shape.model_id < model_ptrs.size());
2104 
2105  // parse the model dictionary - data is unsued.
2106  _vox_file_read_dict(&dict, fp);
2107  break;
2108  }
2109  case CHUNK_ID_IMAP:
2110  {
2111  assert(chunk_size == 256);
2112  _vox_file_read(fp, index_map, 256);
2113  found_index_map_chunk = true;
2114  break;
2115  }
2116  case CHUNK_ID_LAYR:
2117  {
2118  int32_t layer_id = 0;
2119  int32_t reserved_id = 0;
2120  _vox_file_read(fp, &layer_id, sizeof(layer_id));
2121  _vox_file_read_dict(&dict, fp);
2122  _vox_file_read(fp, &reserved_id, sizeof(reserved_id));
2123  assert(reserved_id == -1);
2124 
2125  layers.grow_to_fit_index(layer_id);
2126  layers[layer_id].name = NULL;
2127  layers[layer_id].hidden = false;
2128 
2129  // if we got a layer name from the LAYR dictionary, allocate space in string_data for it and keep track of the index
2130  // within string data. This will be patched to a real pointer at the very end.
2131  const char* name_string = _vox_dict_get_value_as_string(&dict, "_name", NULL);
2132  if (name_string)
2133  {
2134  layers[layer_id].name = (const char*)(string_data.size());
2135  size_t name_size = _vox_strlen(name_string) + 1; // +1 for terminator
2136  string_data.push_back_many(name_string, name_size);
2137  }
2138  // if we got a hidden attribute - assign it now.
2139  const char* hidden_string = _vox_dict_get_value_as_string(&dict, "_hidden", "0");
2140  if (hidden_string)
2141  layers[layer_id].hidden = (hidden_string[0] == '1' ? true : false);
2142  break;
2143  }
2144  // we don't handle MATL/MATT/rOBJ or any other chunks for now, so we just skip the chunk payload.
2145  case CHUNK_ID_MATL:
2146  case CHUNK_ID_MATT:
2147  case CHUNK_ID_rOBJ:
2148  default:
2149  {
2150  _vox_file_seek_forwards(fp, chunk_size);
2151  break;
2152  }
2153  } // end switch
2154  }
2155 
2156  // ok, now that we've parsed all scene nodes - walk the scene hierarchy, and generate instances
2157  // we can't do this while parsing chunks unfortunately because some chunks reference chunks
2158  // that are later in the file than them.
2159  if (nodes.size())
2160  {
2161  bool generate_groups = read_flags & k_read_scene_flags_groups ? true : false;
2162  // if we're not reading scene-embedded groups, we generate only one and then flatten all instance transforms.
2163  if (!generate_groups)
2164  {
2165  ogt_vox_group root_group;
2166  root_group.transform = _vox_transform_identity();
2167  root_group.parent_group_index = k_invalid_group_index;
2168  root_group.layer_index = 0;
2169  root_group.hidden = false;
2170  groups.push_back(root_group);
2171  }
2172  generate_instances_for_node(nodes, 0, child_ids, 0, _vox_transform_identity(), model_ptrs, NULL, false, instances, string_data, groups, k_invalid_group_index, generate_groups);
2173  }
2174  else if (model_ptrs.size() == 1)
2175  {
2176  // add a single instance
2177  ogt_vox_instance new_instance;
2178  new_instance.model_index = 0;
2179  new_instance.group_index = 0;
2180  new_instance.transform = _vox_transform_identity();
2181  new_instance.layer_index = 0;
2182  new_instance.name = 0;
2183  new_instance.hidden = false;
2184  instances.push_back(new_instance);
2185  }
2186 
2187  // if we didn't get a layer chunk -- just create a default layer.
2188  if (layers.size() == 0)
2189  {
2190  // go through all instances and ensure they are only mapped to layer 0
2191  for (uint32_t i = 0; i < instances.size(); i++)
2192  instances[i].layer_index = 0;
2193  // add a single layer
2194  ogt_vox_layer new_layer;
2195  new_layer.hidden = false;
2196  new_layer.name = NULL;
2197  layers.push_back(new_layer);
2198  }
2199 
2200  // To support index-level assumptions (eg. artists using top 16 colors for color/palette cycling,
2201  // other ranges for emissive etc), we must ensure the order of colors that the artist sees in the
2202  // magicavoxel tool matches the actual index we'll end up using here. Unfortunately, magicavoxel
2203  // does an unexpected thing when remapping colors in the editor using ctrl+drag within the palette.
2204  // Instead of remapping all indices in all models, it just keeps track of a display index to actual
2205  // palette map and uses that to show reordered colors in the palette window. This is how that
2206  // map works:
2207  // displaycolor[k] = paletteColor[imap[k]]
2208  // To ensure our indices are in the same order as displayed by magicavoxel within the palette
2209  // window, we apply the mapping from the IMAP chunk both to the color palette and indices within each
2210  // voxel model.
2211  if (found_index_map_chunk)
2212  {
2213  // the imap chunk maps from display index to actual index.
2214  // generate an inverse index map (maps from actual index to display index)
2215  uint8_t index_map_inverse[256];
2216  for (uint32_t i = 0; i < 256; i++)
2217  {
2218  index_map_inverse[index_map[i]] = (uint8_t)i;
2219  }
2220 
2221  // reorder colors in the palette so the palette contains colors in display order
2222  ogt_vox_palette old_palette = palette;
2223  for (uint32_t i = 0; i < 256; i++)
2224  {
2225  uint32_t remapped_index = (index_map[i] + 255) & 0xFF;
2226  palette.color[i] = old_palette.color[remapped_index];
2227  }
2228 
2229  // ensure that all models are remapped so they are using display order palette indices.
2230  for (uint32_t i = 0; i < model_ptrs.size(); i++)
2231  {
2232  ogt_vox_model* model = model_ptrs[i];
2233  if (model)
2234  {
2235  uint32_t num_voxels = model->size_x * model->size_y * model->size_z;
2236  uint8_t* voxels = (uint8_t*)&model[1];
2237  for (uint32_t j = 0; j < num_voxels; j++)
2238  voxels[j] = 1 + index_map_inverse[voxels[j]];
2239  }
2240  }
2241  }
2242 
2243  // rotate the scene palette now so voxel indices can just map straight into the palette
2244  {
2245  ogt_vox_rgba last_color = palette.color[255];
2246  for (uint32_t i = 255; i > 0; i--)
2247  palette.color[i] = palette.color[i - 1];
2248  palette.color[0] = last_color;
2249  palette.color[0].a = 0; // alpha is zero for the 0th color as that color index represents a transparent voxel.
2250  }
2251 
2252  // check for models that are identical by doing a pair-wise compare. If we find identical
2253  // models, we'll end up with NULL gaps in the model_ptrs array, but instances will have
2254  // been remapped to keep the earlier model.
2255  for (uint32_t i = 0; i < model_ptrs.size(); i++)
2256  {
2257  if (!model_ptrs[i])
2258  continue;
2259  for (uint32_t j = i + 1; j < model_ptrs.size(); j++)
2260  {
2261  if (!model_ptrs[j] || !_vox_models_are_equal(model_ptrs[i], model_ptrs[j]))
2262  continue;
2263  // model i and model j are the same, so free model j and keep model i.
2264  _vox_free(model_ptrs[j]);
2265  model_ptrs[j] = NULL;
2266  // remap all instances that were referring to j to now refer to i.
2267  for (uint32_t k = 0; k < instances.size(); k++)
2268  if (instances[k].model_index == j)
2269  instances[k].model_index = i;
2270  }
2271  }
2272 
2273  // sometimes a model can be created which has no solid voxels within just due to the
2274  // authoring flow within magicavoxel. We have already have prevented creation of
2275  // instances that refer to empty models, but here we want to compact the model_ptrs
2276  // array such that it contains no more NULL models. This also requires we remap the
2277  // indices for instances so they continue to refer to their correct models.
2278  {
2279  // first, check to see if we find any empty model. No need to do work otherwise.
2280  bool found_empty_model = false;
2281  for (uint32_t i = 0; i < model_ptrs.size() && !found_empty_model; i++)
2282  {
2283  if (model_ptrs[i] == NULL)
2284  found_empty_model = true;
2285  }
2286  if (found_empty_model)
2287  {
2288  // build a remap table for all instances and simultaneously compact the model_ptrs array.
2289  uint32_t* model_remap = (uint32_t*)_vox_malloc(model_ptrs.size() * sizeof(uint32_t));
2290  uint32_t num_output_models = 0;
2291  for (uint32_t i = 0; i < model_ptrs.size(); i++)
2292  {
2293  if (model_ptrs[i] != NULL)
2294  {
2295  model_ptrs[num_output_models] = model_ptrs[i];
2296  model_remap[i] = num_output_models;
2297  num_output_models++;
2298  }
2299  else
2300  {
2301  model_remap[i] = UINT32_MAX;
2302  }
2303  }
2304  model_ptrs.resize(num_output_models);
2305 
2306  // remap all instances to point to the compacted model index
2307  for (uint32_t i = 0; i < instances.size(); i++)
2308  {
2309  uint32_t new_model_index = model_remap[instances[i].model_index];
2310  assert(new_model_index != UINT32_MAX); // we should have suppressed instances already that point to NULL models.
2311  instances[i].model_index = new_model_index;
2312  }
2313 
2314  // free remap table
2315  _vox_free(model_remap);
2316  model_remap = NULL;
2317  }
2318  }
2319 
2320  // finally, construct the output scene..
2321  size_t scene_size = sizeof(ogt_vox_scene) + string_data.size();
2322  ogt_vox_scene* scene = (ogt_vox_scene*)_vox_calloc(scene_size);
2323  {
2324  // copy name data into the scene
2325  char* scene_string_data = (char*)&scene[1];
2326  memcpy(scene_string_data, &string_data[0], sizeof(char) * string_data.size());
2327 
2328  // copy instances over to scene, and sort them so that instances with the same model are contiguous.
2329  size_t num_scene_instances = instances.size();
2330  ogt_vox_instance* scene_instances = (ogt_vox_instance*)_vox_malloc(sizeof(ogt_vox_instance) * num_scene_instances);
2331  if (num_scene_instances)
2332  {
2333  memcpy(scene_instances, &instances[0], sizeof(ogt_vox_instance) * num_scene_instances);
2334  qsort(scene_instances, num_scene_instances, sizeof(ogt_vox_instance), _vox_ordered_compare_instance);
2335  }
2336  scene->instances = scene_instances;
2337  scene->num_instances = (uint32_t)instances.size();
2338 
2339  // copy model pointers over to the scene,
2340  size_t num_scene_models = model_ptrs.size();
2341  ogt_vox_model** scene_models = (ogt_vox_model**)_vox_malloc(sizeof(ogt_vox_model*) * num_scene_models);
2342  if (num_scene_models)
2343  memcpy(scene_models, &model_ptrs[0], sizeof(ogt_vox_model*) * num_scene_models);
2344  scene->models = (const ogt_vox_model**)scene_models;
2345  scene->num_models = (uint32_t)num_scene_models;
2346 
2347  // copy layer pointers over to the scene
2348  size_t num_scene_layers = layers.size();
2349  ogt_vox_layer* scene_layers = (ogt_vox_layer*)_vox_malloc(sizeof(ogt_vox_layer) * num_scene_layers);
2350  memcpy(scene_layers, &layers[0], sizeof(ogt_vox_layer) * num_scene_layers);
2351  scene->layers = scene_layers;
2352  scene->num_layers = (uint32_t)num_scene_layers;
2353 
2354  // copy group pointers over to the scene
2355  size_t num_scene_groups = groups.size();
2356  ogt_vox_group* scene_groups = num_scene_groups ? (ogt_vox_group*)_vox_malloc(sizeof(ogt_vox_group) * num_scene_groups) : NULL;
2357  if (num_scene_groups)
2358  memcpy(scene_groups, &groups[0], sizeof(ogt_vox_group) * num_scene_groups);
2359  scene->groups = scene_groups;
2360  scene->num_groups = (uint32_t)num_scene_groups;
2361 
2362  // now patch up instance name pointers to point into the scene string area
2363  for (uint32_t i = 0; i < num_scene_instances; i++)
2364  if (scene_instances[i].name)
2365  scene_instances[i].name = scene_string_data + (size_t)scene_instances[i].name;
2366 
2367  // now patch up layer name pointers to point into the scene string area
2368  for (uint32_t i = 0; i < num_scene_layers; i++)
2369  if (scene_layers[i].name)
2370  scene_layers[i].name = scene_string_data + (size_t)scene_layers[i].name;
2371 
2372  // copy the palette.
2373  scene->palette = palette;
2374  }
2375  return scene;
2376 }
2377 
2378 const ogt_vox_scene* ogt_vox_read_scene(const uint8_t* pBuffer, uint32_t buffer_size)
2379 {
2380  return ogt_vox_read_scene_with_flags(pBuffer, buffer_size, 0);
2381 }
2382 
2383 void ogt_vox_destroy_scene(const ogt_vox_scene* p_scene)
2384 {
2385  ogt_vox_scene* scene = const_cast<ogt_vox_scene*>(p_scene);
2386  // free models from model array
2387  for (uint32_t i = 0; i < scene->num_models; i++)
2388  _vox_free((void*)scene->models[i]);
2389  // free model array itself
2390  if (scene->models)
2391  {
2392  _vox_free(scene->models);
2393  scene->models = NULL;
2394  }
2395  // free instance array
2396  if (scene->instances)
2397  {
2398  _vox_free(const_cast<ogt_vox_instance*>(scene->instances));
2399  scene->instances = NULL;
2400  }
2401  // free layer array
2402  if (scene->layers)
2403  {
2404  _vox_free(const_cast<ogt_vox_layer*>(scene->layers));
2405  scene->layers = NULL;
2406  }
2407  // free groups array
2408  if (scene->groups)
2409  {
2410  _vox_free(const_cast<ogt_vox_group*>(scene->groups));
2411  scene->groups = NULL;
2412  }
2413  // finally, free the scene.
2414  _vox_free(scene);
2415 }
2416 
2417 // the vector should be a unit vector aligned along one of the cardinal directions exactly. eg. (1,0,0) or (0, 0, -1)
2418 // this function returns the non-zero column index in out_index and the returns whether that entry is negative.
2419 static bool _vox_get_vec3_rotation_bits(const vec3& vec, uint32_t& out_index)
2420 {
2421  const float* f = &vec.x;
2422  out_index = 3;
2423  bool is_negative = false;
2424  for (uint32_t i = 0; i < 3; i++)
2425  {
2426  if (f[i] == 1.0f || f[i] == -1.0f)
2427  {
2428  out_index = i;
2429  is_negative = f[i] < 0.0f ? true : false;
2430  }
2431  else
2432  {
2433  assert(f[i] == 0.0f); // must be zero
2434  }
2435  }
2436  assert(out_index != 3); // if you hit this, you probably have all zeroes in the vector!
2437  return is_negative;
2438 }
2439 
2440 static uint8_t _vox_make_packed_rotation_from_transform(const ogt_vox_transform* pTransform)
2441 {
2442  // magicavoxel stores rows, and we have columns, so we do the swizzle here into rows
2443  vec3 row0 = vec3_make(pTransform->m00, pTransform->m10, pTransform->m20);
2444  vec3 row1 = vec3_make(pTransform->m01, pTransform->m11, pTransform->m21);
2445  vec3 row2 = vec3_make(pTransform->m02, pTransform->m12, pTransform->m22);
2446  uint32_t row0_index = 3, row1_index = 3, row2_index = 3;
2447  bool row0_negative = _vox_get_vec3_rotation_bits(row0, row0_index);
2448  bool row1_negative = _vox_get_vec3_rotation_bits(row1, row1_index);
2449  bool row2_negative = _vox_get_vec3_rotation_bits(row2, row2_index);
2450  assert(((1 << row0_index) | (1 << row1_index) | (1 << row2_index)) == 7); // check that rows are orthogonal. There must be a non-zero entry in column 0, 1 and 2 across these 3 rows.
2451  return static_cast<uint8_t>((row0_index) | (row1_index << 2) | (row0_negative ? 1 << 4 : 0) | (row1_negative ? 1 << 5 : 0) | (row2_negative ? 1 << 6 : 0));
2452 }
2453 
2454 struct _vox_file_writeable
2455 {
2456  _vox_array<uint8_t> data;
2457 };
2458 
2459 static void _vox_file_writeable_init(_vox_file_writeable* pFp)
2460 {
2461  pFp->data.reserve(1024);
2462 }
2463 static void _vox_file_write(_vox_file_writeable* pFp, const void* pData, uint32_t data_size)
2464 {
2465  pFp->data.push_back_many((const uint8_t*)pData, data_size);
2466 }
2467 static void _vox_file_write_uint32(_vox_file_writeable* pFp, uint32_t data)
2468 {
2469  pFp->data.push_back_many((const uint8_t*)&data, sizeof(uint32_t));
2470 }
2471 static void _vox_file_write_uint8(_vox_file_writeable* pFp, uint8_t data)
2472 {
2473  pFp->data.push_back_many((const uint8_t*)&data, sizeof(uint8_t));
2474 }
2475 static uint32_t _vox_file_get_offset(const _vox_file_writeable* pFp)
2476 {
2477  return (uint32_t)pFp->data.count;
2478 }
2479 static uint8_t* _vox_file_get_data(_vox_file_writeable* pFp)
2480 {
2481  return &pFp->data[0];
2482 }
2483 static void _vox_file_write_dict_key_value(_vox_file_writeable* pFp, const char* szKey, const char* value)
2484 {
2485  if (szKey == NULL || value == NULL)
2486  return;
2487  uint32_t key_len = (uint32_t)_vox_strlen(szKey);
2488  uint32_t value_len = (uint32_t)_vox_strlen(value);
2489  _vox_file_write_uint32(pFp, key_len);
2490  _vox_file_write(pFp, szKey, key_len);
2491  _vox_file_write_uint32(pFp, value_len);
2492  _vox_file_write(pFp, value, value_len);
2493 }
2494 
2495 static uint32_t _vox_dict_key_value_size(const char* szKey, const char* value)
2496 {
2497  if (szKey == NULL || value == NULL)
2498  return 0;
2499  size_t size = sizeof(uint32_t) + _vox_strlen(szKey) + sizeof(uint32_t) + _vox_strlen(value);
2500  return (uint32_t)size;
2501 }
2502 
2503 static void _vox_file_write_chunk_nTRN(_vox_file_writeable* pFp, uint32_t node_id, uint32_t child_node_id, const char* szName, bool bHidden, const ogt_vox_transform* pTransform, uint32_t layer_id)
2504 {
2505  // obtain dictionary string pointers
2506  const char* hidden_string = bHidden ? "1" : NULL;
2507  const char* t_string = NULL;
2508  const char* r_string = NULL;
2509  char t_string_buf[64];
2510  char r_string_buf[64];
2511  t_string_buf[0] = 0;
2512  r_string_buf[0] = 0;
2513  if (pTransform != NULL)
2514  {
2515  uint8_t packed_rotation_bits = _vox_make_packed_rotation_from_transform(pTransform);
2516  _vox_sprintf(t_string_buf, sizeof(t_string_buf), "%i %i %i", (int32_t)pTransform->m30, (int32_t)pTransform->m31, (int32_t)pTransform->m32);
2517  _vox_sprintf(r_string_buf, sizeof(r_string_buf), "%u", packed_rotation_bits);
2518  t_string = t_string_buf;
2519  r_string = r_string_buf;
2520  }
2521 
2522  uint32_t node_dict_size =
2523  sizeof(uint32_t) + // num key value pairs
2524  _vox_dict_key_value_size("_name", szName) +
2525  _vox_dict_key_value_size("_hidden", hidden_string);
2526 
2527  uint32_t frame_dict_size =
2528  sizeof(uint32_t) + // num key value pairs
2529  _vox_dict_key_value_size("_t", t_string) +
2530  _vox_dict_key_value_size("_r", r_string);
2531 
2532  uint32_t chunk_size_ntrn =
2533  sizeof(uint32_t) + // node_id
2534  node_dict_size + // node dictionary
2535  4 * sizeof(uint32_t) + // middle section - 4 uint32s
2536  frame_dict_size;
2537 
2538  // write the nTRN header
2539  _vox_file_write_uint32(pFp, CHUNK_ID_nTRN);
2540  _vox_file_write_uint32(pFp, chunk_size_ntrn);
2541  _vox_file_write_uint32(pFp, 0);
2542 
2543  // write the nTRN payload
2544  _vox_file_write_uint32(pFp, node_id);
2545 
2546  // write the node dictionary
2547  uint32_t node_dict_keyvalue_count = (szName ? 1 : 0) + (hidden_string ? 1 : 0);
2548  _vox_file_write_uint32(pFp, node_dict_keyvalue_count); // num key values
2549  _vox_file_write_dict_key_value(pFp, "_name", szName);
2550  _vox_file_write_dict_key_value(pFp, "_hidden", hidden_string);
2551 
2552  // get other properties.
2553  _vox_file_write_uint32(pFp, child_node_id);
2554  _vox_file_write_uint32(pFp, UINT32_MAX); // reserved_id must have all bits set.
2555  _vox_file_write_uint32(pFp, layer_id);
2556  _vox_file_write_uint32(pFp, 1); // num_frames must be 1
2557 
2558  // write the frame dictionary
2559  _vox_file_write_uint32(pFp, (r_string ? 1 : 0) + (t_string ? 1 : 0)); // num key values
2560  _vox_file_write_dict_key_value(pFp, "_r", r_string);
2561  _vox_file_write_dict_key_value(pFp, "_t", t_string);
2562 }
2563 
2564 // saves the scene out to a buffer that when saved as a .vox file can be loaded with magicavoxel.
2565 uint8_t* ogt_vox_write_scene(const ogt_vox_scene* pScene, uint32_t* pBuffer_size)
2566 {
2567  _vox_file_writeable file;
2568  _vox_file_writeable_init(&file);
2569  _vox_file_writeable* fp = &file;
2570 
2571  // write file header and file version
2572  _vox_file_write_uint32(fp, CHUNK_ID_VOX_);
2573  _vox_file_write_uint32(fp, 150);
2574 
2575  // write the main chunk
2576  _vox_file_write_uint32(fp, CHUNK_ID_MAIN);
2577  _vox_file_write_uint32(fp, 0);
2578  _vox_file_write_uint32(fp, 0); // this main_chunk_child_size will get patched up once everything is written.
2579 
2580  // we need to know how to patch up the main chunk size after we've written everything
2581  const uint32_t offset_post_main_chunk = _vox_file_get_offset(fp);
2582 
2583  // write out all model chunks
2584  for (uint32_t i = 0; i < pScene->num_models; i++)
2585  {
2586  const ogt_vox_model* model = pScene->models[i];
2587  assert(model->size_x <= 126 && model->size_y <= 126 && model->size_z <= 126);
2588  // count the number of solid voxels in the grid
2589  uint32_t num_voxels_in_grid = model->size_x * model->size_y * model->size_z;
2590  uint32_t num_solid_voxels = 0;
2591  for (uint32_t voxel_index = 0; voxel_index < num_voxels_in_grid; voxel_index++)
2592  if (model->voxel_data[voxel_index] != 0)
2593  num_solid_voxels++;
2594  uint32_t chunk_size_xyzi = sizeof(uint32_t) + 4 * num_solid_voxels;
2595 
2596  // write the SIZE chunk header
2597  _vox_file_write_uint32(fp, CHUNK_ID_SIZE);
2598  _vox_file_write_uint32(fp, 12);
2599  _vox_file_write_uint32(fp, 0);
2600 
2601  // write the SIZE chunk payload
2602  _vox_file_write_uint32(fp, model->size_x);
2603  _vox_file_write_uint32(fp, model->size_y);
2604  _vox_file_write_uint32(fp, model->size_z);
2605 
2606  // write the XYZI chunk header
2607  _vox_file_write_uint32(fp, CHUNK_ID_XYZI);
2608  _vox_file_write_uint32(fp, chunk_size_xyzi);
2609  _vox_file_write_uint32(fp, 0);
2610 
2611  // write out XYZI chunk payload
2612  _vox_file_write_uint32(fp, num_solid_voxels);
2613  uint32_t voxel_index = 0;
2614  for (uint32_t z = 0; z < model->size_z; z++)
2615  {
2616  for (uint32_t y = 0; y < model->size_y; y++)
2617  {
2618  for (uint32_t x = 0; x < model->size_x; x++, voxel_index++)
2619  {
2620  uint8_t color_index = model->voxel_data[voxel_index];
2621  if (color_index != 0)
2622  {
2623  _vox_file_write_uint8(fp, (uint8_t)x);
2624  _vox_file_write_uint8(fp, (uint8_t)y);
2625  _vox_file_write_uint8(fp, (uint8_t)z);
2626  _vox_file_write_uint8(fp, color_index);
2627  }
2628  }
2629  }
2630  }
2631  }
2632 
2633  // define our node_id ranges.
2634  assert(pScene->num_groups);
2635  uint32_t first_group_transform_node_id = 0;
2636  uint32_t first_group_node_id = first_group_transform_node_id + pScene->num_groups;
2637  uint32_t first_shape_node_id = first_group_node_id + pScene->num_groups;
2638  uint32_t first_instance_transform_node_id = first_shape_node_id + pScene->num_models;
2639 
2640  // write the nTRN nodes for each of the groups in the scene.
2641  for (uint32_t group_index = 0; group_index < pScene->num_groups; group_index++)
2642  {
2643  const ogt_vox_group* group = &pScene->groups[group_index];
2644  _vox_file_write_chunk_nTRN(fp, first_group_transform_node_id + group_index, first_group_node_id + group_index, NULL, group->hidden, &group->transform, group->layer_index);
2645  }
2646  // write the group nodes for each of the groups in the scene
2647  for (uint32_t group_index = 0; group_index < pScene->num_groups; group_index++)
2648  {
2649  // count how many childnodes there are. This is simply the sum of all
2650  // groups and instances that have this group as its parent
2651  uint32_t num_child_nodes = 0;
2652  for (uint32_t child_group_index = 0; child_group_index < pScene->num_groups; child_group_index++)
2653  if (pScene->groups[child_group_index].parent_group_index == group_index)
2654  num_child_nodes++;
2655  for (uint32_t child_instance_index = 0; child_instance_index < pScene->num_instances; child_instance_index++)
2656  if (pScene->instances[child_instance_index].group_index == group_index)
2657  num_child_nodes++;
2658 
2659  // count number of dictionary items
2660  const char* hidden_string = pScene->groups[group_index].hidden ? "1" : NULL;
2661  uint32_t group_dict_keyvalue_count = (hidden_string ? 1 : 0);
2662 
2663  // compute the chunk size.
2664  uint32_t chunk_size_ngrp =
2665  sizeof(uint32_t) + // node_id
2666  sizeof(uint32_t) + // num keyvalue pairs in node dictionary
2667  _vox_dict_key_value_size("_hidden", hidden_string) +
2668  sizeof(uint32_t) + // num_child_nodes field
2669  sizeof(uint32_t) * num_child_nodes; // uint32_t for each child node id.
2670 
2671  // write the nGRP header
2672  _vox_file_write_uint32(fp, CHUNK_ID_nGRP);
2673  _vox_file_write_uint32(fp, chunk_size_ngrp);
2674  _vox_file_write_uint32(fp, 0);
2675  // write the nGRP payload
2676  _vox_file_write_uint32(fp, first_group_node_id + group_index); // node_id
2677  _vox_file_write_uint32(fp, group_dict_keyvalue_count); // num keyvalue pairs in node dictionary
2678  _vox_file_write_dict_key_value(fp, "_hidden", hidden_string);
2679  _vox_file_write_uint32(fp, num_child_nodes);
2680  // write the child group transform nodes
2681  for (uint32_t child_group_index = 0; child_group_index < pScene->num_groups; child_group_index++)
2682  if (pScene->groups[child_group_index].parent_group_index == group_index)
2683  _vox_file_write_uint32(fp, first_group_transform_node_id + child_group_index);
2684  // write the child instance transform nodes
2685  for (uint32_t child_instance_index = 0; child_instance_index < pScene->num_instances; child_instance_index++)
2686  if (pScene->instances[child_instance_index].group_index == group_index)
2687  _vox_file_write_uint32(fp, first_instance_transform_node_id + child_instance_index);
2688  }
2689 
2690  // write out an nSHP chunk for each of the models
2691  for (uint32_t i = 0; i < pScene->num_models; i++)
2692  {
2693  // compute the size of the nSHP chunk
2694  uint32_t chunk_size_nshp =
2695  sizeof(uint32_t) + // node_id
2696  sizeof(uint32_t) + // num keyvalue pairs in node dictionary
2697  sizeof(uint32_t) + // num_models
2698  sizeof(uint32_t) + // model_id
2699  sizeof(uint32_t); // num keyvalue pairs in model dictionary
2700  // write the nSHP chunk header
2701  _vox_file_write_uint32(fp, CHUNK_ID_nSHP);
2702  _vox_file_write_uint32(fp, chunk_size_nshp);
2703  _vox_file_write_uint32(fp, 0);
2704  // write the nSHP chunk payload
2705  _vox_file_write_uint32(fp, first_shape_node_id + i); // node_id
2706  _vox_file_write_uint32(fp, 0); // num keyvalue pairs in node dictionary
2707  _vox_file_write_uint32(fp, 1); // num_models must be 1
2708  _vox_file_write_uint32(fp, i); // model_id
2709  _vox_file_write_uint32(fp, 0); // num keyvalue pairs in model dictionary
2710  }
2711  // write out an nTRN chunk for all instances - and make them point to the relevant nSHP chunk
2712  for (uint32_t i = 0; i < pScene->num_instances; i++)
2713  {
2714  const ogt_vox_instance* instance = &pScene->instances[i];
2715  uint32_t node_id = first_instance_transform_node_id + i;
2716  uint32_t child_node_id = first_shape_node_id + instance->model_index;
2717  _vox_file_write_chunk_nTRN(fp, node_id, child_node_id, instance->name, instance->hidden, &instance->transform, instance->layer_index);
2718  }
2719 
2720  // write out RGBA chunk for the palette
2721  {
2722  // .vox stores palette rotated by 1 color index, so do that now.
2723  ogt_vox_palette rotated_palette;
2724  for (uint32_t i = 0; i < 256; i++)
2725  rotated_palette.color[i] = pScene->palette.color[(i + 1) & 255];
2726 
2727  // write the palette chunk header
2728  _vox_file_write_uint32(fp, CHUNK_ID_RGBA);
2729  _vox_file_write_uint32(fp, sizeof(ogt_vox_palette));
2730  _vox_file_write_uint32(fp, 0);
2731  // write the palette chunk payload
2732  _vox_file_write(fp, &rotated_palette, sizeof(ogt_vox_palette));
2733  }
2734 
2735  // write all layer chunks out.
2736  for (uint32_t i = 0; i < pScene->num_layers; i++)
2737  {
2738  const char* layer_name_string = pScene->layers[i].name;
2739  const char* hidden_string = pScene->layers[i].hidden ? "1" : NULL;
2740  uint32_t layer_chunk_size =
2741  sizeof(int32_t) + // layer_id
2742  sizeof(uint32_t) + // num key value pairs
2743  _vox_dict_key_value_size("_name", layer_name_string) +
2744  _vox_dict_key_value_size("_hidden", hidden_string) +
2745  sizeof(int32_t); // reserved id, must be -1
2746  uint32_t layer_dict_keyvalue_count = (layer_name_string ? 1 : 0) + (hidden_string ? 1 : 0);
2747  // write the layer chunk header
2748  _vox_file_write_uint32(fp, CHUNK_ID_LAYR);
2749  _vox_file_write_uint32(fp, layer_chunk_size);
2750  _vox_file_write_uint32(fp, 0);
2751  // write the layer chunk payload
2752  _vox_file_write_uint32(fp, i); // layer_id
2753  _vox_file_write_uint32(fp, layer_dict_keyvalue_count); // num keyvalue pairs in layer dictionary
2754  _vox_file_write_dict_key_value(fp, "_name", layer_name_string);
2755  _vox_file_write_dict_key_value(fp, "_hidden", hidden_string);
2756  _vox_file_write_uint32(fp, UINT32_MAX); // reserved id
2757  }
2758 
2759  // we deliberately don't free the fp->data field, just pass the buffer pointer and size out to the caller
2760  *pBuffer_size = (uint32_t)fp->data.count;
2761  uint8_t* buffer_data = _vox_file_get_data(fp);
2762  // we deliberately clear this pointer so it doesn't get auto-freed on exiting. The caller will own the memory hereafter.
2763  fp->data.data = NULL;
2764 
2765  // patch up the main chunk's child chunk size now that we've written everything we're going to write.
2766  {
2767  uint32_t* main_chunk_child_size = (uint32_t*)&buffer_data[offset_post_main_chunk - sizeof(uint32_t)];
2768  *main_chunk_child_size = *pBuffer_size - offset_post_main_chunk;
2769  }
2770 
2771  return buffer_data;
2772 }
2773 
2774 void* ogt_vox_malloc(size_t uiSize)
2775 {
2776  return _vox_malloc(uiSize);
2777 }
2778 
2779 void ogt_vox_free(void* pMem)
2780 {
2781  _vox_free(pMem);
2782 }
2783 
2784 // compute the minimum and maximum x coordinate within the scene.
2785 static void compute_scene_bounding_box_x(const ogt_vox_scene* pScene, int32_t& out_min_x, int32_t& out_max_x)
2786 {
2787  if (pScene->num_instances && pScene->num_models)
2788  {
2789  // We don't apply orientation to the model dimensions and compute the exact min/max.
2790  // Instead we just conservatively use the maximum dimension of the model.
2791  int32_t scene_min_x = 0x7ffffff;
2792  int32_t scene_max_x = -0x7ffffff;
2793  for (uint32_t instance_index = 0; instance_index < pScene->num_instances; instance_index++)
2794  {
2795  const ogt_vox_instance* instance = &pScene->instances[instance_index];
2796  // compute the instance transform, taking into account the group hierarchy.
2797  ogt_vox_transform instance_transform = instance->transform;
2798  uint32_t parent_group_index = instance->group_index;
2799  while (parent_group_index != k_invalid_group_index)
2800  {
2801  const ogt_vox_group* group = &pScene->groups[parent_group_index];
2802  instance_transform = _vox_transform_multiply(instance_transform, group->transform);
2803  parent_group_index = group->parent_group_index;
2804  }
2805 
2806  const ogt_vox_model* model = pScene->models[instance->model_index];
2807  // the instance_transform can be rotated, so we try to figure out whether the
2808  // model's local x, y or z size is aligned along the world x axis.
2809  // One of the column vectors of the transform must have a non-zero in its
2810  // x field and the dimension associated with that column is the correct choice of rus.
2811  int32_t max_dim = instance_transform.m00 != 0.0f ? model->size_x : instance_transform.m10 != 0.0f ? model->size_y
2812  : instance_transform.m20 != 0.0f ? model->size_z
2813  : model->size_x;
2814  int32_t half_dim = max_dim / 2;
2815  int32_t min_x = (int32_t)instance_transform.m30 - half_dim;
2816  int32_t max_x = (int32_t)instance_transform.m30 + half_dim;
2817  scene_min_x = min_x < scene_min_x ? min_x : scene_min_x;
2818  scene_max_x = max_x > scene_max_x ? max_x : scene_max_x;
2819  }
2820  // pass out the dimensions.
2821  out_min_x = scene_min_x;
2822  out_max_x = scene_max_x;
2823  }
2824  else
2825  {
2826  out_min_x = 0;
2827  out_max_x = 0;
2828  }
2829 }
2830 
2831 // returns a mask of which color indices are used by the specified scene.
2832 // used_mask[0] can be false at the end of this if all models 100% fill their voxel grid with solid voxels, so callers
2833 // should handle that case properly.
2834 static void compute_scene_used_color_index_mask(bool* pUsed_mask, const ogt_vox_scene* pScene)
2835 {
2836  memset(pUsed_mask, 0, 256);
2837  for (uint32_t model_index = 0; model_index < pScene->num_models; model_index++)
2838  {
2839  const ogt_vox_model* model = pScene->models[model_index];
2840  uint32_t voxel_count = model->size_x * model->size_y * model->size_z;
2841  for (uint32_t voxel_index = 0; voxel_index < voxel_count; voxel_index++)
2842  {
2843  uint8_t color_index = model->voxel_data[voxel_index];
2844  pUsed_mask[color_index] = true;
2845  }
2846  }
2847 }
2848 
2849 // finds an exact color in the specified palette if it exists, and UINT32_MAX otherwise
2850 static uint32_t find_exact_color_in_palette(const ogt_vox_rgba* pPalette, uint32_t palette_count, const ogt_vox_rgba color_to_find)
2851 {
2852  for (uint32_t color_index = 1; color_index < palette_count; color_index++)
2853  {
2854  const ogt_vox_rgba color_to_match = pPalette[color_index];
2855  // we only try to match r,g,b components exactly.
2856  if (color_to_match.r == color_to_find.r && color_to_match.g == color_to_find.g && color_to_match.b == color_to_find.b)
2857  return color_index;
2858  }
2859  // no exact color found
2860  return UINT32_MAX;
2861 }
2862 
2863 // finds the index within the specified palette that is closest to the color we want to find
2864 static uint32_t find_closest_color_in_palette(const ogt_vox_rgba* pPalette, uint32_t palette_count, const ogt_vox_rgba color_to_find)
2865 {
2866  // the lower the score the better, so initialize this to the maximum possible score
2867  int32_t best_score = INT32_MAX;
2868  uint32_t best_index = 1;
2869  // Here we compute a score based on the pythagorean distance between each color in the palette and the color to find.
2870  // The distance is in R,G,B space, and we choose the color with the lowest score.
2871  for (uint32_t color_index = 1; color_index < palette_count; color_index++)
2872  {
2873  int32_t r_diff = (int32_t)color_to_find.r - (int32_t)pPalette[color_index].r;
2874  int32_t g_diff = (int32_t)color_to_find.g - (int32_t)pPalette[color_index].g;
2875  int32_t b_diff = (int32_t)color_to_find.b - (int32_t)pPalette[color_index].b;
2876  // There are 2 aspects of our treatment of color here you may want to experiment with:
2877  // 1. differences in R, differences in G, differences in B are weighted the same rather than perceptually. Different weightings may be better for you.
2878  // 2. We treat R,G,B as if they are in a perceptually linear within each channel. eg. the differences between
2879  // a value of 5 and 8 in any channel is perceptually the same as the difference between 233 and 236 in the same channel.
2880  int32_t score = (r_diff * r_diff) + (g_diff * g_diff) + (b_diff * b_diff);
2881  if (score < best_score)
2882  {
2883  best_score = score;
2884  best_index = color_index;
2885  }
2886  }
2887  assert(best_score < UINT32_MAX); // this might indicate a completely degenerate palette.
2888  return best_index;
2889 }
2890 
2891 static void update_master_palette_from_scene(ogt_vox_rgba* pMaster_palette, uint32_t& ref_master_palette_count, const ogt_vox_scene* pScene, uint32_t* pScene_to_master_map)
2892 {
2893  // compute the mask of used colors in the scene.
2894  bool scene_used_mask[256];
2895  compute_scene_used_color_index_mask(scene_used_mask, pScene);
2896 
2897  // initialize the map that converts from scene color_index to master color_index
2898  pScene_to_master_map[0] = 0; // zero/empty always maps to zero/empty in the master palette
2899  for (uint32_t i = 1; i < 256; i++)
2900  pScene_to_master_map[i] = UINT32_MAX; // UINT32_MAX means unassigned
2901 
2902  // for each used color in the scene, now allocate it into the master palette.
2903  for (uint32_t color_index = 1; color_index < 256; color_index++)
2904  {
2905  if (scene_used_mask[color_index])
2906  {
2907  const ogt_vox_rgba color = pScene->palette.color[color_index];
2908  // find the exact color in the master palette. Will be UINT32_MAX if the color doesn't already exist
2909  uint32_t master_index = find_exact_color_in_palette(pMaster_palette, ref_master_palette_count, color);
2910  if (master_index == UINT32_MAX)
2911  {
2912  if (ref_master_palette_count < 256)
2913  {
2914  // master palette capacity hasn't been exceeded so far, allocate the color to it.
2915  pMaster_palette[ref_master_palette_count] = color;
2916  master_index = ref_master_palette_count++;
2917  }
2918  else
2919  {
2920  // otherwise, find the color that is perceptually closest to the original color.
2921 
2922  // TODO(jpaver): It is potentially problematic if we hit this path for a many-scene merge.
2923  // Earlier scenes will reserve their colors exactly into the master palette, whereas later
2924  // scenes will end up having some of their colors remapped to different colors.
2925 
2926  // A more holistic approach to color allocation may be necessary here eg.
2927  // we might allow the master palette to grow to more than 256 entries, and then use
2928  // similarity/frequency metrics to reduce the palette from that down to 256 entries. This
2929  // will mean all scenes will have be equally important if they have a high-frequency
2930  // usage of a color.
2931  master_index = find_closest_color_in_palette(pMaster_palette, ref_master_palette_count, color);
2932  }
2933  }
2934  // caller needs to know how to map its original color index into the master palette
2935  pScene_to_master_map[color_index] = master_index;
2936  }
2937  }
2938 }
2939 
2940 ogt_vox_scene* ogt_vox_merge_scenes(const ogt_vox_scene** pScenes, uint32_t scene_count, const ogt_vox_rgba* pRequired_colors, const uint32_t required_color_count)
2941 {
2942  assert(required_color_count <= 255); // can't exceed the maximum colors in the master palette plus the empty slot.
2943 
2944  // initialize the master palette. If required colors are specified, map them into the master palette now.
2945  ogt_vox_rgba master_palette[256];
2946  uint32_t master_palette_count = 1; // color_index 0 is reserved for empty color!
2947  memset(&master_palette, 0, sizeof(master_palette));
2948  for (uint32_t required_index = 0; required_index < required_color_count; required_index++)
2949  master_palette[master_palette_count++] = pRequired_colors[required_index];
2950 
2951  // count the number of required models, instances in the master scene
2952  uint32_t max_layers = 1; // we don't actually merge layers. Every instance will be in layer 0.
2953  uint32_t max_models = 0;
2954  uint32_t max_instances = 0;
2955  uint32_t max_groups = 1; // we add 1 root global group that everything will ultimately be parented to.
2956  for (uint32_t scene_index = 0; scene_index < scene_count; scene_index++)
2957  {
2958  if (!pScenes[scene_index])
2959  continue;
2960  max_instances += pScenes[scene_index]->num_instances;
2961  max_models += pScenes[scene_index]->num_models;
2962  max_groups += pScenes[scene_index]->num_groups;
2963  }
2964 
2965  // allocate the master instances array
2966  ogt_vox_instance* instances = (ogt_vox_instance*)_vox_malloc(sizeof(ogt_vox_instance) * max_instances);
2967  ogt_vox_model** models = (ogt_vox_model**)_vox_malloc(sizeof(ogt_vox_model*) * max_models);
2968  ogt_vox_layer* layers = (ogt_vox_layer*)_vox_malloc(sizeof(ogt_vox_layer) * max_layers);
2969  ogt_vox_group* groups = (ogt_vox_group*)_vox_malloc(sizeof(ogt_vox_group) * max_groups);
2970  uint32_t num_instances = 0;
2971  uint32_t num_models = 0;
2972  uint32_t num_layers = 0;
2973  uint32_t num_groups = 0;
2974 
2975  // add a single layer.
2976  layers[num_layers].hidden = false;
2977  layers[num_layers].name = "merged";
2978  num_layers++;
2979 
2980  // magicavoxel expects exactly 1 root group, so if we have multiple scenes with multiple roots,
2981  // we must ensure all merged scenes are parented to the same root group. Allocate it now for the
2982  // merged scene.
2983  uint32_t global_root_group_index = num_groups;
2984  {
2985  assert(global_root_group_index == 0);
2986  ogt_vox_group root_group;
2987  root_group.hidden = false;
2988  root_group.layer_index = 0;
2989  root_group.parent_group_index = k_invalid_group_index;
2990  root_group.transform = _vox_transform_identity();
2991  groups[num_groups++] = root_group;
2992  }
2993 
2994  // go ahead and do the merge now!
2995  size_t string_data_size = 0;
2996  int32_t offset_x = 0;
2997  for (uint32_t scene_index = 0; scene_index < scene_count; scene_index++)
2998  {
2999  const ogt_vox_scene* scene = pScenes[scene_index];
3000  if (!scene)
3001  continue;
3002 
3003  // update the master palette, and get the map of this scene's color indices into the master palette.
3004  uint32_t scene_color_index_to_master_map[256];
3005  update_master_palette_from_scene(master_palette, master_palette_count, scene, scene_color_index_to_master_map);
3006 
3007  // cache away the base model index for this scene.
3008  uint32_t base_model_index = num_models;
3009  uint32_t base_group_index = num_groups;
3010 
3011  // create copies of all models that have color indices remapped.
3012  for (uint32_t model_index = 0; model_index < scene->num_models; model_index++)
3013  {
3014  const ogt_vox_model* model = scene->models[model_index];
3015  uint32_t voxel_count = model->size_x * model->size_y * model->size_z;
3016  // clone the model
3017  ogt_vox_model* override_model = (ogt_vox_model*)_vox_malloc(sizeof(ogt_vox_model) + voxel_count);
3018  uint8_t* override_voxel_data = (uint8_t*)&override_model[1];
3019 
3020  // remap all color indices in the cloned model so they reference the master palette now!
3021  for (uint32_t voxel_index = 0; voxel_index < voxel_count; voxel_index++)
3022  {
3023  uint8_t old_color_index = model->voxel_data[voxel_index];
3024  uint32_t new_color_index = scene_color_index_to_master_map[old_color_index];
3025  assert(new_color_index < 256);
3026  override_voxel_data[voxel_index] = (uint8_t)new_color_index;
3027  }
3028  // assign the new model.
3029  *override_model = *model;
3030  override_model->voxel_data = override_voxel_data;
3031  override_model->voxel_hash = _vox_hash(override_voxel_data, voxel_count);
3032 
3033  models[num_models++] = override_model;
3034  }
3035 
3036  // compute the scene bounding box on x dimension. this is used to offset instances
3037  // and groups in the merged model along X dimension such that they do not overlap
3038  // with instances from another scene in the merged model.
3039  int32_t scene_min_x, scene_max_x;
3040  compute_scene_bounding_box_x(scene, scene_min_x, scene_max_x);
3041  float scene_offset_x = (float)(offset_x - scene_min_x);
3042 
3043  // each scene has a root group, and it must the 0th group in its local groups[] array,
3044  assert(scene->groups[0].parent_group_index == k_invalid_group_index);
3045  // create copies of all groups into the merged scene (except the root group from each scene -- which is why we start group_index at 1 here)
3046  for (uint32_t group_index = 1; group_index < scene->num_groups; group_index++)
3047  {
3048  const ogt_vox_group* src_group = &scene->groups[group_index];
3049  assert(src_group->parent_group_index != k_invalid_group_index); // there can be only 1 root group per scene and it must be the 0th group.
3050  ogt_vox_group dst_group = *src_group;
3051  assert(dst_group.parent_group_index < scene->num_groups);
3052  dst_group.layer_index = 0;
3053  dst_group.parent_group_index = (dst_group.parent_group_index == 0) ? global_root_group_index : base_group_index + (dst_group.parent_group_index - 1);
3054  // if this group belongs to the global root group, it must be translated so it doesn't overlap with other scenes.
3055  if (dst_group.parent_group_index == global_root_group_index)
3056  dst_group.transform.m30 += scene_offset_x;
3057  groups[num_groups++] = dst_group;
3058  }
3059 
3060  // create copies of all instances (and bias them such that minimum on x starts at zero)
3061  for (uint32_t instance_index = 0; instance_index < scene->num_instances; instance_index++)
3062  {
3063  const ogt_vox_instance* src_instance = &scene->instances[instance_index];
3064  assert(src_instance->group_index < scene->num_groups); // every instance must be mapped to a group.
3065  ogt_vox_instance* dst_instance = &instances[num_instances++];
3066  *dst_instance = *src_instance;
3067  dst_instance->layer_index = 0;
3068  dst_instance->group_index = (dst_instance->group_index == 0) ? global_root_group_index : base_group_index + (dst_instance->group_index - 1);
3069  dst_instance->model_index += base_model_index;
3070  if (dst_instance->name)
3071  string_data_size += _vox_strlen(dst_instance->name) + 1; // + 1 for zero terminator
3072  // if this instance belongs to the global rot group, it must be translated so it doesn't overlap with other scenes.
3073  if (dst_instance->group_index == global_root_group_index)
3074  dst_instance->transform.m30 += scene_offset_x;
3075  }
3076 
3077  offset_x += (scene_max_x - scene_min_x); // step the width of the scene in x dimension
3078  offset_x += 4; // a margin of this many voxels between scenes
3079  }
3080 
3081  // fill any unused master palette entries with purple/invalid color.
3082  const ogt_vox_rgba k_invalid_color = {255, 0, 255, 255}; // purple = invalid
3083  for (uint32_t color_index = master_palette_count; color_index < 256; color_index++)
3084  master_palette[color_index] = k_invalid_color;
3085 
3086  // assign the master scene on output. string_data is part of the scene allocation.
3087  size_t scene_size = sizeof(ogt_vox_scene) + string_data_size;
3088  ogt_vox_scene* merged_scene = (ogt_vox_scene*)_vox_calloc(scene_size);
3089 
3090  // copy name data into the string section and make instances point to it. This makes the merged model self-contained.
3091  char* scene_string_data = (char*)&merged_scene[1];
3092  for (uint32_t instance_index = 0; instance_index < num_instances; instance_index++)
3093  {
3094  if (instances[instance_index].name)
3095  {
3096  size_t string_len = _vox_strlen(instances[instance_index].name) + 1; // +1 for zero terminator
3097  memcpy(scene_string_data, instances[instance_index].name, string_len);
3098  instances[instance_index].name = scene_string_data;
3099  scene_string_data += string_len;
3100  }
3101  }
3102 
3103  assert(num_groups <= max_groups);
3104 
3105  memset(merged_scene, 0, sizeof(ogt_vox_scene));
3106  merged_scene->instances = instances;
3107  merged_scene->num_instances = max_instances;
3108  merged_scene->models = (const ogt_vox_model**)models;
3109  merged_scene->num_models = max_models;
3110  merged_scene->layers = layers;
3111  merged_scene->num_layers = max_layers;
3112  merged_scene->groups = groups;
3113  merged_scene->num_groups = num_groups;
3114  // copy color palette into the merged scene
3115  for (uint32_t color_index = 0; color_index < 256; color_index++)
3116  merged_scene->palette.color[color_index] = master_palette[color_index];
3117 
3118  return merged_scene;
3119 }
3120 
3121 #endif // #ifdef OGT_VOX_IMPLEMENTATION
3122 
3123 /* -------------------------------------------------------------------------------------------------------------------------------------------------
3124 
3125  MIT License
3126 
3127  Copyright (c) 2019 Justin Paver
3128 
3129  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
3130  to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
3131  and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
3132 
3133  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
3134 
3135  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3136  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3137  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
3138  IN THE SOFTWARE.
3139 
3140 ------------------------------------------------------------------------------------------------------------------------------------------------- */
ogt_vox_group
Definition: ogt_vox.h:203
ogt_vox_scene
Definition: ogt_vox.h:212
ogt_vox_layer
Definition: ogt_vox.h:196
ogt_vox_model
Definition: ogt_vox.h:175
ogt_vox_transform
Definition: ogt_vox.h:160
ogt_vox_instance
Definition: ogt_vox.h:185
ogt_vox_rgba
Definition: ogt_vox.h:154
ogt_vox_palette
Definition: ogt_vox.h:169