123 # if _MSC_VER == 1400
125 typedef unsigned char uint8_t;
126 typedef signed int int32_t;
127 typedef 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?
151 static 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;
226 typedef void* (*ogt_vox_alloc_func)(
size_t size);
229 typedef void (*ogt_vox_free_func)(
void* ptr);
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);
237 static const uint32_t k_read_scene_flags_groups = 1 << 0;
241 const ogt_vox_scene* ogt_vox_read_scene(
const uint8_t* pBuffer, uint32_t buffer_size);
244 const ogt_vox_scene* ogt_vox_read_scene_with_flags(
const uint8_t* pBuffer, uint32_t buffer_size, uint32_t read_flags);
250 uint8_t* ogt_vox_write_scene(
const ogt_vox_scene* pScene, uint32_t* pBuffer_size);
256 #endif // OGT_VOX_H__
264 #ifdef OGT_VOX_IMPLEMENTATION
271 # define MAKE_VOX_CHUNK_ID(c0, c1, c2, c3) ((c0 << 0) | (c1 << 8) | (c2 << 16) | (c3 << 24))
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');
288 static const uint8_t k_default_vox_palette[256 * 4] = {
1316 static inline uint32_t _vox_max(uint32_t a, uint32_t b)
1318 return (a > b) ? a : b;
1320 static 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__)
1347 static inline vec3 vec3_make(
float x,
float y,
float z)
1355 static inline vec3 vec3_negate(
const vec3& v)
1367 const uint8_t* buffer;
1368 const uint32_t buffer_size;
1372 static 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;
1380 static void _vox_file_seek_forwards(_vox_file* pFp, uint32_t offset)
1382 pFp->offset += offset;
1385 static bool _vox_file_eof(
const _vox_file* pFp)
1387 return pFp->offset >= pFp->buffer_size;
1390 static const void* _vox_file_data_pointer(
const _vox_file* pFp)
1392 return &pFp->buffer[pFp->offset];
1396 static 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);
1405 static void* _ogt_priv_alloc_default(
size_t uiSize)
1407 return malloc(uiSize);
1409 static void _ogt_priv_free_default(
void* pPtr)
1413 static ogt_vox_alloc_func g_alloc_func = _ogt_priv_alloc_default;
1414 static ogt_vox_free_func g_free_func = _ogt_priv_free_default;
1417 void 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;
1434 static void* _vox_malloc(
size_t uiSize)
1436 return uiSize ? g_alloc_func(uiSize) : NULL;
1439 static void* _vox_calloc(
size_t uiSize)
1441 void* pMem = _vox_malloc(uiSize);
1443 memset(pMem, 0, uiSize);
1447 static void _vox_free(
void* pOld_ptr)
1450 g_free_func(pOld_ptr);
1453 static 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);
1493 void reserve(
size_t uiNew_capacity)
1495 data = (T*)_vox_realloc(data, capacity *
sizeof(T), uiNew_capacity *
sizeof(T));
1496 capacity = uiNew_capacity;
1498 void grow_to_fit_index(
size_t uiIndex)
1500 if (uiIndex >= count)
1501 resize(uiIndex + 1);
1503 void resize(
size_t uiNew_count)
1505 if (uiNew_count > capacity)
1506 reserve(uiNew_count);
1507 count = uiNew_count;
1509 void push_back(
const T& new_element)
1511 if (count == capacity)
1513 size_t new_capacity = capacity ? (capacity * 3) >> 1 : 2;
1514 reserve(new_capacity);
1515 assert(capacity > count);
1517 data[count++] = new_element;
1519 void push_back_many(
const T* pNew_elements,
size_t uiNum_elements)
1521 if (count + uiNum_elements > capacity)
1523 size_t new_capacity = capacity + uiNum_elements;
1524 new_capacity = new_capacity ? (new_capacity * 3) >> 1 : 2;
1525 reserve(new_capacity);
1526 assert(capacity >= (count + uiNum_elements));
1528 for (
size_t i = 0; i < uiNum_elements; i++)
1529 data[count + i] = pNew_elements[i];
1530 count += uiNum_elements;
1536 T& operator[](
size_t uiIndex)
1538 assert(uiIndex < count);
1539 return data[uiIndex];
1541 const T& operator[](
size_t uiIndex)
const
1543 assert(uiIndex < count);
1544 return data[uiIndex];
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);
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
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];
1605 uint32_t buffer_mem_used;
1608 static bool _vox_file_read_dict(_vox_dictionary* pDict, _vox_file* pFp)
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);
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++)
1619 uint32_t key_string_size = 0;
1620 _vox_file_read(pFp, &key_string_size,
sizeof(uint32_t));
1622 if (pDict->buffer_mem_used + key_string_size > k_vox_max_dict_buffer_size)
1624 char* key = &pDict->buffer[pDict->buffer_mem_used];
1625 pDict->buffer_mem_used += key_string_size + 1;
1626 _vox_file_read(pFp, key, key_string_size);
1627 key[key_string_size] = 0;
1628 assert(_vox_strlen(key) == key_string_size);
1631 uint32_t value_string_size = 0;
1632 _vox_file_read(pFp, &value_string_size,
sizeof(uint32_t));
1634 if (pDict->buffer_mem_used + value_string_size > k_vox_max_dict_buffer_size)
1636 char* value = &pDict->buffer[pDict->buffer_mem_used];
1637 pDict->buffer_mem_used += value_string_size + 1;
1638 _vox_file_read(pFp, value, value_string_size);
1639 value[value_string_size] = 0;
1640 assert(_vox_strlen(value) == value_string_size);
1642 pDict->keys[pDict->num_key_value_pairs] = key;
1643 pDict->values[pDict->num_key_value_pairs] = value;
1644 pDict->num_key_value_pairs++;
1651 static const char* _vox_dict_get_value_as_string(
const _vox_dictionary* pDict,
const char* szKey_to_find,
const char* szDefault_value = NULL)
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;
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)
1668 static const uint32_t k_row2_index[] = {UINT32_MAX, UINT32_MAX, UINT32_MAX, 2, UINT32_MAX, 1, 0, UINT32_MAX};
1671 static ogt_vox_transform _vox_make_transform_from_dict_strings(
const char* szRotation_string,
const char* szTranslation_string)
1675 if (szRotation_string != NULL)
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)];
1686 assert(row2_vec_index != UINT32_MAX);
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);
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;
1715 if (szTranslation_string != NULL)
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;
1728 enum _vox_scene_node_type
1730 k_nodetype_invalid = 0,
1731 k_nodetype_group = 1,
1732 k_nodetype_transform = 2,
1733 k_nodetype_shape = 3,
1736 struct _vox_scene_node_
1738 _vox_scene_node_type node_type;
1746 uint32_t child_node_id;
1753 uint32_t first_child_node_id_index;
1754 uint32_t num_child_nodes;
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)
1769 const _vox_scene_node_* node = &nodes[node_index];
1771 switch (node->node_type)
1773 case k_nodetype_transform:
1775 ogt_vox_transform new_transform = (bGenerate_groups) ? node->u.transform.transform
1776 : _vox_transform_multiply(node->u.transform.transform, 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;
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);
1782 case k_nodetype_group:
1785 uint32_t next_group_index = 0;
1786 if (bGenerate_groups)
1788 next_group_index = (uint32_t)ref_groups.size();
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);
1797 bTransform_last_hidden =
false;
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++)
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);
1806 case k_nodetype_shape:
1808 assert(node->u.shape.model_id < model_ptrs.size());
1809 if (node->u.shape.model_id < model_ptrs.size() &&
1810 model_ptrs[node->u.shape.model_id] != NULL)
1812 assert(bGenerate_groups || group_index == 0);
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;
1821 new_instance.name = 0;
1822 if (szTransform_last_name && szTransform_last_name[0])
1824 new_instance.name = (
const char*)(ref_string_data.size());
1825 size_t name_size = _vox_strlen(szTransform_last_name) + 1;
1826 ref_string_data.push_back_many(szTransform_last_name, name_size);
1829 ref_instances.push_back(new_instance);
1841 static int _vox_ordered_compare_instance(
const void* p_lhs,
const void* p_rhs)
1845 return lhs->model_index < rhs->model_index ? -1 : lhs->model_index > rhs->model_index ? 1
1854 if (lhs->voxel_hash != rhs->voxel_hash)
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)
1863 return memcmp(lhs->voxel_data, rhs->voxel_data, num_voxels_lhs) == 0 ? true :
false;
1866 const ogt_vox_scene* ogt_vox_read_scene_with_flags(
const uint8_t* pBuffer, uint32_t buffer_size, uint32_t read_flags)
1868 _vox_file file = {pBuffer, buffer_size, 0};
1869 _vox_file* fp = &file;
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;
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;
1888 model_ptrs.reserve(64);
1889 instances.reserve(256);
1890 child_ids.reserve(256);
1894 string_data.reserve(256);
1899 string_data.push_back(
'X');
1900 child_ids.push_back(-1);
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)
1914 while (!_vox_file_eof(fp))
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));
1929 assert(chunk_size == 0);
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));
1942 assert(chunk_child_size == 0 && size_x && size_y && size_z);
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)
1948 uint32_t voxel_count = size_x * size_y * size_z;
1952 uint8_t* voxel_data = (uint8_t*)&model[1];
1955 model_ptrs.push_back(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;
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;
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++)
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;
1979 _vox_file_seek_forwards(fp, num_voxels_in_chunk * 4);
1981 model->voxel_hash = _vox_hash(voxel_data, size_x * size_y * size_z);
1985 model_ptrs.push_back(NULL);
1991 assert(chunk_size ==
sizeof(palette));
1992 _vox_file_read(fp, &palette,
sizeof(palette));
1998 _vox_file_read(fp, &node_id,
sizeof(node_id));
2004 bool hidden =
false;
2007 _vox_file_read_dict(&dict, fp);
2008 const char* name_string = _vox_dict_get_value_as_string(&dict,
"_name");
2010 _vox_strcpy_static(node_name, name_string);
2012 const char* hidden_string = _vox_dict_get_value_as_string(&dict,
"_hidden",
"0");
2014 hidden = (hidden_string[0] ==
'1' ? true :
false);
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);
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);
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;
2048 _vox_strcpy_static(transform_node->u.transform.name, node_name);
2055 _vox_file_read(fp, &node_id,
sizeof(node_id));
2058 _vox_file_read_dict(&dict, fp);
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;
2068 uint32_t num_child_nodes = 0;
2069 _vox_file_read(fp, &num_child_nodes,
sizeof(num_child_nodes));
2072 if (num_child_nodes)
2074 size_t prior_size = child_ids.size();
2075 assert(prior_size > 0);
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;
2086 _vox_file_read(fp, &node_id,
sizeof(node_id));
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;
2095 _vox_file_read_dict(&dict, fp);
2097 uint32_t num_models = 0;
2098 _vox_file_read(fp, &num_models,
sizeof(num_models));
2099 assert(num_models == 1);
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());
2106 _vox_file_read_dict(&dict, fp);
2111 assert(chunk_size == 256);
2112 _vox_file_read(fp, index_map, 256);
2113 found_index_map_chunk =
true;
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);
2125 layers.grow_to_fit_index(layer_id);
2126 layers[layer_id].name = NULL;
2127 layers[layer_id].hidden =
false;
2131 const char* name_string = _vox_dict_get_value_as_string(&dict,
"_name", NULL);
2134 layers[layer_id].name = (
const char*)(string_data.size());
2135 size_t name_size = _vox_strlen(name_string) + 1;
2136 string_data.push_back_many(name_string, name_size);
2139 const char* hidden_string = _vox_dict_get_value_as_string(&dict,
"_hidden",
"0");
2141 layers[layer_id].hidden = (hidden_string[0] ==
'1' ? true :
false);
2150 _vox_file_seek_forwards(fp, chunk_size);
2161 bool generate_groups = read_flags & k_read_scene_flags_groups ? true :
false;
2163 if (!generate_groups)
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);
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);
2174 else if (model_ptrs.size() == 1)
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);
2188 if (layers.size() == 0)
2191 for (uint32_t i = 0; i < instances.size(); i++)
2192 instances[i].layer_index = 0;
2195 new_layer.hidden =
false;
2196 new_layer.name = NULL;
2197 layers.push_back(new_layer);
2211 if (found_index_map_chunk)
2215 uint8_t index_map_inverse[256];
2216 for (uint32_t i = 0; i < 256; i++)
2218 index_map_inverse[index_map[i]] = (uint8_t)i;
2223 for (uint32_t i = 0; i < 256; i++)
2225 uint32_t remapped_index = (index_map[i] + 255) & 0xFF;
2226 palette.color[i] = old_palette.color[remapped_index];
2230 for (uint32_t i = 0; i < model_ptrs.size(); i++)
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]];
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;
2255 for (uint32_t i = 0; i < model_ptrs.size(); i++)
2259 for (uint32_t j = i + 1; j < model_ptrs.size(); j++)
2261 if (!model_ptrs[j] || !_vox_models_are_equal(model_ptrs[i], model_ptrs[j]))
2264 _vox_free(model_ptrs[j]);
2265 model_ptrs[j] = NULL;
2267 for (uint32_t k = 0; k < instances.size(); k++)
2268 if (instances[k].model_index == j)
2269 instances[k].model_index = i;
2280 bool found_empty_model =
false;
2281 for (uint32_t i = 0; i < model_ptrs.size() && !found_empty_model; i++)
2283 if (model_ptrs[i] == NULL)
2284 found_empty_model =
true;
2286 if (found_empty_model)
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++)
2293 if (model_ptrs[i] != NULL)
2295 model_ptrs[num_output_models] = model_ptrs[i];
2296 model_remap[i] = num_output_models;
2297 num_output_models++;
2301 model_remap[i] = UINT32_MAX;
2304 model_ptrs.resize(num_output_models);
2307 for (uint32_t i = 0; i < instances.size(); i++)
2309 uint32_t new_model_index = model_remap[instances[i].model_index];
2310 assert(new_model_index != UINT32_MAX);
2311 instances[i].model_index = new_model_index;
2315 _vox_free(model_remap);
2321 size_t scene_size =
sizeof(
ogt_vox_scene) + string_data.size();
2325 char* scene_string_data = (
char*)&scene[1];
2326 memcpy(scene_string_data, &string_data[0],
sizeof(
char) * string_data.size());
2329 size_t num_scene_instances = instances.size();
2331 if (num_scene_instances)
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);
2336 scene->instances = scene_instances;
2337 scene->num_instances = (uint32_t)instances.size();
2340 size_t num_scene_models = model_ptrs.size();
2342 if (num_scene_models)
2343 memcpy(scene_models, &model_ptrs[0],
sizeof(
ogt_vox_model*) * num_scene_models);
2345 scene->num_models = (uint32_t)num_scene_models;
2348 size_t num_scene_layers = layers.size();
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;
2355 size_t num_scene_groups = groups.size();
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;
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;
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;
2373 scene->palette = palette;
2378 const ogt_vox_scene* ogt_vox_read_scene(
const uint8_t* pBuffer, uint32_t buffer_size)
2380 return ogt_vox_read_scene_with_flags(pBuffer, buffer_size, 0);
2387 for (uint32_t i = 0; i < scene->num_models; i++)
2388 _vox_free((
void*)scene->models[i]);
2392 _vox_free(scene->models);
2393 scene->models = NULL;
2396 if (scene->instances)
2399 scene->instances = NULL;
2405 scene->layers = NULL;
2411 scene->groups = NULL;
2419 static bool _vox_get_vec3_rotation_bits(
const vec3& vec, uint32_t& out_index)
2421 const float* f = &vec.x;
2423 bool is_negative =
false;
2424 for (uint32_t i = 0; i < 3; i++)
2426 if (f[i] == 1.0f || f[i] == -1.0f)
2429 is_negative = f[i] < 0.0f ? true :
false;
2433 assert(f[i] == 0.0f);
2436 assert(out_index != 3);
2440 static uint8_t _vox_make_packed_rotation_from_transform(
const ogt_vox_transform* pTransform)
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);
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));
2454 struct _vox_file_writeable
2456 _vox_array<uint8_t> data;
2459 static void _vox_file_writeable_init(_vox_file_writeable* pFp)
2461 pFp->data.reserve(1024);
2463 static void _vox_file_write(_vox_file_writeable* pFp,
const void* pData, uint32_t data_size)
2465 pFp->data.push_back_many((
const uint8_t*)pData, data_size);
2467 static void _vox_file_write_uint32(_vox_file_writeable* pFp, uint32_t data)
2469 pFp->data.push_back_many((
const uint8_t*)&data,
sizeof(uint32_t));
2471 static void _vox_file_write_uint8(_vox_file_writeable* pFp, uint8_t data)
2473 pFp->data.push_back_many((
const uint8_t*)&data,
sizeof(uint8_t));
2475 static uint32_t _vox_file_get_offset(
const _vox_file_writeable* pFp)
2477 return (uint32_t)pFp->data.count;
2479 static uint8_t* _vox_file_get_data(_vox_file_writeable* pFp)
2481 return &pFp->data[0];
2483 static void _vox_file_write_dict_key_value(_vox_file_writeable* pFp,
const char* szKey,
const char* value)
2485 if (szKey == NULL || value == NULL)
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);
2495 static uint32_t _vox_dict_key_value_size(
const char* szKey,
const char* value)
2497 if (szKey == NULL || value == NULL)
2499 size_t size =
sizeof(uint32_t) + _vox_strlen(szKey) +
sizeof(uint32_t) + _vox_strlen(value);
2500 return (uint32_t)size;
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)
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)
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;
2522 uint32_t node_dict_size =
2524 _vox_dict_key_value_size(
"_name", szName) +
2525 _vox_dict_key_value_size(
"_hidden", hidden_string);
2527 uint32_t frame_dict_size =
2529 _vox_dict_key_value_size(
"_t", t_string) +
2530 _vox_dict_key_value_size(
"_r", r_string);
2532 uint32_t chunk_size_ntrn =
2535 4 *
sizeof(uint32_t) +
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);
2544 _vox_file_write_uint32(pFp, node_id);
2547 uint32_t node_dict_keyvalue_count = (szName ? 1 : 0) + (hidden_string ? 1 : 0);
2548 _vox_file_write_uint32(pFp, node_dict_keyvalue_count);
2549 _vox_file_write_dict_key_value(pFp,
"_name", szName);
2550 _vox_file_write_dict_key_value(pFp,
"_hidden", hidden_string);
2553 _vox_file_write_uint32(pFp, child_node_id);
2554 _vox_file_write_uint32(pFp, UINT32_MAX);
2555 _vox_file_write_uint32(pFp, layer_id);
2556 _vox_file_write_uint32(pFp, 1);
2559 _vox_file_write_uint32(pFp, (r_string ? 1 : 0) + (t_string ? 1 : 0));
2560 _vox_file_write_dict_key_value(pFp,
"_r", r_string);
2561 _vox_file_write_dict_key_value(pFp,
"_t", t_string);
2565 uint8_t* ogt_vox_write_scene(
const ogt_vox_scene* pScene, uint32_t* pBuffer_size)
2567 _vox_file_writeable file;
2568 _vox_file_writeable_init(&file);
2569 _vox_file_writeable* fp = &file;
2572 _vox_file_write_uint32(fp, CHUNK_ID_VOX_);
2573 _vox_file_write_uint32(fp, 150);
2576 _vox_file_write_uint32(fp, CHUNK_ID_MAIN);
2577 _vox_file_write_uint32(fp, 0);
2578 _vox_file_write_uint32(fp, 0);
2581 const uint32_t offset_post_main_chunk = _vox_file_get_offset(fp);
2584 for (uint32_t i = 0; i < pScene->num_models; i++)
2587 assert(model->size_x <= 126 && model->size_y <= 126 && model->size_z <= 126);
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)
2594 uint32_t chunk_size_xyzi =
sizeof(uint32_t) + 4 * num_solid_voxels;
2597 _vox_file_write_uint32(fp, CHUNK_ID_SIZE);
2598 _vox_file_write_uint32(fp, 12);
2599 _vox_file_write_uint32(fp, 0);
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);
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);
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++)
2616 for (uint32_t y = 0; y < model->size_y; y++)
2618 for (uint32_t x = 0; x < model->size_x; x++, voxel_index++)
2620 uint8_t color_index = model->voxel_data[voxel_index];
2621 if (color_index != 0)
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);
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;
2641 for (uint32_t group_index = 0; group_index < pScene->num_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);
2647 for (uint32_t group_index = 0; group_index < pScene->num_groups; group_index++)
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)
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)
2660 const char* hidden_string = pScene->groups[group_index].hidden ?
"1" : NULL;
2661 uint32_t group_dict_keyvalue_count = (hidden_string ? 1 : 0);
2664 uint32_t chunk_size_ngrp =
2667 _vox_dict_key_value_size(
"_hidden", hidden_string) +
2669 sizeof(uint32_t) * num_child_nodes;
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);
2676 _vox_file_write_uint32(fp, first_group_node_id + group_index);
2677 _vox_file_write_uint32(fp, group_dict_keyvalue_count);
2678 _vox_file_write_dict_key_value(fp,
"_hidden", hidden_string);
2679 _vox_file_write_uint32(fp, num_child_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);
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);
2691 for (uint32_t i = 0; i < pScene->num_models; i++)
2694 uint32_t chunk_size_nshp =
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);
2705 _vox_file_write_uint32(fp, first_shape_node_id + i);
2706 _vox_file_write_uint32(fp, 0);
2707 _vox_file_write_uint32(fp, 1);
2708 _vox_file_write_uint32(fp, i);
2709 _vox_file_write_uint32(fp, 0);
2712 for (uint32_t i = 0; i < pScene->num_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);
2724 for (uint32_t i = 0; i < 256; i++)
2725 rotated_palette.color[i] = pScene->palette.color[(i + 1) & 255];
2728 _vox_file_write_uint32(fp, CHUNK_ID_RGBA);
2730 _vox_file_write_uint32(fp, 0);
2736 for (uint32_t i = 0; i < pScene->num_layers; i++)
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 =
2743 _vox_dict_key_value_size(
"_name", layer_name_string) +
2744 _vox_dict_key_value_size(
"_hidden", hidden_string) +
2746 uint32_t layer_dict_keyvalue_count = (layer_name_string ? 1 : 0) + (hidden_string ? 1 : 0);
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);
2752 _vox_file_write_uint32(fp, i);
2753 _vox_file_write_uint32(fp, layer_dict_keyvalue_count);
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);
2760 *pBuffer_size = (uint32_t)fp->data.count;
2761 uint8_t* buffer_data = _vox_file_get_data(fp);
2763 fp->data.data = NULL;
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;
2774 void* ogt_vox_malloc(
size_t uiSize)
2776 return _vox_malloc(uiSize);
2779 void ogt_vox_free(
void* pMem)
2785 static void compute_scene_bounding_box_x(
const ogt_vox_scene* pScene, int32_t& out_min_x, int32_t& out_max_x)
2787 if (pScene->num_instances && pScene->num_models)
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++)
2798 uint32_t parent_group_index = instance->group_index;
2799 while (parent_group_index != k_invalid_group_index)
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;
2806 const ogt_vox_model* model = pScene->models[instance->model_index];
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
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;
2821 out_min_x = scene_min_x;
2822 out_max_x = scene_max_x;
2834 static void compute_scene_used_color_index_mask(
bool* pUsed_mask,
const ogt_vox_scene* pScene)
2836 memset(pUsed_mask, 0, 256);
2837 for (uint32_t model_index = 0; model_index < pScene->num_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++)
2843 uint8_t color_index = model->voxel_data[voxel_index];
2844 pUsed_mask[color_index] =
true;
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)
2852 for (uint32_t color_index = 1; color_index < palette_count; color_index++)
2854 const ogt_vox_rgba color_to_match = pPalette[color_index];
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)
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)
2867 int32_t best_score = INT32_MAX;
2868 uint32_t best_index = 1;
2871 for (uint32_t color_index = 1; color_index < palette_count; color_index++)
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;
2880 int32_t score = (r_diff * r_diff) + (g_diff * g_diff) + (b_diff * b_diff);
2881 if (score < best_score)
2884 best_index = color_index;
2887 assert(best_score < UINT32_MAX);
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)
2894 bool scene_used_mask[256];
2895 compute_scene_used_color_index_mask(scene_used_mask, pScene);
2898 pScene_to_master_map[0] = 0;
2899 for (uint32_t i = 1; i < 256; i++)
2900 pScene_to_master_map[i] = UINT32_MAX;
2903 for (uint32_t color_index = 1; color_index < 256; color_index++)
2905 if (scene_used_mask[color_index])
2907 const ogt_vox_rgba color = pScene->palette.color[color_index];
2909 uint32_t master_index = find_exact_color_in_palette(pMaster_palette, ref_master_palette_count, color);
2910 if (master_index == UINT32_MAX)
2912 if (ref_master_palette_count < 256)
2915 pMaster_palette[ref_master_palette_count] = color;
2916 master_index = ref_master_palette_count++;
2931 master_index = find_closest_color_in_palette(pMaster_palette, ref_master_palette_count, color);
2935 pScene_to_master_map[color_index] = master_index;
2942 assert(required_color_count <= 255);
2946 uint32_t master_palette_count = 1;
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];
2952 uint32_t max_layers = 1;
2953 uint32_t max_models = 0;
2954 uint32_t max_instances = 0;
2955 uint32_t max_groups = 1;
2956 for (uint32_t scene_index = 0; scene_index < scene_count; scene_index++)
2958 if (!pScenes[scene_index])
2960 max_instances += pScenes[scene_index]->num_instances;
2961 max_models += pScenes[scene_index]->num_models;
2962 max_groups += pScenes[scene_index]->num_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;
2976 layers[num_layers].hidden =
false;
2977 layers[num_layers].name =
"merged";
2983 uint32_t global_root_group_index = num_groups;
2985 assert(global_root_group_index == 0);
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;
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++)
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);
3008 uint32_t base_model_index = num_models;
3009 uint32_t base_group_index = num_groups;
3012 for (uint32_t model_index = 0; model_index < scene->num_models; model_index++)
3015 uint32_t voxel_count = model->size_x * model->size_y * model->size_z;
3018 uint8_t* override_voxel_data = (uint8_t*)&override_model[1];
3021 for (uint32_t voxel_index = 0; voxel_index < voxel_count; voxel_index++)
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;
3029 *override_model = *model;
3030 override_model->voxel_data = override_voxel_data;
3031 override_model->voxel_hash = _vox_hash(override_voxel_data, voxel_count);
3033 models[num_models++] = override_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);
3044 assert(scene->groups[0].parent_group_index == k_invalid_group_index);
3046 for (uint32_t group_index = 1; group_index < scene->num_groups; group_index++)
3048 const ogt_vox_group* src_group = &scene->groups[group_index];
3049 assert(src_group->parent_group_index != k_invalid_group_index);
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);
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;
3061 for (uint32_t instance_index = 0; instance_index < scene->num_instances; instance_index++)
3064 assert(src_instance->group_index < scene->num_groups);
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;
3073 if (dst_instance->group_index == global_root_group_index)
3074 dst_instance->transform.m30 += scene_offset_x;
3077 offset_x += (scene_max_x - scene_min_x);
3082 const ogt_vox_rgba k_invalid_color = {255, 0, 255, 255};
3083 for (uint32_t color_index = master_palette_count; color_index < 256; color_index++)
3084 master_palette[color_index] = k_invalid_color;
3087 size_t scene_size =
sizeof(
ogt_vox_scene) + string_data_size;
3091 char* scene_string_data = (
char*)&merged_scene[1];
3092 for (uint32_t instance_index = 0; instance_index < num_instances; instance_index++)
3094 if (instances[instance_index].name)
3096 size_t string_len = _vox_strlen(instances[instance_index].name) + 1;
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;
3103 assert(num_groups <= max_groups);
3106 merged_scene->instances = instances;
3107 merged_scene->num_instances = max_instances;
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;
3115 for (uint32_t color_index = 0; color_index < 256; color_index++)
3116 merged_scene->palette.color[color_index] = master_palette[color_index];
3118 return merged_scene;
3121 #endif // #ifdef OGT_VOX_IMPLEMENTATION