125typedef unsigned char uint8_t;
126typedef signed int int32_t;
127typedef unsigned int uint32_t;
129# define UINT32_MAX ((uint32_t)0xFFFFFFFF)
132# define INT32_MAX ((int32_t)0x7FFFFFFF)
135# define UINT8_MAX ((uint8_t)0xFF)
137# elif defined(_MSC_VER)
139# include <inttypes.h>
142# elif defined(__GNUC__)
144# include <inttypes.h>
147# error some fixup needed for this platform?
151static const uint32_t k_invalid_group_index = UINT32_MAX;
162 float m00, m01, m02, m03;
163 float m10, m11, m12, m13;
164 float m20, m21, m22, m23;
165 float m30, m31, m32, m33;
181 const uint8_t* voxel_data;
189 uint32_t model_index;
190 uint32_t layer_index;
191 uint32_t group_index;
206 uint32_t parent_group_index;
207 uint32_t layer_index;
215 uint32_t num_instances;
226typedef void* (*ogt_vox_alloc_func)(
size_t size);
229typedef void (*ogt_vox_free_func)(
void* ptr);
232void ogt_vox_set_memory_allocator(ogt_vox_alloc_func alloc_func, ogt_vox_free_func free_func);
233void* ogt_vox_malloc(
size_t uiSize);
234void ogt_vox_free(
void* pMem);
237static const uint32_t k_read_scene_flags_groups = 1 << 0;
241const ogt_vox_scene* ogt_vox_read_scene(
const uint8_t* pBuffer, uint32_t buffer_size);
244const ogt_vox_scene* ogt_vox_read_scene_with_flags(
const uint8_t* pBuffer, uint32_t buffer_size, uint32_t read_flags);
250uint8_t* ogt_vox_write_scene(
const ogt_vox_scene* pScene, uint32_t* pBuffer_size);
264#ifdef OGT_VOX_IMPLEMENTATION
271# define MAKE_VOX_CHUNK_ID(c0, c1, c2, c3) ((c0 << 0) | (c1 << 8) | (c2 << 16) | (c3 << 24))
273static const uint32_t CHUNK_ID_VOX_ = MAKE_VOX_CHUNK_ID(
'V',
'O',
'X',
' ');
274static const uint32_t CHUNK_ID_MAIN = MAKE_VOX_CHUNK_ID(
'M',
'A',
'I',
'N');
275static const uint32_t CHUNK_ID_SIZE = MAKE_VOX_CHUNK_ID(
'S',
'I',
'Z',
'E');
276static const uint32_t CHUNK_ID_XYZI = MAKE_VOX_CHUNK_ID(
'X',
'Y',
'Z',
'I');
277static const uint32_t CHUNK_ID_RGBA = MAKE_VOX_CHUNK_ID(
'R',
'G',
'B',
'A');
278static const uint32_t CHUNK_ID_nTRN = MAKE_VOX_CHUNK_ID(
'n',
'T',
'R',
'N');
279static const uint32_t CHUNK_ID_nGRP = MAKE_VOX_CHUNK_ID(
'n',
'G',
'R',
'P');
280static const uint32_t CHUNK_ID_nSHP = MAKE_VOX_CHUNK_ID(
'n',
'S',
'H',
'P');
281static const uint32_t CHUNK_ID_IMAP = MAKE_VOX_CHUNK_ID(
'I',
'M',
'A',
'P');
282static const uint32_t CHUNK_ID_LAYR = MAKE_VOX_CHUNK_ID(
'L',
'A',
'Y',
'R');
283static const uint32_t CHUNK_ID_MATL = MAKE_VOX_CHUNK_ID(
'M',
'A',
'T',
'L');
284static const uint32_t CHUNK_ID_MATT = MAKE_VOX_CHUNK_ID(
'M',
'A',
'T',
'T');
285static const uint32_t CHUNK_ID_rOBJ = MAKE_VOX_CHUNK_ID(
'r',
'O',
'B',
'J');
288static const uint8_t k_default_vox_palette[256 * 4] = {
1316static inline uint32_t _vox_max(uint32_t a, uint32_t b)
1318 return (a > b) ? a : b;
1320static inline uint32_t _vox_min(uint32_t a, uint32_t b)
1322 return (a < b) ? a : b;
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__)
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__)
1347static inline vec3 vec3_make(
float x,
float y,
float z)
1355static inline vec3 vec3_negate(
const vec3& v)
1367 const uint8_t* buffer;
1368 const uint32_t buffer_size;
1372static bool _vox_file_read(_vox_file* pFp,
void* pData, uint32_t data_size)
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;
1380static void _vox_file_seek_forwards(_vox_file* pFp, uint32_t offset)
1382 pFp->offset += offset;
1385static bool _vox_file_eof(
const _vox_file* pFp)
1387 return pFp->offset >= pFp->buffer_size;
1390static const void* _vox_file_data_pointer(
const _vox_file* pFp)
1392 return &pFp->buffer[pFp->offset];
1396static uint32_t _vox_hash(
const uint8_t* pData, uint32_t data_size)
1399 for (uint32_t i = 0; i < data_size; i++)
1400 hash = pData[i] + (hash * 65559);
1405static void* _ogt_priv_alloc_default(
size_t uiSize)
1407 return malloc(uiSize);
1409static void _ogt_priv_free_default(
void* pPtr)
1413static ogt_vox_alloc_func g_alloc_func = _ogt_priv_alloc_default;
1414static ogt_vox_free_func g_free_func = _ogt_priv_free_default;
1417void ogt_vox_set_memory_allocator(ogt_vox_alloc_func alloc_func, ogt_vox_free_func free_func)
1419 assert((alloc_func && free_func) ||
1420 (!alloc_func && !free_func));
1421 if (alloc_func && free_func)
1423 g_alloc_func = alloc_func;
1424 g_free_func = free_func;
1429 g_alloc_func = _ogt_priv_alloc_default;
1430 g_free_func = _ogt_priv_free_default;
1434static void* _vox_malloc(
size_t uiSize)
1436 return uiSize ? g_alloc_func(uiSize) : NULL;
1439static void* _vox_calloc(
size_t uiSize)
1441 void* pMem = _vox_malloc(uiSize);
1443 memset(pMem, 0, uiSize);
1447static void _vox_free(
void* pOld_ptr)
1450 g_free_func(pOld_ptr);
1453static void* _vox_realloc(
void* pOld_ptr,
size_t uiOld_size,
size_t uiNew_size)
1456 if (uiNew_size && uiOld_size >= uiNew_size)
1460 void* new_ptr = _vox_malloc(uiNew_size);
1464 if (pOld_ptr && uiOld_size)
1465 memcpy(new_ptr, pOld_ptr, uiOld_size);
1467 assert(uiNew_size > uiOld_size);
1468 uintptr_t new_tail_ptr = (uintptr_t)new_ptr + uiOld_size;
1469 memset((
void*)new_tail_ptr, 0, uiNew_size - uiOld_size);
1472 _vox_free(pOld_ptr);
1481 data(NULL), capacity(0), count(0)
1491 void reserve(
size_t uiNew_capacity)
1493 data = (T*)_vox_realloc(data, capacity *
sizeof(T), uiNew_capacity *
sizeof(T));
1494 capacity = uiNew_capacity;
1496 void grow_to_fit_index(
size_t uiIndex)
1498 if (uiIndex >= count)
1499 resize(uiIndex + 1);
1501 void resize(
size_t uiNew_count)
1503 if (uiNew_count > capacity)
1504 reserve(uiNew_count);
1505 count = uiNew_count;
1507 void push_back(
const T& new_element)
1509 if (count == capacity)
1511 size_t new_capacity = capacity ? (capacity * 3) >> 1 : 2;
1512 reserve(new_capacity);
1513 assert(capacity > count);
1515 data[count++] = new_element;
1517 void push_back_many(
const T* pNew_elements,
size_t uiNum_elements)
1519 if (count + uiNum_elements > capacity)
1521 size_t new_capacity = capacity + uiNum_elements;
1522 new_capacity = new_capacity ? (new_capacity * 3) >> 1 : 2;
1523 reserve(new_capacity);
1524 assert(capacity >= (count + uiNum_elements));
1526 for (
size_t i = 0; i < uiNum_elements; i++)
1527 data[count + i] = pNew_elements[i];
1528 count += uiNum_elements;
1534 T& operator[](
size_t uiIndex)
1536 assert(uiIndex < count);
1537 return data[uiIndex];
1539 const T& operator[](
size_t uiIndex)
const
1541 assert(uiIndex < count);
1542 return data[uiIndex];
1575 r.m00 = (a.m00 * b.m00) + (a.m01 * b.m10) + (a.m02 * b.m20) + (a.m03 * b.m30);
1576 r.m01 = (a.m00 * b.m01) + (a.m01 * b.m11) + (a.m02 * b.m21) + (a.m03 * b.m31);
1577 r.m02 = (a.m00 * b.m02) + (a.m01 * b.m12) + (a.m02 * b.m22) + (a.m03 * b.m32);
1578 r.m03 = (a.m00 * b.m03) + (a.m01 * b.m13) + (a.m02 * b.m23) + (a.m03 * b.m33);
1579 r.m10 = (a.m10 * b.m00) + (a.m11 * b.m10) + (a.m12 * b.m20) + (a.m13 * b.m30);
1580 r.m11 = (a.m10 * b.m01) + (a.m11 * b.m11) + (a.m12 * b.m21) + (a.m13 * b.m31);
1581 r.m12 = (a.m10 * b.m02) + (a.m11 * b.m12) + (a.m12 * b.m22) + (a.m13 * b.m32);
1582 r.m13 = (a.m10 * b.m03) + (a.m11 * b.m13) + (a.m12 * b.m23) + (a.m13 * b.m33);
1583 r.m20 = (a.m20 * b.m00) + (a.m21 * b.m10) + (a.m22 * b.m20) + (a.m23 * b.m30);
1584 r.m21 = (a.m20 * b.m01) + (a.m21 * b.m11) + (a.m22 * b.m21) + (a.m23 * b.m31);
1585 r.m22 = (a.m20 * b.m02) + (a.m21 * b.m12) + (a.m22 * b.m22) + (a.m23 * b.m32);
1586 r.m23 = (a.m20 * b.m03) + (a.m21 * b.m13) + (a.m22 * b.m23) + (a.m23 * b.m33);
1587 r.m30 = (a.m30 * b.m00) + (a.m31 * b.m10) + (a.m32 * b.m20) + (a.m33 * b.m30);
1588 r.m31 = (a.m30 * b.m01) + (a.m31 * b.m11) + (a.m32 * b.m21) + (a.m33 * b.m31);
1589 r.m32 = (a.m30 * b.m02) + (a.m31 * b.m12) + (a.m32 * b.m22) + (a.m33 * b.m32);
1590 r.m33 = (a.m30 * b.m03) + (a.m31 * b.m13) + (a.m32 * b.m23) + (a.m33 * b.m33);
1595static const uint32_t k_vox_max_dict_buffer_size = 4096;
1596static const uint32_t k_vox_max_dict_key_value_pairs = 256;
1597struct _vox_dictionary
1599 const char* keys[k_vox_max_dict_key_value_pairs];
1600 const char* values[k_vox_max_dict_key_value_pairs];
1601 uint32_t num_key_value_pairs;
1602 char buffer[k_vox_max_dict_buffer_size + 4];
1603 uint32_t buffer_mem_used;
1606static bool _vox_file_read_dict(_vox_dictionary* pDict, _vox_file* pFp)
1608 uint32_t num_pairs_to_read = 0;
1609 _vox_file_read(pFp, &num_pairs_to_read,
sizeof(uint32_t));
1610 assert(num_pairs_to_read <= k_vox_max_dict_key_value_pairs);
1612 pDict->buffer_mem_used = 0;
1613 pDict->num_key_value_pairs = 0;
1614 for (uint32_t i = 0; i < num_pairs_to_read; i++)
1617 uint32_t key_string_size = 0;
1618 _vox_file_read(pFp, &key_string_size,
sizeof(uint32_t));
1620 if (pDict->buffer_mem_used + key_string_size > k_vox_max_dict_buffer_size)
1622 char* key = &pDict->buffer[pDict->buffer_mem_used];
1623 pDict->buffer_mem_used += key_string_size + 1;
1624 _vox_file_read(pFp, key, key_string_size);
1625 key[key_string_size] = 0;
1626 assert(_vox_strlen(key) == key_string_size);
1629 uint32_t value_string_size = 0;
1630 _vox_file_read(pFp, &value_string_size,
sizeof(uint32_t));
1632 if (pDict->buffer_mem_used + value_string_size > k_vox_max_dict_buffer_size)
1634 char* value = &pDict->buffer[pDict->buffer_mem_used];
1635 pDict->buffer_mem_used += value_string_size + 1;
1636 _vox_file_read(pFp, value, value_string_size);
1637 value[value_string_size] = 0;
1638 assert(_vox_strlen(value) == value_string_size);
1640 pDict->keys[pDict->num_key_value_pairs] = key;
1641 pDict->values[pDict->num_key_value_pairs] = value;
1642 pDict->num_key_value_pairs++;
1649static const char* _vox_dict_get_value_as_string(
const _vox_dictionary* pDict,
const char* szKey_to_find,
const char* szDefault_value = NULL)
1651 for (uint32_t i = 0; i < pDict->num_key_value_pairs; i++)
1652 if (_vox_strcasecmp(pDict->keys[i], szKey_to_find) == 0)
1653 return pDict->values[i];
1654 return szDefault_value;
1658static const vec3 k_vectors[4] = {
1659 vec3_make(1.0f, 0.0f, 0.0f),
1660 vec3_make(0.0f, 1.0f, 0.0f),
1661 vec3_make(0.0f, 0.0f, 1.0f),
1662 vec3_make(0.0f, 0.0f, 0.0f)
1666static const uint32_t k_row2_index[] = {UINT32_MAX, UINT32_MAX, UINT32_MAX, 2, UINT32_MAX, 1, 0, UINT32_MAX};
1669static ogt_vox_transform _vox_make_transform_from_dict_strings(
const char* szRotation_string,
const char* szTranslation_string)
1673 if (szRotation_string != NULL)
1680 uint32_t packed_rotation_bits = atoi(szRotation_string);
1681 uint32_t row0_vec_index = (packed_rotation_bits >> 0) & 3;
1682 uint32_t row1_vec_index = (packed_rotation_bits >> 2) & 3;
1683 uint32_t row2_vec_index = k_row2_index[(1 << row0_vec_index) | (1 << row1_vec_index)];
1684 assert(row2_vec_index != UINT32_MAX);
1691 vec3 row0 = k_vectors[row0_vec_index];
1692 vec3 row1 = k_vectors[row1_vec_index];
1693 vec3 row2 = k_vectors[row2_vec_index];
1694 if (packed_rotation_bits & (1 << 4))
1695 row0 = vec3_negate(row0);
1696 if (packed_rotation_bits & (1 << 5))
1697 row1 = vec3_negate(row1);
1698 if (packed_rotation_bits & (1 << 6))
1699 row2 = vec3_negate(row2);
1702 transform.m00 = row0.x;
1703 transform.m01 = row1.x;
1704 transform.m02 = row2.x;
1705 transform.m10 = row0.y;
1706 transform.m11 = row1.y;
1707 transform.m12 = row2.y;
1708 transform.m20 = row0.z;
1709 transform.m21 = row1.z;
1710 transform.m22 = row2.z;
1713 if (szTranslation_string != NULL)
1718 _vox_str_scanf(szTranslation_string,
"%i %i %i", &x, &y, &z);
1719 transform.m30 = (float)x;
1720 transform.m31 = (float)y;
1721 transform.m32 = (float)z;
1726enum _vox_scene_node_type
1728 k_nodetype_invalid = 0,
1729 k_nodetype_group = 1,
1730 k_nodetype_transform = 2,
1731 k_nodetype_shape = 3,
1734struct _vox_scene_node_
1736 _vox_scene_node_type node_type;
1743 ogt_vox_transform transform;
1744 uint32_t child_node_id;
1751 uint32_t first_child_node_id_index;
1752 uint32_t num_child_nodes;
1762static void generate_instances_for_node(
1763 const _vox_array<_vox_scene_node_>& nodes, uint32_t node_index,
const _vox_array<uint32_t>& child_id_array, uint32_t layer_index,
1764 const ogt_vox_transform& transform,
const _vox_array<ogt_vox_model*>& model_ptrs,
const char* szTransform_last_name,
bool bTransform_last_hidden,
1765 _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)
1767 const _vox_scene_node_* node = &nodes[node_index];
1769 switch (node->node_type)
1771 case k_nodetype_transform:
1773 ogt_vox_transform new_transform = (bGenerate_groups) ? node->u.transform.transform
1775 _vox_transform_multiply(node->u.transform.transform, transform);
1776 const char* new_transform_name = node->u.transform.name[0] ? node->u.transform.name : NULL;
1777 szTransform_last_name = new_transform_name ? new_transform_name : szTransform_last_name;
1778 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);
1781 case k_nodetype_group:
1784 uint32_t next_group_index = 0;
1785 if (bGenerate_groups)
1787 next_group_index = (uint32_t)ref_groups.size();
1789 group.parent_group_index = group_index;
1790 group.transform = transform;
1791 group.hidden = bTransform_last_hidden;
1792 group.layer_index = layer_index;
1793 ref_groups.push_back(group);
1796 bTransform_last_hidden =
false;
1798 const uint32_t* child_node_ids = (
const uint32_t*)&child_id_array[node->u.group.first_child_node_id_index];
1799 for (uint32_t i = 0; i < node->u.group.num_child_nodes; i++)
1801 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);
1805 case k_nodetype_shape:
1807 assert(node->u.shape.model_id < model_ptrs.size());
1808 if (node->u.shape.model_id < model_ptrs.size() &&
1809 model_ptrs[node->u.shape.model_id] != NULL)
1811 assert(bGenerate_groups || group_index == 0);
1813 new_instance.model_index = node->u.shape.model_id;
1814 new_instance.transform = transform;
1815 new_instance.layer_index = layer_index;
1816 new_instance.group_index = group_index;
1817 new_instance.hidden = bTransform_last_hidden;
1820 new_instance.name = 0;
1821 if (szTransform_last_name && szTransform_last_name[0])
1823 new_instance.name = (
const char*)(ref_string_data.size());
1824 size_t name_size = _vox_strlen(szTransform_last_name) + 1;
1825 ref_string_data.push_back_many(szTransform_last_name, name_size);
1828 ref_instances.push_back(new_instance);
1840static int _vox_ordered_compare_instance(
const void* p_lhs,
const void* p_rhs)
1844 return lhs->model_index < rhs->model_index ? -1 : lhs->model_index > rhs->model_index ? 1 :
1853 if (lhs->voxel_hash != rhs->voxel_hash)
1856 uint32_t num_voxels_lhs = lhs->size_x * lhs->size_y * lhs->size_z;
1857 uint32_t num_voxels_rhs = rhs->size_x * rhs->size_y * rhs->size_z;
1858 if (num_voxels_lhs != num_voxels_rhs)
1862 return memcmp(lhs->voxel_data, rhs->voxel_data, num_voxels_lhs) == 0 ? true :
false;
1865const ogt_vox_scene* ogt_vox_read_scene_with_flags(
const uint8_t* pBuffer, uint32_t buffer_size, uint32_t read_flags)
1867 _vox_file file = {pBuffer, buffer_size, 0};
1868 _vox_file* fp = &file;
1871 _vox_array<ogt_vox_model*> model_ptrs;
1872 _vox_array<_vox_scene_node_> nodes;
1873 _vox_array<ogt_vox_instance> instances;
1874 _vox_array<char> string_data;
1875 _vox_array<ogt_vox_layer> layers;
1876 _vox_array<ogt_vox_group> groups;
1877 _vox_array<uint32_t> child_ids;
1879 _vox_dictionary dict;
1880 uint32_t size_x = 0;
1881 uint32_t size_y = 0;
1882 uint32_t size_z = 0;
1883 uint8_t index_map[256];
1884 bool found_index_map_chunk =
false;
1887 model_ptrs.reserve(64);
1888 instances.reserve(256);
1889 child_ids.reserve(256);
1893 string_data.reserve(256);
1898 string_data.push_back(
'X');
1899 child_ids.push_back(-1);
1905 uint32_t file_header;
1906 uint32_t file_version;
1907 _vox_file_read(fp, &file_header,
sizeof(uint32_t));
1908 _vox_file_read(fp, &file_version,
sizeof(uint32_t));
1909 if (file_header != CHUNK_ID_VOX_ || file_version != 150)
1913 while (!_vox_file_eof(fp))
1916 uint32_t chunk_id = 0;
1917 uint32_t chunk_size = 0;
1918 uint32_t chunk_child_size = 0;
1919 _vox_file_read(fp, &chunk_id,
sizeof(uint32_t));
1920 _vox_file_read(fp, &chunk_size,
sizeof(uint32_t));
1921 _vox_file_read(fp, &chunk_child_size,
sizeof(uint32_t));
1928 assert(chunk_size == 0);
1933 assert(chunk_size == 12 && chunk_child_size == 0);
1934 _vox_file_read(fp, &size_x,
sizeof(uint32_t));
1935 _vox_file_read(fp, &size_y,
sizeof(uint32_t));
1936 _vox_file_read(fp, &size_z,
sizeof(uint32_t));
1941 assert(chunk_child_size == 0 && size_x && size_y && size_z);
1943 uint32_t num_voxels_in_chunk = 0;
1944 _vox_file_read(fp, &num_voxels_in_chunk,
sizeof(uint32_t));
1945 if (num_voxels_in_chunk != 0)
1947 uint32_t voxel_count = size_x * size_y * size_z;
1951 uint8_t* voxel_data = (uint8_t*)&model[1];
1954 model_ptrs.push_back(model);
1957 model->size_x = size_x;
1958 model->size_y = size_y;
1959 model->size_z = size_z;
1960 model->voxel_data = voxel_data;
1963 const uint32_t k_stride_x = 1;
1964 const uint32_t k_stride_y = size_x;
1965 const uint32_t k_stride_z = size_x * size_y;
1968 const uint8_t* packed_voxel_data = (
const uint8_t*)_vox_file_data_pointer(fp);
1969 for (uint32_t i = 0; i < num_voxels_in_chunk; i++)
1971 uint8_t x = packed_voxel_data[i * 4 + 0];
1972 uint8_t y = packed_voxel_data[i * 4 + 1];
1973 uint8_t z = packed_voxel_data[i * 4 + 2];
1974 uint8_t color_index = packed_voxel_data[i * 4 + 3];
1975 assert(x < size_x && y < size_y && z < size_z);
1976 voxel_data[(x * k_stride_x) + (y * k_stride_y) + (z * k_stride_z)] = color_index;
1978 _vox_file_seek_forwards(fp, num_voxels_in_chunk * 4);
1980 model->voxel_hash = _vox_hash(voxel_data, size_x * size_y * size_z);
1984 model_ptrs.push_back(NULL);
1990 assert(chunk_size ==
sizeof(palette));
1991 _vox_file_read(fp, &palette,
sizeof(palette));
1997 _vox_file_read(fp, &node_id,
sizeof(node_id));
2003 bool hidden =
false;
2006 _vox_file_read_dict(&dict, fp);
2007 const char* name_string = _vox_dict_get_value_as_string(&dict,
"_name");
2009 _vox_strcpy_static(node_name, name_string);
2011 const char* hidden_string = _vox_dict_get_value_as_string(&dict,
"_hidden",
"0");
2013 hidden = (hidden_string[0] ==
'1' ? true :
false);
2018 uint32_t child_node_id, reserved_id, layer_id, num_frames;
2019 _vox_file_read(fp, &child_node_id,
sizeof(child_node_id));
2020 _vox_file_read(fp, &reserved_id,
sizeof(reserved_id));
2021 _vox_file_read(fp, &layer_id,
sizeof(layer_id));
2022 _vox_file_read(fp, &num_frames,
sizeof(num_frames));
2023 assert(reserved_id == UINT32_MAX && num_frames == 1);
2031 _vox_file_read_dict(&dict, fp);
2032 const char* rotation_value = _vox_dict_get_value_as_string(&dict,
"_r");
2033 const char* translation_value = _vox_dict_get_value_as_string(&dict,
"_t");
2034 frame_transform = _vox_make_transform_from_dict_strings(rotation_value, translation_value);
2038 nodes.grow_to_fit_index(node_id);
2039 _vox_scene_node_* transform_node = &nodes[node_id];
2040 assert(transform_node);
2041 transform_node->node_type = k_nodetype_transform;
2042 transform_node->u.transform.child_node_id = child_node_id;
2043 transform_node->u.transform.layer_id = layer_id;
2044 transform_node->u.transform.transform = frame_transform;
2045 transform_node->u.transform.hidden = hidden;
2047 _vox_strcpy_static(transform_node->u.transform.name, node_name);
2054 _vox_file_read(fp, &node_id,
sizeof(node_id));
2057 _vox_file_read_dict(&dict, fp);
2060 nodes.grow_to_fit_index(node_id);
2061 _vox_scene_node_* group_node = &nodes[node_id];
2062 group_node->node_type = k_nodetype_group;
2063 group_node->u.group.first_child_node_id_index = 0;
2064 group_node->u.group.num_child_nodes = 0;
2067 uint32_t num_child_nodes = 0;
2068 _vox_file_read(fp, &num_child_nodes,
sizeof(num_child_nodes));
2071 if (num_child_nodes)
2073 size_t prior_size = child_ids.size();
2074 assert(prior_size > 0);
2075 child_ids.resize(prior_size + num_child_nodes);
2076 _vox_file_read(fp, &child_ids[prior_size],
sizeof(uint32_t) * num_child_nodes);
2077 group_node->u.group.first_child_node_id_index = (uint32_t)prior_size;
2078 group_node->u.group.num_child_nodes = num_child_nodes;
2085 _vox_file_read(fp, &node_id,
sizeof(node_id));
2088 nodes.grow_to_fit_index(node_id);
2089 _vox_scene_node_* shape_node = &nodes[node_id];
2090 shape_node->node_type = k_nodetype_shape;
2091 shape_node->u.shape.model_id = UINT32_MAX;
2094 _vox_file_read_dict(&dict, fp);
2096 uint32_t num_models = 0;
2097 _vox_file_read(fp, &num_models,
sizeof(num_models));
2098 assert(num_models == 1);
2101 _vox_file_read(fp, &shape_node->u.shape.model_id,
sizeof(uint32_t));
2102 assert(shape_node->u.shape.model_id < model_ptrs.size());
2105 _vox_file_read_dict(&dict, fp);
2110 assert(chunk_size == 256);
2111 _vox_file_read(fp, index_map, 256);
2112 found_index_map_chunk =
true;
2117 int32_t layer_id = 0;
2118 int32_t reserved_id = 0;
2119 _vox_file_read(fp, &layer_id,
sizeof(layer_id));
2120 _vox_file_read_dict(&dict, fp);
2121 _vox_file_read(fp, &reserved_id,
sizeof(reserved_id));
2122 assert(reserved_id == -1);
2124 layers.grow_to_fit_index(layer_id);
2125 layers[layer_id].name = NULL;
2126 layers[layer_id].hidden =
false;
2130 const char* name_string = _vox_dict_get_value_as_string(&dict,
"_name", NULL);
2133 layers[layer_id].name = (
const char*)(string_data.size());
2134 size_t name_size = _vox_strlen(name_string) + 1;
2135 string_data.push_back_many(name_string, name_size);
2138 const char* hidden_string = _vox_dict_get_value_as_string(&dict,
"_hidden",
"0");
2140 layers[layer_id].hidden = (hidden_string[0] ==
'1' ? true :
false);
2149 _vox_file_seek_forwards(fp, chunk_size);
2160 bool generate_groups = read_flags & k_read_scene_flags_groups ? true :
false;
2162 if (!generate_groups)
2165 root_group.transform = _vox_transform_identity();
2166 root_group.parent_group_index = k_invalid_group_index;
2167 root_group.layer_index = 0;
2168 root_group.hidden =
false;
2169 groups.push_back(root_group);
2171 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 else if (model_ptrs.size() == 1)
2177 new_instance.model_index = 0;
2178 new_instance.group_index = 0;
2179 new_instance.transform = _vox_transform_identity();
2180 new_instance.layer_index = 0;
2181 new_instance.name = 0;
2182 new_instance.hidden =
false;
2183 instances.push_back(new_instance);
2187 if (layers.size() == 0)
2190 for (uint32_t i = 0; i < instances.size(); i++)
2191 instances[i].layer_index = 0;
2194 new_layer.hidden =
false;
2195 new_layer.name = NULL;
2196 layers.push_back(new_layer);
2210 if (found_index_map_chunk)
2214 uint8_t index_map_inverse[256];
2215 for (uint32_t i = 0; i < 256; i++)
2217 index_map_inverse[index_map[i]] = (uint8_t)i;
2222 for (uint32_t i = 0; i < 256; i++)
2224 uint32_t remapped_index = (index_map[i] + 255) & 0xFF;
2225 palette.color[i] = old_palette.color[remapped_index];
2229 for (uint32_t i = 0; i < model_ptrs.size(); i++)
2234 uint32_t num_voxels = model->size_x * model->size_y * model->size_z;
2235 uint8_t* voxels = (uint8_t*)&model[1];
2236 for (uint32_t j = 0; j < num_voxels; j++)
2237 voxels[j] = 1 + index_map_inverse[voxels[j]];
2245 for (uint32_t i = 255; i > 0; i--)
2246 palette.color[i] = palette.color[i - 1];
2247 palette.color[0] = last_color;
2248 palette.color[0].a = 0;
2254 for (uint32_t i = 0; i < model_ptrs.size(); i++)
2258 for (uint32_t j = i + 1; j < model_ptrs.size(); j++)
2260 if (!model_ptrs[j] || !_vox_models_are_equal(model_ptrs[i], model_ptrs[j]))
2263 _vox_free(model_ptrs[j]);
2264 model_ptrs[j] = NULL;
2266 for (uint32_t k = 0; k < instances.size(); k++)
2267 if (instances[k].model_index == j)
2268 instances[k].model_index = i;
2279 bool found_empty_model =
false;
2280 for (uint32_t i = 0; i < model_ptrs.size() && !found_empty_model; i++)
2282 if (model_ptrs[i] == NULL)
2283 found_empty_model =
true;
2285 if (found_empty_model)
2288 uint32_t* model_remap = (uint32_t*)_vox_malloc(model_ptrs.size() *
sizeof(uint32_t));
2289 uint32_t num_output_models = 0;
2290 for (uint32_t i = 0; i < model_ptrs.size(); i++)
2292 if (model_ptrs[i] != NULL)
2294 model_ptrs[num_output_models] = model_ptrs[i];
2295 model_remap[i] = num_output_models;
2296 num_output_models++;
2300 model_remap[i] = UINT32_MAX;
2303 model_ptrs.resize(num_output_models);
2306 for (uint32_t i = 0; i < instances.size(); i++)
2308 uint32_t new_model_index = model_remap[instances[i].model_index];
2309 assert(new_model_index != UINT32_MAX);
2310 instances[i].model_index = new_model_index;
2314 _vox_free(model_remap);
2320 size_t scene_size =
sizeof(
ogt_vox_scene) + string_data.size();
2324 char* scene_string_data = (
char*)&scene[1];
2325 memcpy(scene_string_data, &string_data[0],
sizeof(
char) * string_data.size());
2328 size_t num_scene_instances = instances.size();
2330 if (num_scene_instances)
2332 memcpy(scene_instances, &instances[0],
sizeof(
ogt_vox_instance) * num_scene_instances);
2333 qsort(scene_instances, num_scene_instances,
sizeof(
ogt_vox_instance), _vox_ordered_compare_instance);
2335 scene->instances = scene_instances;
2336 scene->num_instances = (uint32_t)instances.size();
2339 size_t num_scene_models = model_ptrs.size();
2341 if (num_scene_models)
2342 memcpy(scene_models, &model_ptrs[0],
sizeof(
ogt_vox_model*) * num_scene_models);
2344 scene->num_models = (uint32_t)num_scene_models;
2347 size_t num_scene_layers = layers.size();
2349 memcpy(scene_layers, &layers[0],
sizeof(
ogt_vox_layer) * num_scene_layers);
2350 scene->layers = scene_layers;
2351 scene->num_layers = (uint32_t)num_scene_layers;
2354 size_t num_scene_groups = groups.size();
2356 if (num_scene_groups)
2357 memcpy(scene_groups, &groups[0],
sizeof(
ogt_vox_group) * num_scene_groups);
2358 scene->groups = scene_groups;
2359 scene->num_groups = (uint32_t)num_scene_groups;
2362 for (uint32_t i = 0; i < num_scene_instances; i++)
2363 if (scene_instances[i].name)
2364 scene_instances[i].name = scene_string_data + (size_t)scene_instances[i].name;
2367 for (uint32_t i = 0; i < num_scene_layers; i++)
2368 if (scene_layers[i].name)
2369 scene_layers[i].name = scene_string_data + (size_t)scene_layers[i].name;
2372 scene->palette = palette;
2377const ogt_vox_scene* ogt_vox_read_scene(
const uint8_t* pBuffer, uint32_t buffer_size)
2379 return ogt_vox_read_scene_with_flags(pBuffer, buffer_size, 0);
2386 for (uint32_t i = 0; i < scene->num_models; i++)
2387 _vox_free((
void*)scene->models[i]);
2391 _vox_free(scene->models);
2392 scene->models = NULL;
2395 if (scene->instances)
2398 scene->instances = NULL;
2404 scene->layers = NULL;
2410 scene->groups = NULL;
2418static bool _vox_get_vec3_rotation_bits(
const vec3& vec, uint32_t& out_index)
2420 const float* f = &vec.x;
2422 bool is_negative =
false;
2423 for (uint32_t i = 0; i < 3; i++)
2425 if (f[i] == 1.0f || f[i] == -1.0f)
2428 is_negative = f[i] < 0.0f ? true :
false;
2432 assert(f[i] == 0.0f);
2435 assert(out_index != 3);
2439static uint8_t _vox_make_packed_rotation_from_transform(
const ogt_vox_transform* pTransform)
2442 vec3 row0 = vec3_make(pTransform->m00, pTransform->m10, pTransform->m20);
2443 vec3 row1 = vec3_make(pTransform->m01, pTransform->m11, pTransform->m21);
2444 vec3 row2 = vec3_make(pTransform->m02, pTransform->m12, pTransform->m22);
2445 uint32_t row0_index = 3, row1_index = 3, row2_index = 3;
2446 bool row0_negative = _vox_get_vec3_rotation_bits(row0, row0_index);
2447 bool row1_negative = _vox_get_vec3_rotation_bits(row1, row1_index);
2448 bool row2_negative = _vox_get_vec3_rotation_bits(row2, row2_index);
2449 assert(((1 << row0_index) | (1 << row1_index) | (1 << row2_index)) == 7);
2450 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));
2453struct _vox_file_writeable
2455 _vox_array<uint8_t> data;
2458static void _vox_file_writeable_init(_vox_file_writeable* pFp)
2460 pFp->data.reserve(1024);
2462static void _vox_file_write(_vox_file_writeable* pFp,
const void* pData, uint32_t data_size)
2464 pFp->data.push_back_many((
const uint8_t*)pData, data_size);
2466static void _vox_file_write_uint32(_vox_file_writeable* pFp, uint32_t data)
2468 pFp->data.push_back_many((
const uint8_t*)&data,
sizeof(uint32_t));
2470static void _vox_file_write_uint8(_vox_file_writeable* pFp, uint8_t data)
2472 pFp->data.push_back_many((
const uint8_t*)&data,
sizeof(uint8_t));
2474static uint32_t _vox_file_get_offset(
const _vox_file_writeable* pFp)
2476 return (uint32_t)pFp->data.count;
2478static uint8_t* _vox_file_get_data(_vox_file_writeable* pFp)
2480 return &pFp->data[0];
2482static void _vox_file_write_dict_key_value(_vox_file_writeable* pFp,
const char* szKey,
const char* value)
2484 if (szKey == NULL || value == NULL)
2486 uint32_t key_len = (uint32_t)_vox_strlen(szKey);
2487 uint32_t value_len = (uint32_t)_vox_strlen(value);
2488 _vox_file_write_uint32(pFp, key_len);
2489 _vox_file_write(pFp, szKey, key_len);
2490 _vox_file_write_uint32(pFp, value_len);
2491 _vox_file_write(pFp, value, value_len);
2494static uint32_t _vox_dict_key_value_size(
const char* szKey,
const char* value)
2496 if (szKey == NULL || value == NULL)
2498 size_t size =
sizeof(uint32_t) + _vox_strlen(szKey) +
sizeof(uint32_t) + _vox_strlen(value);
2499 return (uint32_t)size;
2502static 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)
2505 const char* hidden_string = bHidden ?
"1" : NULL;
2506 const char* t_string = NULL;
2507 const char* r_string = NULL;
2508 char t_string_buf[64];
2509 char r_string_buf[64];
2510 t_string_buf[0] = 0;
2511 r_string_buf[0] = 0;
2512 if (pTransform != NULL)
2514 uint8_t packed_rotation_bits = _vox_make_packed_rotation_from_transform(pTransform);
2515 _vox_sprintf(t_string_buf,
sizeof(t_string_buf),
"%i %i %i", (int32_t)pTransform->m30, (int32_t)pTransform->m31, (int32_t)pTransform->m32);
2516 _vox_sprintf(r_string_buf,
sizeof(r_string_buf),
"%u", packed_rotation_bits);
2517 t_string = t_string_buf;
2518 r_string = r_string_buf;
2521 uint32_t node_dict_size =
2523 _vox_dict_key_value_size(
"_name", szName) +
2524 _vox_dict_key_value_size(
"_hidden", hidden_string);
2526 uint32_t frame_dict_size =
2528 _vox_dict_key_value_size(
"_t", t_string) +
2529 _vox_dict_key_value_size(
"_r", r_string);
2531 uint32_t chunk_size_ntrn =
2534 4 *
sizeof(uint32_t) +
2538 _vox_file_write_uint32(pFp, CHUNK_ID_nTRN);
2539 _vox_file_write_uint32(pFp, chunk_size_ntrn);
2540 _vox_file_write_uint32(pFp, 0);
2543 _vox_file_write_uint32(pFp, node_id);
2546 uint32_t node_dict_keyvalue_count = (szName ? 1 : 0) + (hidden_string ? 1 : 0);
2547 _vox_file_write_uint32(pFp, node_dict_keyvalue_count);
2548 _vox_file_write_dict_key_value(pFp,
"_name", szName);
2549 _vox_file_write_dict_key_value(pFp,
"_hidden", hidden_string);
2552 _vox_file_write_uint32(pFp, child_node_id);
2553 _vox_file_write_uint32(pFp, UINT32_MAX);
2554 _vox_file_write_uint32(pFp, layer_id);
2555 _vox_file_write_uint32(pFp, 1);
2558 _vox_file_write_uint32(pFp, (r_string ? 1 : 0) + (t_string ? 1 : 0));
2559 _vox_file_write_dict_key_value(pFp,
"_r", r_string);
2560 _vox_file_write_dict_key_value(pFp,
"_t", t_string);
2564uint8_t* ogt_vox_write_scene(
const ogt_vox_scene* pScene, uint32_t* pBuffer_size)
2566 _vox_file_writeable file;
2567 _vox_file_writeable_init(&file);
2568 _vox_file_writeable* fp = &file;
2571 _vox_file_write_uint32(fp, CHUNK_ID_VOX_);
2572 _vox_file_write_uint32(fp, 150);
2575 _vox_file_write_uint32(fp, CHUNK_ID_MAIN);
2576 _vox_file_write_uint32(fp, 0);
2577 _vox_file_write_uint32(fp, 0);
2580 const uint32_t offset_post_main_chunk = _vox_file_get_offset(fp);
2583 for (uint32_t i = 0; i < pScene->num_models; i++)
2586 assert(model->size_x <= 126 && model->size_y <= 126 && model->size_z <= 126);
2588 uint32_t num_voxels_in_grid = model->size_x * model->size_y * model->size_z;
2589 uint32_t num_solid_voxels = 0;
2590 for (uint32_t voxel_index = 0; voxel_index < num_voxels_in_grid; voxel_index++)
2591 if (model->voxel_data[voxel_index] != 0)
2593 uint32_t chunk_size_xyzi =
sizeof(uint32_t) + 4 * num_solid_voxels;
2596 _vox_file_write_uint32(fp, CHUNK_ID_SIZE);
2597 _vox_file_write_uint32(fp, 12);
2598 _vox_file_write_uint32(fp, 0);
2601 _vox_file_write_uint32(fp, model->size_x);
2602 _vox_file_write_uint32(fp, model->size_y);
2603 _vox_file_write_uint32(fp, model->size_z);
2606 _vox_file_write_uint32(fp, CHUNK_ID_XYZI);
2607 _vox_file_write_uint32(fp, chunk_size_xyzi);
2608 _vox_file_write_uint32(fp, 0);
2611 _vox_file_write_uint32(fp, num_solid_voxels);
2612 uint32_t voxel_index = 0;
2613 for (uint32_t z = 0; z < model->size_z; z++)
2615 for (uint32_t y = 0; y < model->size_y; y++)
2617 for (uint32_t x = 0; x < model->size_x; x++, voxel_index++)
2619 uint8_t color_index = model->voxel_data[voxel_index];
2620 if (color_index != 0)
2622 _vox_file_write_uint8(fp, (uint8_t)x);
2623 _vox_file_write_uint8(fp, (uint8_t)y);
2624 _vox_file_write_uint8(fp, (uint8_t)z);
2625 _vox_file_write_uint8(fp, color_index);
2633 assert(pScene->num_groups);
2634 uint32_t first_group_transform_node_id = 0;
2635 uint32_t first_group_node_id = first_group_transform_node_id + pScene->num_groups;
2636 uint32_t first_shape_node_id = first_group_node_id + pScene->num_groups;
2637 uint32_t first_instance_transform_node_id = first_shape_node_id + pScene->num_models;
2640 for (uint32_t group_index = 0; group_index < pScene->num_groups; group_index++)
2643 _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);
2646 for (uint32_t group_index = 0; group_index < pScene->num_groups; group_index++)
2650 uint32_t num_child_nodes = 0;
2651 for (uint32_t child_group_index = 0; child_group_index < pScene->num_groups; child_group_index++)
2652 if (pScene->groups[child_group_index].parent_group_index == group_index)
2654 for (uint32_t child_instance_index = 0; child_instance_index < pScene->num_instances; child_instance_index++)
2655 if (pScene->instances[child_instance_index].group_index == group_index)
2659 const char* hidden_string = pScene->groups[group_index].hidden ?
"1" : NULL;
2660 uint32_t group_dict_keyvalue_count = (hidden_string ? 1 : 0);
2663 uint32_t chunk_size_ngrp =
2666 _vox_dict_key_value_size(
"_hidden", hidden_string) +
2668 sizeof(uint32_t) * num_child_nodes;
2671 _vox_file_write_uint32(fp, CHUNK_ID_nGRP);
2672 _vox_file_write_uint32(fp, chunk_size_ngrp);
2673 _vox_file_write_uint32(fp, 0);
2675 _vox_file_write_uint32(fp, first_group_node_id + group_index);
2676 _vox_file_write_uint32(fp, group_dict_keyvalue_count);
2677 _vox_file_write_dict_key_value(fp,
"_hidden", hidden_string);
2678 _vox_file_write_uint32(fp, num_child_nodes);
2680 for (uint32_t child_group_index = 0; child_group_index < pScene->num_groups; child_group_index++)
2681 if (pScene->groups[child_group_index].parent_group_index == group_index)
2682 _vox_file_write_uint32(fp, first_group_transform_node_id + child_group_index);
2684 for (uint32_t child_instance_index = 0; child_instance_index < pScene->num_instances; child_instance_index++)
2685 if (pScene->instances[child_instance_index].group_index == group_index)
2686 _vox_file_write_uint32(fp, first_instance_transform_node_id + child_instance_index);
2690 for (uint32_t i = 0; i < pScene->num_models; i++)
2693 uint32_t chunk_size_nshp =
2700 _vox_file_write_uint32(fp, CHUNK_ID_nSHP);
2701 _vox_file_write_uint32(fp, chunk_size_nshp);
2702 _vox_file_write_uint32(fp, 0);
2704 _vox_file_write_uint32(fp, first_shape_node_id + i);
2705 _vox_file_write_uint32(fp, 0);
2706 _vox_file_write_uint32(fp, 1);
2707 _vox_file_write_uint32(fp, i);
2708 _vox_file_write_uint32(fp, 0);
2711 for (uint32_t i = 0; i < pScene->num_instances; i++)
2714 uint32_t node_id = first_instance_transform_node_id + i;
2715 uint32_t child_node_id = first_shape_node_id + instance->model_index;
2716 _vox_file_write_chunk_nTRN(fp, node_id, child_node_id, instance->name, instance->hidden, &instance->transform, instance->layer_index);
2723 for (uint32_t i = 0; i < 256; i++)
2724 rotated_palette.color[i] = pScene->palette.color[(i + 1) & 255];
2727 _vox_file_write_uint32(fp, CHUNK_ID_RGBA);
2729 _vox_file_write_uint32(fp, 0);
2735 for (uint32_t i = 0; i < pScene->num_layers; i++)
2737 const char* layer_name_string = pScene->layers[i].name;
2738 const char* hidden_string = pScene->layers[i].hidden ?
"1" : NULL;
2739 uint32_t layer_chunk_size =
2742 _vox_dict_key_value_size(
"_name", layer_name_string) +
2743 _vox_dict_key_value_size(
"_hidden", hidden_string) +
2745 uint32_t layer_dict_keyvalue_count = (layer_name_string ? 1 : 0) + (hidden_string ? 1 : 0);
2747 _vox_file_write_uint32(fp, CHUNK_ID_LAYR);
2748 _vox_file_write_uint32(fp, layer_chunk_size);
2749 _vox_file_write_uint32(fp, 0);
2751 _vox_file_write_uint32(fp, i);
2752 _vox_file_write_uint32(fp, layer_dict_keyvalue_count);
2753 _vox_file_write_dict_key_value(fp,
"_name", layer_name_string);
2754 _vox_file_write_dict_key_value(fp,
"_hidden", hidden_string);
2755 _vox_file_write_uint32(fp, UINT32_MAX);
2759 *pBuffer_size = (uint32_t)fp->data.count;
2760 uint8_t* buffer_data = _vox_file_get_data(fp);
2762 fp->data.data = NULL;
2766 uint32_t* main_chunk_child_size = (uint32_t*)&buffer_data[offset_post_main_chunk -
sizeof(uint32_t)];
2767 *main_chunk_child_size = *pBuffer_size - offset_post_main_chunk;
2773void* ogt_vox_malloc(
size_t uiSize)
2775 return _vox_malloc(uiSize);
2778void ogt_vox_free(
void* pMem)
2784static void compute_scene_bounding_box_x(
const ogt_vox_scene* pScene, int32_t& out_min_x, int32_t& out_max_x)
2786 if (pScene->num_instances && pScene->num_models)
2790 int32_t scene_min_x = 0x7ffffff;
2791 int32_t scene_max_x = -0x7ffffff;
2792 for (uint32_t instance_index = 0; instance_index < pScene->num_instances; instance_index++)
2797 uint32_t parent_group_index = instance->group_index;
2798 while (parent_group_index != k_invalid_group_index)
2800 const ogt_vox_group* group = &pScene->groups[parent_group_index];
2801 instance_transform = _vox_transform_multiply(instance_transform, group->transform);
2802 parent_group_index = group->parent_group_index;
2805 const ogt_vox_model* model = pScene->models[instance->model_index];
2810 int32_t max_dim = instance_transform.m00 != 0.0f ? model->size_x : instance_transform.m10 != 0.0f ? model->size_y :
2811 instance_transform.m20 != 0.0f ? model->size_z :
2813 int32_t half_dim = max_dim / 2;
2814 int32_t min_x = (int32_t)instance_transform.m30 - half_dim;
2815 int32_t max_x = (int32_t)instance_transform.m30 + half_dim;
2816 scene_min_x = min_x < scene_min_x ? min_x : scene_min_x;
2817 scene_max_x = max_x > scene_max_x ? max_x : scene_max_x;
2820 out_min_x = scene_min_x;
2821 out_max_x = scene_max_x;
2833static void compute_scene_used_color_index_mask(
bool* pUsed_mask,
const ogt_vox_scene* pScene)
2835 memset(pUsed_mask, 0, 256);
2836 for (uint32_t model_index = 0; model_index < pScene->num_models; model_index++)
2839 uint32_t voxel_count = model->size_x * model->size_y * model->size_z;
2840 for (uint32_t voxel_index = 0; voxel_index < voxel_count; voxel_index++)
2842 uint8_t color_index = model->voxel_data[voxel_index];
2843 pUsed_mask[color_index] =
true;
2849static uint32_t find_exact_color_in_palette(
const ogt_vox_rgba* pPalette, uint32_t palette_count,
const ogt_vox_rgba color_to_find)
2851 for (uint32_t color_index = 1; color_index < palette_count; color_index++)
2853 const ogt_vox_rgba color_to_match = pPalette[color_index];
2855 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)
2863static uint32_t find_closest_color_in_palette(
const ogt_vox_rgba* pPalette, uint32_t palette_count,
const ogt_vox_rgba color_to_find)
2866 int32_t best_score = INT32_MAX;
2867 uint32_t best_index = 1;
2870 for (uint32_t color_index = 1; color_index < palette_count; color_index++)
2872 int32_t r_diff = (int32_t)color_to_find.r - (int32_t)pPalette[color_index].r;
2873 int32_t g_diff = (int32_t)color_to_find.g - (int32_t)pPalette[color_index].g;
2874 int32_t b_diff = (int32_t)color_to_find.b - (int32_t)pPalette[color_index].b;
2879 int32_t score = (r_diff * r_diff) + (g_diff * g_diff) + (b_diff * b_diff);
2880 if (score < best_score)
2883 best_index = color_index;
2886 assert(best_score < UINT32_MAX);
2890static 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)
2893 bool scene_used_mask[256];
2894 compute_scene_used_color_index_mask(scene_used_mask, pScene);
2897 pScene_to_master_map[0] = 0;
2898 for (uint32_t i = 1; i < 256; i++)
2899 pScene_to_master_map[i] = UINT32_MAX;
2902 for (uint32_t color_index = 1; color_index < 256; color_index++)
2904 if (scene_used_mask[color_index])
2906 const ogt_vox_rgba color = pScene->palette.color[color_index];
2908 uint32_t master_index = find_exact_color_in_palette(pMaster_palette, ref_master_palette_count, color);
2909 if (master_index == UINT32_MAX)
2911 if (ref_master_palette_count < 256)
2914 pMaster_palette[ref_master_palette_count] = color;
2915 master_index = ref_master_palette_count++;
2930 master_index = find_closest_color_in_palette(pMaster_palette, ref_master_palette_count, color);
2934 pScene_to_master_map[color_index] = master_index;
2941 assert(required_color_count <= 255);
2945 uint32_t master_palette_count = 1;
2946 memset(&master_palette, 0,
sizeof(master_palette));
2947 for (uint32_t required_index = 0; required_index < required_color_count; required_index++)
2948 master_palette[master_palette_count++] = pRequired_colors[required_index];
2951 uint32_t max_layers = 1;
2952 uint32_t max_models = 0;
2953 uint32_t max_instances = 0;
2954 uint32_t max_groups = 1;
2955 for (uint32_t scene_index = 0; scene_index < scene_count; scene_index++)
2957 if (!pScenes[scene_index])
2959 max_instances += pScenes[scene_index]->num_instances;
2960 max_models += pScenes[scene_index]->num_models;
2961 max_groups += pScenes[scene_index]->num_groups;
2969 uint32_t num_instances = 0;
2970 uint32_t num_models = 0;
2971 uint32_t num_layers = 0;
2972 uint32_t num_groups = 0;
2975 layers[num_layers].hidden =
false;
2976 layers[num_layers].name =
"merged";
2982 uint32_t global_root_group_index = num_groups;
2984 assert(global_root_group_index == 0);
2986 root_group.hidden =
false;
2987 root_group.layer_index = 0;
2988 root_group.parent_group_index = k_invalid_group_index;
2989 root_group.transform = _vox_transform_identity();
2990 groups[num_groups++] = root_group;
2994 size_t string_data_size = 0;
2995 int32_t offset_x = 0;
2996 for (uint32_t scene_index = 0; scene_index < scene_count; scene_index++)
3003 uint32_t scene_color_index_to_master_map[256];
3004 update_master_palette_from_scene(master_palette, master_palette_count, scene, scene_color_index_to_master_map);
3007 uint32_t base_model_index = num_models;
3008 uint32_t base_group_index = num_groups;
3011 for (uint32_t model_index = 0; model_index < scene->num_models; model_index++)
3014 uint32_t voxel_count = model->size_x * model->size_y * model->size_z;
3017 uint8_t* override_voxel_data = (uint8_t*)&override_model[1];
3020 for (uint32_t voxel_index = 0; voxel_index < voxel_count; voxel_index++)
3022 uint8_t old_color_index = model->voxel_data[voxel_index];
3023 uint32_t new_color_index = scene_color_index_to_master_map[old_color_index];
3024 assert(new_color_index < 256);
3025 override_voxel_data[voxel_index] = (uint8_t)new_color_index;
3028 *override_model = *model;
3029 override_model->voxel_data = override_voxel_data;
3030 override_model->voxel_hash = _vox_hash(override_voxel_data, voxel_count);
3032 models[num_models++] = override_model;
3038 int32_t scene_min_x, scene_max_x;
3039 compute_scene_bounding_box_x(scene, scene_min_x, scene_max_x);
3040 float scene_offset_x = (float)(offset_x - scene_min_x);
3043 assert(scene->groups[0].parent_group_index == k_invalid_group_index);
3045 for (uint32_t group_index = 1; group_index < scene->num_groups; group_index++)
3047 const ogt_vox_group* src_group = &scene->groups[group_index];
3048 assert(src_group->parent_group_index != k_invalid_group_index);
3050 assert(dst_group.parent_group_index < scene->num_groups);
3051 dst_group.layer_index = 0;
3052 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 (dst_group.parent_group_index == global_root_group_index)
3055 dst_group.transform.m30 += scene_offset_x;
3056 groups[num_groups++] = dst_group;
3060 for (uint32_t instance_index = 0; instance_index < scene->num_instances; instance_index++)
3063 assert(src_instance->group_index < scene->num_groups);
3065 *dst_instance = *src_instance;
3066 dst_instance->layer_index = 0;
3067 dst_instance->group_index = (dst_instance->group_index == 0) ? global_root_group_index : base_group_index + (dst_instance->group_index - 1);
3068 dst_instance->model_index += base_model_index;
3069 if (dst_instance->name)
3070 string_data_size += _vox_strlen(dst_instance->name) + 1;
3072 if (dst_instance->group_index == global_root_group_index)
3073 dst_instance->transform.m30 += scene_offset_x;
3076 offset_x += (scene_max_x - scene_min_x);
3081 const ogt_vox_rgba k_invalid_color = {255, 0, 255, 255};
3082 for (uint32_t color_index = master_palette_count; color_index < 256; color_index++)
3083 master_palette[color_index] = k_invalid_color;
3086 size_t scene_size =
sizeof(
ogt_vox_scene) + string_data_size;
3090 char* scene_string_data = (
char*)&merged_scene[1];
3091 for (uint32_t instance_index = 0; instance_index < num_instances; instance_index++)
3093 if (instances[instance_index].name)
3095 size_t string_len = _vox_strlen(instances[instance_index].name) + 1;
3096 memcpy(scene_string_data, instances[instance_index].name, string_len);
3097 instances[instance_index].name = scene_string_data;
3098 scene_string_data += string_len;
3102 assert(num_groups <= max_groups);
3105 merged_scene->instances = instances;
3106 merged_scene->num_instances = max_instances;
3108 merged_scene->num_models = max_models;
3109 merged_scene->layers = layers;
3110 merged_scene->num_layers = max_layers;
3111 merged_scene->groups = groups;
3112 merged_scene->num_groups = num_groups;
3114 for (uint32_t color_index = 0; color_index < 256; color_index++)
3115 merged_scene->palette.color[color_index] = master_palette[color_index];
3117 return merged_scene;