94 #ifndef CGLTF_H_INCLUDED__
95 #define CGLTF_H_INCLUDED__
136 void* (*alloc_func)(
void* user, cgltf_size
size);
860 const char* gltf_path);
922 #if defined(__INTELLISENSE__) || defined(__JETBRAINS_IDE__)
924 #define CGLTF_IMPLEMENTATION
927 #ifdef CGLTF_IMPLEMENTATION
935 #if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF) || !defined(CGLTF_ATOLL)
940 #define JSMN_PARENT_LINKS
959 JSMN_ERROR_NOMEM = -1,
961 JSMN_ERROR_INVAL = -2,
970 #ifdef JSMN_PARENT_LINKS
976 unsigned int toknext;
979 static void jsmn_init(jsmn_parser *parser);
980 static int jsmn_parse(jsmn_parser *parser,
const char *js,
size_t len, jsmntok_t *tokens,
size_t num_tokens);
987 #define GlbHeaderSize 12
988 #define GlbChunkHeaderSize 8
989 static const uint32_t GlbVersion = 2;
990 static const uint32_t GlbMagic = 0x46546C67;
991 static const uint32_t GlbMagicJsonChunk = 0x4E4F534A;
992 static const uint32_t GlbMagicBinChunk = 0x004E4942;
997 #define CGLTF_MALLOC(size) malloc(size)
1000 #define CGLTF_FREE(ptr) free(ptr)
1003 #define CGLTF_ATOI(str) atoi(str)
1006 #define CGLTF_ATOF(str) atof(str)
1009 #define CGLTF_ATOLL(str) atoll(str)
1011 #ifndef CGLTF_VALIDATE_ENABLE_ASSERTS
1012 #define CGLTF_VALIDATE_ENABLE_ASSERTS 0
1018 return CGLTF_MALLOC(size);
1021 static void cgltf_default_free(
void* user,
void*
ptr)
1029 if (SIZE_MAX / element_size < count)
1038 memset(result, 0, element_size * count);
1046 void (*memory_free)(
void*,
void*) = memory_options->
free_func ? memory_options->
free_func : &cgltf_default_free;
1048 FILE* file =
fopen(path,
"rb");
1061 __int64
length = _ftelli64(file);
1063 long length =
ftell(file);
1076 char* file_data = (
char*)memory_alloc(memory_options->
user_data, file_size);
1083 cgltf_size read_size = fread(file_data, 1, file_size, file);
1087 if (read_size != file_size)
1089 memory_free(memory_options->
user_data, file_data);
1109 void (*memfree)(
void*,
void*) = memory_options->
free_func ? memory_options->
free_func : &cgltf_default_free;
1110 memfree(memory_options->
user_data, data);
1117 if (size < GlbHeaderSize)
1122 if (options == NULL)
1139 memcpy(&tmp, data, 4);
1140 if (tmp != GlbMagic)
1154 cgltf_result json_result = cgltf_parse_json(&fixed_options, (
const uint8_t*)data, size, out_data);
1165 const uint8_t*
ptr = (
const uint8_t*)data;
1167 memcpy(&tmp, ptr + 4, 4);
1169 if (version != GlbVersion)
1175 memcpy(&tmp, ptr + 8, 4);
1181 const uint8_t* json_chunk = ptr + GlbHeaderSize;
1183 if (GlbHeaderSize + GlbChunkHeaderSize > size)
1189 uint32_t json_length;
1190 memcpy(&json_length, json_chunk, 4);
1191 if (json_length > size - GlbHeaderSize - GlbChunkHeaderSize)
1197 memcpy(&tmp, json_chunk + 4, 4);
1198 if (tmp != GlbMagicJsonChunk)
1203 json_chunk += GlbChunkHeaderSize;
1205 const void* bin = NULL;
1208 if (GlbChunkHeaderSize <= size - GlbHeaderSize - GlbChunkHeaderSize - json_length)
1211 const uint8_t* bin_chunk = json_chunk + json_length;
1214 uint32_t bin_length;
1215 memcpy(&bin_length, bin_chunk, 4);
1216 if (bin_length > size - GlbHeaderSize - GlbChunkHeaderSize - json_length - GlbChunkHeaderSize)
1222 memcpy(&tmp, bin_chunk + 4, 4);
1223 if (tmp != GlbMagicBinChunk)
1228 bin_chunk += GlbChunkHeaderSize;
1231 bin_size = bin_length;
1234 cgltf_result json_result = cgltf_parse_json(&fixed_options, json_chunk, json_length, out_data);
1241 (*out_data)->bin = bin;
1242 (*out_data)->bin_size = bin_size;
1249 if (options == NULL)
1257 void* file_data = NULL;
1258 cgltf_size file_size = 0;
1265 result =
cgltf_parse(options, file_data, file_size, out_data);
1269 file_release(&options->
memory, &options->
file, file_data, file_size);
1273 (*out_data)->file_data = file_data;
1279 static void cgltf_combine_paths(
char* path,
const char* base,
const char* uri)
1281 const char* s0 = strrchr(base,
'/');
1282 const char* s1 = strrchr(base,
'\\');
1283 const char* slash = s0 ? (s1 && s1 > s0 ? s1 : s0) : s1;
1287 size_t prefix = slash - base + 1;
1289 strncpy(path, base, prefix);
1290 strcpy(path + prefix, uri);
1298 static cgltf_result cgltf_load_buffer_file(
const cgltf_options* options, cgltf_size size,
const char* uri,
const char* gltf_path,
void** out_data)
1304 char* path = (
char*)memory_alloc(options->
memory.
user_data, strlen(uri) + strlen(gltf_path) + 1);
1310 cgltf_combine_paths(path, gltf_path, uri);
1315 void* file_data = NULL;
1330 unsigned char* data = (
unsigned char*)memory_alloc(options->
memory.
user_data, size);
1337 unsigned int buffer_bits = 0;
1339 for (cgltf_size i = 0; i <
size; ++i)
1341 while (buffer_bits < 8)
1343 char ch = *base64++;
1346 (unsigned)(ch -
'A') < 26 ? (ch -
'A') :
1347 (
unsigned)(ch -
'a') < 26 ? (ch -
'a') + 26 :
1348 (unsigned)(ch -
'0') < 10 ? (ch -
'0') + 52 :
1359 buffer = (buffer << 6) | index;
1363 data[i] = (
unsigned char)(buffer >> (buffer_bits - 8));
1372 static int cgltf_unhex(
char ch)
1375 (
unsigned)(ch -
'0') < 10 ? (ch -
'0') :
1376 (unsigned)(ch -
'A') < 6 ? (ch -
'A') + 10 :
1377 (
unsigned)(ch -
'a') < 6 ? (ch -
'a') + 10 :
1383 char*
read =
string + strcspn(
string,
"\\");
1394 cgltf_size written = read -
last;
1395 memmove(write, last, written);
1406 case '\"': *write++ =
'\"';
break;
1407 case '/': *write++ =
'/';
break;
1408 case '\\': *write++ =
'\\';
break;
1409 case 'b': *write++ =
'\b';
break;
1410 case 'f': *write++ =
'\f';
break;
1411 case 'r': *write++ =
'\r';
break;
1412 case 'n': *write++ =
'\n';
break;
1413 case 't': *write++ =
'\t';
break;
1418 for (cgltf_size i = 0; i < 4; ++i)
1420 character = (character << 4) + cgltf_unhex(*read++);
1423 if (character <= 0x7F)
1425 *write++ = character & 0xFF;
1427 else if (character <= 0x7FF)
1429 *write++ = 0xC0 | ((character >> 6) & 0xFF);
1430 *write++ = 0x80 | (character & 0x3F);
1434 *write++ = 0xE0 | ((character >> 12) & 0xFF);
1435 *write++ = 0x80 | ((character >> 6) & 0x3F);
1436 *write++ = 0x80 | (character & 0x3F);
1445 read += strcspn(read,
"\\");
1461 int ch1 = cgltf_unhex(i[1]);
1465 int ch2 = cgltf_unhex(i[2]);
1469 *write++ = (char)(ch1 * 16 + ch2);
1485 if (options == NULL)
1515 if (strncmp(uri,
"data:", 5) == 0)
1517 const char* comma = strchr(uri,
',');
1519 if (comma && comma - uri >= 7 && strncmp(comma - 7,
";base64", 7) == 0)
1534 else if (strstr(uri,
"://") == NULL && gltf_path)
1555 char* data = (
char*)buffer_view->
buffer->
data + offset + buffer_view->
offset;
1556 cgltf_size bound = 0;
1558 switch (component_type)
1561 for (
size_t i = 0; i <
count; ++i)
1563 cgltf_size
v = ((
unsigned char*)data)[i];
1564 bound = bound > v ? bound :
v;
1569 for (
size_t i = 0; i <
count; ++i)
1571 cgltf_size
v = ((
unsigned short*)data)[i];
1572 bound = bound > v ? bound :
v;
1577 for (
size_t i = 0; i <
count; ++i)
1579 cgltf_size
v = ((
unsigned int*)data)[i];
1580 bound = bound > v ? bound :
v;
1591 #if CGLTF_VALIDATE_ENABLE_ASSERTS
1592 #define CGLTF_ASSERT_IF(cond, result) assert(!(cond)); if (cond) return result;
1594 #define CGLTF_ASSERT_IF(cond, result) if (cond) return result;
1610 cgltf_size req_size = accessor->
offset + accessor->
stride * (accessor->
count - 1) + element_size;
1709 CGLTF_ASSERT_IF(indices &&
1731 for (cgltf_size i = 0; i < data->
nodes_count; ++i)
1752 for (cgltf_size i = 0; i < data->
nodes_count; ++i)
1785 cgltf_size components = 1;
1816 *dest_size = json_size + 1;
1822 if (*dest_size + 1 < json_size)
1825 dest[*dest_size - 1] = 0;
1830 dest[json_size] = 0;
1843 for (cgltf_size i = 0; i < extensions_count; ++i)
1860 data->memory.free_func(data->memory.user_data, data->asset.copyright);
1861 data->memory.free_func(data->memory.user_data, data->asset.generator);
1862 data->memory.free_func(data->memory.user_data, data->asset.version);
1863 data->memory.free_func(data->memory.user_data, data->asset.min_version);
1865 cgltf_free_extensions(data, data->asset.extensions, data->asset.extensions_count);
1866 cgltf_free_extras(data, &data->asset.extras);
1868 for (cgltf_size i = 0; i < data->accessors_count; ++i)
1870 data->memory.free_func(data->memory.user_data, data->accessors[i].name);
1872 cgltf_free_extensions(data, data->accessors[i].extensions, data->accessors[i].extensions_count);
1873 cgltf_free_extras(data, &data->accessors[i].extras);
1875 data->memory.free_func(data->memory.user_data, data->accessors);
1877 for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
1879 data->memory.free_func(data->memory.user_data, data->buffer_views[i].name);
1880 data->memory.free_func(data->memory.user_data, data->buffer_views[i].data);
1882 cgltf_free_extensions(data, data->buffer_views[i].extensions, data->buffer_views[i].extensions_count);
1883 cgltf_free_extras(data, &data->buffer_views[i].extras);
1885 data->memory.free_func(data->memory.user_data, data->buffer_views);
1887 for (cgltf_size i = 0; i < data->buffers_count; ++i)
1889 data->memory.free_func(data->memory.user_data, data->buffers[i].name);
1893 file_release(&data->memory, &data->file, data->buffers[i].data, data->buffers[i].size);
1897 data->memory.free_func(data->memory.user_data, data->buffers[i].data);
1900 data->memory.free_func(data->memory.user_data, data->buffers[i].uri);
1902 cgltf_free_extensions(data, data->buffers[i].extensions, data->buffers[i].extensions_count);
1903 cgltf_free_extras(data, &data->buffers[i].extras);
1905 data->memory.free_func(data->memory.user_data, data->buffers);
1907 for (cgltf_size i = 0; i < data->meshes_count; ++i)
1909 data->memory.free_func(data->memory.user_data, data->meshes[i].name);
1911 for (cgltf_size
j = 0;
j < data->meshes[i].primitives_count; ++
j)
1913 for (cgltf_size k = 0; k < data->meshes[i].primitives[
j].attributes_count; ++k)
1915 data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[
j].attributes[k].name);
1918 data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[
j].attributes);
1920 for (cgltf_size k = 0; k < data->meshes[i].primitives[
j].targets_count; ++k)
1922 for (cgltf_size m = 0; m < data->meshes[i].primitives[
j].targets[k].attributes_count; ++m)
1924 data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].targets[k].attributes[m].name);
1927 data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].targets[k].attributes);
1930 data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].targets);
1932 if (data->meshes[i].primitives[j].has_draco_mesh_compression)
1934 for (cgltf_size k = 0; k < data->meshes[i].primitives[
j].draco_mesh_compression.attributes_count; ++k)
1936 data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes[k].name);
1939 data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes);
1942 for (cgltf_size k = 0; k < data->meshes[i].primitives[
j].mappings_count; ++k)
1944 cgltf_free_extras(data, &data->meshes[i].primitives[j].mappings[k].extras);
1947 data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].mappings);
1949 cgltf_free_extensions(data, data->meshes[i].primitives[j].extensions, data->meshes[i].primitives[j].extensions_count);
1950 cgltf_free_extras(data, &data->meshes[i].primitives[j].extras);
1953 data->memory.free_func(data->memory.user_data, data->meshes[i].primitives);
1954 data->memory.free_func(data->memory.user_data, data->meshes[i].weights);
1956 for (cgltf_size j = 0; j < data->meshes[i].target_names_count; ++
j)
1958 data->memory.free_func(data->memory.user_data, data->meshes[i].target_names[j]);
1961 cgltf_free_extensions(data, data->meshes[i].extensions, data->meshes[i].extensions_count);
1962 cgltf_free_extras(data, &data->meshes[i].extras);
1964 data->memory.free_func(data->memory.user_data, data->meshes[i].target_names);
1967 data->memory.free_func(data->memory.user_data, data->meshes);
1969 for (cgltf_size i = 0; i < data->materials_count; ++i)
1971 data->memory.free_func(data->memory.user_data, data->materials[i].name);
1973 cgltf_free_extensions(data, data->materials[i].extensions, data->materials[i].extensions_count);
1974 cgltf_free_extras(data, &data->materials[i].extras);
1977 data->memory.free_func(data->memory.user_data, data->materials);
1979 for (cgltf_size i = 0; i < data->images_count; ++i)
1981 data->memory.free_func(data->memory.user_data, data->images[i].name);
1982 data->memory.free_func(data->memory.user_data, data->images[i].uri);
1983 data->memory.free_func(data->memory.user_data, data->images[i].mime_type);
1985 cgltf_free_extensions(data, data->images[i].extensions, data->images[i].extensions_count);
1986 cgltf_free_extras(data, &data->images[i].extras);
1989 data->memory.free_func(data->memory.user_data, data->images);
1991 for (cgltf_size i = 0; i < data->textures_count; ++i)
1993 data->memory.free_func(data->memory.user_data, data->textures[i].name);
1995 cgltf_free_extensions(data, data->textures[i].extensions, data->textures[i].extensions_count);
1996 cgltf_free_extras(data, &data->textures[i].extras);
1999 data->memory.free_func(data->memory.user_data, data->textures);
2001 for (cgltf_size i = 0; i < data->samplers_count; ++i)
2003 data->memory.free_func(data->memory.user_data, data->samplers[i].name);
2005 cgltf_free_extensions(data, data->samplers[i].extensions, data->samplers[i].extensions_count);
2006 cgltf_free_extras(data, &data->samplers[i].extras);
2009 data->memory.free_func(data->memory.user_data, data->samplers);
2011 for (cgltf_size i = 0; i < data->skins_count; ++i)
2013 data->memory.free_func(data->memory.user_data, data->skins[i].name);
2014 data->memory.free_func(data->memory.user_data, data->skins[i].joints);
2016 cgltf_free_extensions(data, data->skins[i].extensions, data->skins[i].extensions_count);
2017 cgltf_free_extras(data, &data->skins[i].extras);
2020 data->memory.free_func(data->memory.user_data, data->skins);
2022 for (cgltf_size i = 0; i < data->cameras_count; ++i)
2024 data->memory.free_func(data->memory.user_data, data->cameras[i].name);
2028 cgltf_free_extras(data, &data->cameras[i].data.perspective.extras);
2032 cgltf_free_extras(data, &data->cameras[i].data.orthographic.extras);
2035 cgltf_free_extensions(data, data->cameras[i].extensions, data->cameras[i].extensions_count);
2036 cgltf_free_extras(data, &data->cameras[i].extras);
2039 data->memory.free_func(data->memory.user_data, data->cameras);
2041 for (cgltf_size i = 0; i < data->lights_count; ++i)
2043 data->memory.free_func(data->memory.user_data, data->lights[i].name);
2045 cgltf_free_extras(data, &data->lights[i].extras);
2048 data->memory.free_func(data->memory.user_data, data->lights);
2050 for (cgltf_size i = 0; i < data->nodes_count; ++i)
2052 data->memory.free_func(data->memory.user_data, data->nodes[i].name);
2053 data->memory.free_func(data->memory.user_data, data->nodes[i].children);
2054 data->memory.free_func(data->memory.user_data, data->nodes[i].weights);
2056 if (data->nodes[i].has_mesh_gpu_instancing)
2058 for (cgltf_size j = 0; j < data->nodes[i].mesh_gpu_instancing.attributes_count; ++
j)
2060 data->memory.free_func(data->memory.user_data, data->nodes[i].mesh_gpu_instancing.attributes[j].name);
2063 data->memory.free_func(data->memory.user_data, data->nodes[i].mesh_gpu_instancing.attributes);
2066 cgltf_free_extensions(data, data->nodes[i].extensions, data->nodes[i].extensions_count);
2067 cgltf_free_extras(data, &data->nodes[i].extras);
2070 data->memory.free_func(data->memory.user_data, data->nodes);
2072 for (cgltf_size i = 0; i < data->scenes_count; ++i)
2074 data->memory.free_func(data->memory.user_data, data->scenes[i].name);
2075 data->memory.free_func(data->memory.user_data, data->scenes[i].nodes);
2077 cgltf_free_extensions(data, data->scenes[i].extensions, data->scenes[i].extensions_count);
2078 cgltf_free_extras(data, &data->scenes[i].extras);
2081 data->memory.free_func(data->memory.user_data, data->scenes);
2083 for (cgltf_size i = 0; i < data->animations_count; ++i)
2085 data->memory.free_func(data->memory.user_data, data->animations[i].name);
2086 for (cgltf_size j = 0; j < data->animations[i].samplers_count; ++
j)
2088 cgltf_free_extensions(data, data->animations[i].samplers[j].extensions, data->animations[i].samplers[j].extensions_count);
2089 cgltf_free_extras(data, &data->animations[i].samplers[j].extras);
2091 data->memory.free_func(data->memory.user_data, data->animations[i].samplers);
2093 for (cgltf_size j = 0; j < data->animations[i].channels_count; ++
j)
2095 cgltf_free_extensions(data, data->animations[i].channels[j].extensions, data->animations[i].channels[j].extensions_count);
2096 cgltf_free_extras(data, &data->animations[i].channels[j].extras);
2098 data->memory.free_func(data->memory.user_data, data->animations[i].channels);
2100 cgltf_free_extensions(data, data->animations[i].extensions, data->animations[i].extensions_count);
2101 cgltf_free_extras(data, &data->animations[i].extras);
2104 data->memory.free_func(data->memory.user_data, data->animations);
2106 for (cgltf_size i = 0; i < data->variants_count; ++i)
2108 data->memory.free_func(data->memory.user_data, data->variants[i].name);
2110 cgltf_free_extras(data, &data->variants[i].extras);
2113 data->memory.free_func(data->memory.user_data, data->variants);
2115 cgltf_free_extensions(data, data->data_extensions, data->data_extensions_count);
2116 cgltf_free_extras(data, &data->extras);
2118 for (cgltf_size i = 0; i < data->extensions_used_count; ++i)
2120 data->memory.free_func(data->memory.user_data, data->extensions_used[i]);
2123 data->memory.free_func(data->memory.user_data, data->extensions_used);
2125 for (cgltf_size i = 0; i < data->extensions_required_count; ++i)
2127 data->memory.free_func(data->memory.user_data, data->extensions_required[i]);
2130 data->memory.free_func(data->memory.user_data, data->extensions_required);
2132 file_release(&data->memory, &data->file, data->file_data, data->file_size);
2134 data->memory.free_func(data->memory.user_data, data);
2143 memcpy(lm, node->
matrix,
sizeof(
float) * 16);
2156 float sx = node->
scale[0];
2157 float sy = node->
scale[1];
2158 float sz = node->
scale[2];
2160 lm[0] = (1 - 2 * qy*qy - 2 * qz*qz) * sx;
2161 lm[1] = (2 * qx*qy + 2 * qz*qw) * sx;
2162 lm[2] = (2 * qx*qz - 2 * qy*qw) * sx;
2165 lm[4] = (2 * qx*qy - 2 * qz*qw) * sy;
2166 lm[5] = (1 - 2 * qx*qx - 2 * qz*qz) * sy;
2167 lm[6] = (2 * qy*qz + 2 * qx*qw) * sy;
2170 lm[8] = (2 * qx*qz + 2 * qy*qw) * sz;
2171 lm[9] = (2 * qy*qz - 2 * qx*qw) * sz;
2172 lm[10] = (1 - 2 * qx*qx - 2 * qy*qy) * sz;
2194 for (
int i = 0; i < 4; ++i)
2196 float l0 = lm[i * 4 + 0];
2197 float l1 = lm[i * 4 + 1];
2198 float l2 = lm[i * 4 + 2];
2200 float r0 = l0 * pm[0] + l1 * pm[4] + l2 * pm[8];
2201 float r1 = l0 * pm[1] + l1 * pm[5] + l2 * pm[9];
2202 float r2 = l0 * pm[2] + l1 * pm[6] + l2 * pm[10];
2219 switch (component_type)
2222 return *((
const int16_t*) in);
2224 return *((
const uint16_t*) in);
2226 return *((
const uint32_t*) in);
2228 return *((
const int8_t*) in);
2230 return *((
const uint8_t*) in);
2236 static cgltf_size cgltf_component_read_index(
const void* in,
cgltf_component_type component_type)
2238 switch (component_type)
2241 return *((
const uint16_t*) in);
2243 return *((
const uint32_t*) in);
2245 return *((
const uint8_t*) in);
2255 return *((
const float*) in);
2260 switch (component_type)
2264 return *((
const int16_t*) in) / (
cgltf_float)32767;
2266 return *((
const uint16_t*) in) / (
cgltf_float)65535;
2276 return (
cgltf_float)cgltf_component_read_integer(in, component_type);
2283 if (element_size < num_components) {
2293 out[0] = cgltf_component_read_float(element, component_type, normalized);
2294 out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
2295 out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
2296 out[3] = cgltf_component_read_float(element + 5, component_type, normalized);
2302 out[0] = cgltf_component_read_float(element, component_type, normalized);
2303 out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
2304 out[2] = cgltf_component_read_float(element + 2, component_type, normalized);
2305 out[3] = cgltf_component_read_float(element + 4, component_type, normalized);
2306 out[4] = cgltf_component_read_float(element + 5, component_type, normalized);
2307 out[5] = cgltf_component_read_float(element + 6, component_type, normalized);
2308 out[6] = cgltf_component_read_float(element + 8, component_type, normalized);
2309 out[7] = cgltf_component_read_float(element + 9, component_type, normalized);
2310 out[8] = cgltf_component_read_float(element + 10, component_type, normalized);
2316 out[0] = cgltf_component_read_float(element, component_type, normalized);
2317 out[1] = cgltf_component_read_float(element + 2, component_type, normalized);
2318 out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
2319 out[3] = cgltf_component_read_float(element + 8, component_type, normalized);
2320 out[4] = cgltf_component_read_float(element + 10, component_type, normalized);
2321 out[5] = cgltf_component_read_float(element + 12, component_type, normalized);
2322 out[6] = cgltf_component_read_float(element + 16, component_type, normalized);
2323 out[7] = cgltf_component_read_float(element + 18, component_type, normalized);
2324 out[8] = cgltf_component_read_float(element + 20, component_type, normalized);
2328 for (cgltf_size i = 0; i < num_components; ++i)
2330 out[i] = cgltf_component_read_float(element + component_size * i, component_type, normalized);
2338 return (
const uint8_t*)view->
data;
2343 const uint8_t* result = (
const uint8_t*)view->
buffer->
data;
2353 if (attr->
type == type && attr->
index == index)
2360 static const uint8_t* cgltf_find_sparse_index(
const cgltf_accessor* accessor, cgltf_size needle)
2366 if (index_data == NULL || value_data == NULL)
2374 cgltf_size offset = 0;
2375 cgltf_size length = sparse->
count;
2379 cgltf_size rem = length % 2;
2382 cgltf_size index = cgltf_component_read_index(index_data + (offset + length) * index_stride, sparse->
indices_component_type);
2383 offset += index < needle ? length + rem : 0;
2386 if (offset == sparse->
count)
2389 cgltf_size index = cgltf_component_read_index(index_data + offset * index_stride, sparse->
indices_component_type);
2390 return index == needle ? value_data + offset * accessor->
stride : NULL;
2397 const uint8_t* element = cgltf_find_sparse_index(accessor, index);
2403 memset(out, 0, element_size *
sizeof(
cgltf_float));
2407 if (element == NULL)
2418 cgltf_size available_floats = accessor->
count * floats_per_element;
2421 return available_floats;
2424 float_count = available_floats < float_count ? available_floats : float_count;
2425 cgltf_size element_count = float_count / floats_per_element;
2430 memset(out, 0, element_count * floats_per_element *
sizeof(
cgltf_float));
2435 if (element == NULL)
2439 element += accessor->
offset;
2443 memcpy(out, element, element_count * floats_per_element *
sizeof(
cgltf_float));
2449 for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element, element += accessor->
stride)
2467 if (index_data == NULL || reader_head == NULL)
2476 for (cgltf_size reader_index = 0; reader_index < sparse->
count; reader_index++, index_data += index_stride, reader_head += accessor->
stride)
2479 float* writer_head = out + writer_index * floats_per_element;
2481 if (!cgltf_element_read_float(reader_head, accessor->
type, accessor->
component_type, accessor->
normalized, writer_head, floats_per_element))
2488 return element_count * floats_per_element;
2493 switch (component_type)
2496 return *((
const int8_t*) in);
2499 return *((
const uint8_t*) in);
2502 return *((
const int16_t*) in);
2505 return *((
const uint16_t*) in);
2508 return *((
const uint32_t*) in);
2519 if (element_size < num_components)
2532 for (cgltf_size i = 0; i < num_components; ++i)
2534 out[i] = cgltf_component_read_uint(element + component_size * i, component_type);
2543 const uint8_t* element = cgltf_find_sparse_index(accessor, index);
2545 return cgltf_element_read_uint(element, accessor->
type, accessor->
component_type, out, element_size);
2549 memset(out, 0, element_size *
sizeof(
cgltf_uint));
2553 if (element == NULL)
2558 return cgltf_element_read_uint(element, accessor->
type, accessor->
component_type, out, element_size);
2565 const uint8_t* element = cgltf_find_sparse_index(accessor, index);
2567 return cgltf_component_read_index(element, accessor->
component_type);
2574 if (element == NULL)
2579 return cgltf_component_read_index(element, accessor->
component_type);
2585 return (cgltf_size)(
object - data->
meshes);
2591 return (cgltf_size)(
object - data->
materials);
2597 return (cgltf_size)(
object - data->
accessors);
2609 return (cgltf_size)(
object - data->
buffers);
2615 return (cgltf_size)(
object - data->
images);
2621 return (cgltf_size)(
object - data->
textures);
2627 return (cgltf_size)(
object - data->
samplers);
2633 return (cgltf_size)(
object - data->
skins);
2639 return (cgltf_size)(
object - data->
cameras);
2645 return (cgltf_size)(
object - data->
lights);
2651 return (cgltf_size)(
object - data->
nodes);
2657 return (cgltf_size)(
object - data->
scenes);
2663 return (cgltf_size)(
object - data->
animations);
2669 return (cgltf_size)(
object - animation->
samplers);
2675 return (cgltf_size)(
object - animation->
channels);
2682 return accessor->
count;
2686 cgltf_size available_numbers = accessor->
count * numbers_per_element;
2688 index_count = available_numbers < index_count ? available_numbers : index_count;
2699 if (index_component_size > out_component_size)
2704 if (element == NULL)
2708 element += accessor->
offset;
2710 if (index_component_size == out_component_size && accessor->
stride == out_component_size * numbers_per_element)
2712 memcpy(out, element, index_count * index_component_size);
2719 switch (out_component_size)
2722 for (cgltf_size index = 0; index < index_count; index++, element += accessor->
stride)
2724 ((uint8_t*)out)[
index] = (uint8_t)cgltf_component_read_index(element, accessor->
component_type);
2728 for (cgltf_size index = 0; index < index_count; index++, element += accessor->
stride)
2730 ((uint16_t*)out)[
index] = (uint16_t)cgltf_component_read_index(element, accessor->
component_type);
2734 for (cgltf_size index = 0; index < index_count; index++, element += accessor->
stride)
2736 ((uint32_t*)out)[
index] = (uint32_t)cgltf_component_read_index(element, accessor->
component_type);
2746 #define CGLTF_ERROR_JSON -1
2747 #define CGLTF_ERROR_NOMEM -2
2748 #define CGLTF_ERROR_LEGACY -3
2750 #define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; }
2751 #define CGLTF_CHECK_TOKTYPE_RET(tok_, type_, ret_) if ((tok_).type != (type_)) { return ret_; }
2752 #define CGLTF_CHECK_KEY(tok_) if ((tok_).type != JSMN_STRING || (tok_).size == 0) { return CGLTF_ERROR_JSON; }
2754 #define CGLTF_PTRINDEX(type, idx) (type*)((cgltf_size)idx + 1)
2755 #define CGLTF_PTRFIXUP(var, data, size) if (var) { if ((cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1]; }
2756 #define CGLTF_PTRFIXUP_REQ(var, data, size) if (!var || (cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1];
2758 static int cgltf_json_strcmp(jsmntok_t
const* tok,
const uint8_t* json_chunk,
const char* str)
2760 CGLTF_CHECK_TOKTYPE(*tok, JSMN_STRING);
2761 size_t const str_len = strlen(str);
2762 size_t const name_length = (size_t)(tok->end - tok->start);
2763 return (str_len == name_length) ? strncmp((
const char*)json_chunk + tok->start, str, str_len) : 128;
2766 static int cgltf_json_to_int(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2768 CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
2770 int size = (size_t)(tok->end - tok->start) <
sizeof(tmp) ? (
int)(tok->end - tok->start) : (
int)(
sizeof(tmp) - 1);
2771 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2773 return CGLTF_ATOI(tmp);
2776 static cgltf_size cgltf_json_to_size(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2778 CGLTF_CHECK_TOKTYPE_RET(*tok, JSMN_PRIMITIVE, 0);
2780 int size = (size_t)(tok->end - tok->start) <
sizeof(tmp) ? (
int)(tok->end - tok->start) : (
int)(
sizeof(tmp) - 1);
2781 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2783 long long res = CGLTF_ATOLL(tmp);
2787 static cgltf_float cgltf_json_to_float(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2789 CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
2791 int size = (size_t)(tok->end - tok->start) <
sizeof(tmp) ? (
int)(tok->end - tok->start) : (
int)(
sizeof(tmp) - 1);
2792 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2797 static cgltf_bool cgltf_json_to_bool(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2799 int size = (
int)(tok->end - tok->start);
2800 return size == 4 && memcmp(json_chunk + tok->start,
"true", 4) == 0;
2803 static int cgltf_skip_json(jsmntok_t
const* tokens,
int i)
2809 switch (tokens[i].type)
2812 end += tokens[i].size * 2;
2816 end += tokens[i].size;
2819 case JSMN_PRIMITIVE:
2833 static void cgltf_fill_float_array(
float* out_array,
int size,
float value)
2835 for (
int j = 0; j <
size; ++
j)
2841 static int cgltf_parse_json_float_array(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
float* out_array,
int size)
2843 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2844 if (tokens[i].size != size)
2846 return CGLTF_ERROR_JSON;
2849 for (
int j = 0; j <
size; ++
j)
2851 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
2852 out_array[
j] = cgltf_json_to_float(tokens + i, json_chunk);
2858 static int cgltf_parse_json_string(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
char** out_string)
2860 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
2863 return CGLTF_ERROR_JSON;
2865 int size = (
int)(tokens[i].end - tokens[i].
start);
2869 return CGLTF_ERROR_NOMEM;
2871 strncpy(result, (
const char*)json_chunk + tokens[i].start, size);
2877 static int cgltf_parse_json_array(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
size_t element_size,
void** out_array, cgltf_size* out_size)
2880 if (tokens[i].type != JSMN_ARRAY)
2882 return tokens[i].type == JSMN_OBJECT ? CGLTF_ERROR_LEGACY : CGLTF_ERROR_JSON;
2886 return CGLTF_ERROR_JSON;
2888 int size = tokens[i].size;
2889 void* result = cgltf_calloc(options, element_size, size);
2892 return CGLTF_ERROR_NOMEM;
2899 static int cgltf_parse_json_string_array(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
char*** out_array, cgltf_size* out_size)
2901 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2902 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
char*), (
void**)out_array, out_size);
2908 for (cgltf_size j = 0; j < *out_size; ++
j)
2910 i = cgltf_parse_json_string(options, tokens, i, json_chunk, j + (*out_array));
2927 const char* us = strchr(name,
'_');
2928 size_t len = us ? (size_t)(us - name) : strlen(name);
2930 if (len == 8 && strncmp(name,
"POSITION", 8) == 0)
2934 else if (len == 6 && strncmp(name,
"NORMAL", 6) == 0)
2938 else if (len == 7 && strncmp(name,
"TANGENT", 7) == 0)
2942 else if (len == 8 && strncmp(name,
"TEXCOORD", 8) == 0)
2946 else if (len == 5 && strncmp(name,
"COLOR", 5) == 0)
2950 else if (len == 6 && strncmp(name,
"JOINTS", 6) == 0)
2954 else if (len == 7 && strncmp(name,
"WEIGHTS", 7) == 0)
2965 *out_index = CGLTF_ATOI(us + 1);
2974 static int cgltf_parse_json_attribute_list(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_attribute** out_attributes, cgltf_size* out_attributes_count)
2976 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2978 if (*out_attributes)
2980 return CGLTF_ERROR_JSON;
2983 *out_attributes_count = tokens[i].size;
2987 if (!*out_attributes)
2989 return CGLTF_ERROR_NOMEM;
2992 for (cgltf_size j = 0; j < *out_attributes_count; ++
j)
2994 CGLTF_CHECK_KEY(tokens[i]);
2996 i = cgltf_parse_json_string(options, tokens, i, json_chunk, &(*out_attributes)[j].name);
2999 return CGLTF_ERROR_JSON;
3002 cgltf_parse_attribute_type((*out_attributes)[j].name, &(*out_attributes)[j].type, &(*out_attributes)[j].index);
3004 (*out_attributes)[
j].data = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
3011 static int cgltf_parse_json_extras(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_extras* out_extras)
3013 if (out_extras->
data)
3015 return CGLTF_ERROR_JSON;
3022 size_t start = tokens[i].start;
3023 size_t size = tokens[i].end -
start;
3025 if (!out_extras->
data)
3027 return CGLTF_ERROR_NOMEM;
3029 strncpy(out_extras->
data, (
const char*)json_chunk + start, size);
3032 i = cgltf_skip_json(tokens, i);
3036 static int cgltf_parse_json_unprocessed_extension(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_extension* out_extension)
3038 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
3039 CGLTF_CHECK_TOKTYPE(tokens[i+1], JSMN_OBJECT);
3040 if (out_extension->
name)
3042 return CGLTF_ERROR_JSON;
3045 cgltf_size name_length = tokens[i].end - tokens[i].start;
3047 if (!out_extension->
name)
3049 return CGLTF_ERROR_NOMEM;
3051 strncpy(out_extension->
name, (
const char*)json_chunk + tokens[i].start, name_length);
3052 out_extension->
name[name_length] = 0;
3055 size_t start = tokens[i].start;
3056 size_t size = tokens[i].end -
start;
3058 if (!out_extension->
data)
3060 return CGLTF_ERROR_NOMEM;
3062 strncpy(out_extension->
data, (
const char*)json_chunk + start, size);
3065 i = cgltf_skip_json(tokens, i);
3070 static int cgltf_parse_json_unprocessed_extensions(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk, cgltf_size* out_extensions_count,
cgltf_extension** out_extensions)
3074 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3077 return CGLTF_ERROR_JSON;
3080 int extensions_size = tokens[i].size;
3081 *out_extensions_count = 0;
3084 if (!*out_extensions)
3086 return CGLTF_ERROR_NOMEM;
3091 for (
int j = 0; j < extensions_size; ++
j)
3093 CGLTF_CHECK_KEY(tokens[i]);
3095 cgltf_size extension_index = (*out_extensions_count)++;
3097 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, extension);
3109 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3111 int size = tokens[i].size;
3114 for (
int j = 0; j <
size; ++
j)
3116 CGLTF_CHECK_KEY(tokens[i]);
3118 if (cgltf_json_strcmp(tokens + i, json_chunk,
"attributes") == 0)
3120 i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_draco_mesh_compression->
attributes, &out_draco_mesh_compression->
attributes_count);
3122 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"bufferView") == 0)
3130 i = cgltf_skip_json(tokens, i+1);
3144 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3146 int size = tokens[i].size;
3149 for (
int j = 0; j <
size; ++
j)
3151 CGLTF_CHECK_KEY(tokens[i]);
3153 if (cgltf_json_strcmp(tokens + i, json_chunk,
"attributes") == 0)
3155 i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_mesh_gpu_instancing->
attributes, &out_mesh_gpu_instancing->
attributes_count);
3159 i = cgltf_skip_json(tokens, i+1);
3171 static int cgltf_parse_json_material_mapping_data(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_material_mapping* out_mappings, cgltf_size* offset)
3174 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
3176 int size = tokens[i].size;
3179 for (
int j = 0; j <
size; ++
j)
3181 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3183 int obj_size = tokens[i].size;
3187 int variants_tok = -1;
3188 int extras_tok = -1;
3190 for (
int k = 0; k < obj_size; ++k)
3192 CGLTF_CHECK_KEY(tokens[i]);
3194 if (cgltf_json_strcmp(tokens + i, json_chunk,
"material") == 0)
3197 material = cgltf_json_to_int(tokens + i, json_chunk);
3200 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"variants") == 0)
3203 CGLTF_CHECK_TOKTYPE(tokens[variants_tok], JSMN_ARRAY);
3205 i = cgltf_skip_json(tokens, i+1);
3207 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3210 i = cgltf_skip_json(tokens, extras_tok);
3214 i = cgltf_skip_json(tokens, i+1);
3223 if (material < 0 || variants_tok < 0)
3225 return CGLTF_ERROR_JSON;
3230 for (
int k = 0; k < tokens[variants_tok].size; ++k)
3232 int variant = cgltf_json_to_int(&tokens[variants_tok + 1 + k], json_chunk);
3239 if (extras_tok >= 0)
3241 int e = cgltf_parse_json_extras(options, tokens, extras_tok, json_chunk, &out_mappings[*offset].extras);
3251 (*offset) += tokens[variants_tok].size;
3258 static int cgltf_parse_json_material_mappings(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_primitive* out_prim)
3260 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3262 int size = tokens[i].size;
3265 for (
int j = 0; j <
size; ++
j)
3267 CGLTF_CHECK_KEY(tokens[i]);
3269 if (cgltf_json_strcmp(tokens + i, json_chunk,
"mappings") == 0)
3273 return CGLTF_ERROR_JSON;
3276 cgltf_size mappings_offset = 0;
3277 int k = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, NULL, &mappings_offset);
3286 mappings_offset = 0;
3287 i = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, out_prim->
mappings, &mappings_offset);
3291 i = cgltf_skip_json(tokens, i+1);
3303 static cgltf_primitive_type cgltf_json_to_primitive_type(jsmntok_t
const* tok,
const uint8_t* json_chunk)
3305 int type = cgltf_json_to_int(tok, json_chunk);
3328 static int cgltf_parse_json_primitive(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_primitive* out_prim)
3330 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3334 int size = tokens[i].size;
3337 for (
int j = 0; j <
size; ++
j)
3339 CGLTF_CHECK_KEY(tokens[i]);
3341 if (cgltf_json_strcmp(tokens+i, json_chunk,
"mode") == 0)
3344 out_prim->
type = cgltf_json_to_primitive_type(tokens+i, json_chunk);
3347 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"indices") == 0)
3353 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"material") == 0)
3359 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"attributes") == 0)
3363 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"targets") == 0)
3380 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3382 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_prim->
extras);
3384 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3388 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3391 return CGLTF_ERROR_JSON;
3394 int extensions_size = tokens[i].size;
3400 return CGLTF_ERROR_NOMEM;
3404 for (
int k = 0; k < extensions_size; ++k)
3406 CGLTF_CHECK_KEY(tokens[i]);
3408 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_draco_mesh_compression") == 0)
3411 i = cgltf_parse_json_draco_mesh_compression(options, tokens, i + 1, json_chunk, &out_prim->
draco_mesh_compression);
3413 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_variants") == 0)
3415 i = cgltf_parse_json_material_mappings(options, tokens, i + 1, json_chunk, out_prim);
3419 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_prim->
extensions[out_prim->
extensions_count++]));
3430 i = cgltf_skip_json(tokens, i+1);
3442 static int cgltf_parse_json_mesh(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_mesh* out_mesh)
3444 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3446 int size = tokens[i].size;
3449 for (
int j = 0; j <
size; ++
j)
3451 CGLTF_CHECK_KEY(tokens[i]);
3453 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
3455 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_mesh->
name);
3457 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"primitives") == 0)
3465 for (cgltf_size prim_index = 0; prim_index < out_mesh->
primitives_count; ++prim_index)
3467 i = cgltf_parse_json_primitive(options, tokens, i, json_chunk, &out_mesh->
primitives[prim_index]);
3474 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"weights") == 0)
3482 i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_mesh->
weights, (
int)out_mesh->
weights_count);
3484 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3491 if (tokens[i].type == JSMN_OBJECT)
3493 int extras_size = tokens[i].size;
3496 for (
int k = 0; k < extras_size; ++k)
3498 CGLTF_CHECK_KEY(tokens[i]);
3500 if (cgltf_json_strcmp(tokens+i, json_chunk,
"targetNames") == 0 && tokens[i+1].type == JSMN_ARRAY)
3506 i = cgltf_skip_json(tokens, i+1);
3517 i = cgltf_skip_json(tokens, i);
3520 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3522 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_mesh->
extensions_count, &out_mesh->
extensions);
3526 i = cgltf_skip_json(tokens, i+1);
3538 static int cgltf_parse_json_meshes(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
3548 i = cgltf_parse_json_mesh(options, tokens, i, json_chunk, &out_data->
meshes[j]);
3557 static cgltf_component_type cgltf_json_to_component_type(jsmntok_t
const* tok,
const uint8_t* json_chunk)
3559 int type = cgltf_json_to_int(tok, json_chunk);
3580 static int cgltf_parse_json_accessor_sparse(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_accessor_sparse* out_sparse)
3582 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3584 int size = tokens[i].size;
3587 for (
int j = 0; j <
size; ++
j)
3589 CGLTF_CHECK_KEY(tokens[i]);
3591 if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
3594 out_sparse->
count = cgltf_json_to_size(tokens + i, json_chunk);
3597 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"indices") == 0)
3600 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3602 int indices_size = tokens[i].size;
3605 for (
int k = 0; k < indices_size; ++k)
3607 CGLTF_CHECK_KEY(tokens[i]);
3609 if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3615 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3621 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"componentType") == 0)
3629 i = cgltf_skip_json(tokens, i+1);
3638 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"values") == 0)
3641 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3643 int values_size = tokens[i].size;
3646 for (
int k = 0; k < values_size; ++k)
3648 CGLTF_CHECK_KEY(tokens[i]);
3650 if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3656 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3664 i = cgltf_skip_json(tokens, i+1);
3675 i = cgltf_skip_json(tokens, i+1);
3687 static int cgltf_parse_json_accessor(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_accessor* out_accessor)
3689 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3691 int size = tokens[i].size;
3694 for (
int j = 0; j <
size; ++
j)
3696 CGLTF_CHECK_KEY(tokens[i]);
3698 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
3700 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_accessor->
name);
3702 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3708 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3712 cgltf_json_to_size(tokens+i, json_chunk);
3715 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"componentType") == 0)
3718 out_accessor->
component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
3721 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"normalized") == 0)
3724 out_accessor->
normalized = cgltf_json_to_bool(tokens+i, json_chunk);
3727 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
3730 out_accessor->
count = cgltf_json_to_size(tokens+i, json_chunk);
3733 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
3736 if (cgltf_json_strcmp(tokens+i, json_chunk,
"SCALAR") == 0)
3740 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC2") == 0)
3744 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC3") == 0)
3748 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC4") == 0)
3752 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT2") == 0)
3756 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT3") == 0)
3760 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT4") == 0)
3766 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"min") == 0)
3771 int min_size = tokens[i].size > 16 ? 16 : tokens[i].size;
3772 i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->
min, min_size);
3774 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"max") == 0)
3779 int max_size = tokens[i].size > 16 ? 16 : tokens[i].size;
3780 i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->
max, max_size);
3782 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"sparse") == 0)
3785 i = cgltf_parse_json_accessor_sparse(tokens, i + 1, json_chunk, &out_accessor->
sparse);
3787 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3789 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_accessor->
extras);
3791 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3793 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_accessor->
extensions_count, &out_accessor->
extensions);
3797 i = cgltf_skip_json(tokens, i+1);
3809 static int cgltf_parse_json_texture_transform(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_texture_transform* out_texture_transform)
3811 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3813 int size = tokens[i].size;
3816 for (
int j = 0; j <
size; ++
j)
3818 CGLTF_CHECK_KEY(tokens[i]);
3820 if (cgltf_json_strcmp(tokens + i, json_chunk,
"offset") == 0)
3822 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->
offset, 2);
3824 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"rotation") == 0)
3827 out_texture_transform->
rotation = cgltf_json_to_float(tokens + i, json_chunk);
3830 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scale") == 0)
3832 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->
scale, 2);
3834 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"texCoord") == 0)
3838 out_texture_transform->
texcoord = cgltf_json_to_int(tokens + i, json_chunk);
3843 i = cgltf_skip_json(tokens, i + 1);
3855 static int cgltf_parse_json_texture_view(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_texture_view* out_texture_view)
3859 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3861 out_texture_view->
scale = 1.0f;
3862 cgltf_fill_float_array(out_texture_view->
transform.
scale, 2, 1.0f);
3864 int size = tokens[i].size;
3867 for (
int j = 0; j <
size; ++
j)
3869 CGLTF_CHECK_KEY(tokens[i]);
3871 if (cgltf_json_strcmp(tokens + i, json_chunk,
"index") == 0)
3874 out_texture_view->
texture = CGLTF_PTRINDEX(
cgltf_texture, cgltf_json_to_int(tokens + i, json_chunk));
3877 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"texCoord") == 0)
3880 out_texture_view->
texcoord = cgltf_json_to_int(tokens + i, json_chunk);
3883 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scale") == 0)
3886 out_texture_view->
scale = cgltf_json_to_float(tokens + i, json_chunk);
3889 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"strength") == 0)
3892 out_texture_view->
scale = cgltf_json_to_float(tokens + i, json_chunk);
3895 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3899 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3900 int extensions_size = tokens[i].size;
3904 for (
int k = 0; k < extensions_size; ++k)
3906 CGLTF_CHECK_KEY(tokens[i]);
3908 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_texture_transform") == 0)
3911 i = cgltf_parse_json_texture_transform(tokens, i + 1, json_chunk, &out_texture_view->
transform);
3915 i = cgltf_skip_json(tokens, i + 1);
3926 i = cgltf_skip_json(tokens, i + 1);
3940 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3942 int size = tokens[i].size;
3945 for (
int j = 0; j <
size; ++
j)
3947 CGLTF_CHECK_KEY(tokens[i]);
3949 if (cgltf_json_strcmp(tokens+i, json_chunk,
"metallicFactor") == 0)
3953 cgltf_json_to_float(tokens + i, json_chunk);
3956 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"roughnessFactor") == 0)
3960 cgltf_json_to_float(tokens+i, json_chunk);
3963 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"baseColorFactor") == 0)
3965 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->
base_color_factor, 4);
3967 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"baseColorTexture") == 0)
3969 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->
base_color_texture);
3971 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"metallicRoughnessTexture") == 0)
3977 i = cgltf_skip_json(tokens, i+1);
3991 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3992 int size = tokens[i].size;
3995 for (
int j = 0; j <
size; ++
j)
3997 CGLTF_CHECK_KEY(tokens[i]);
3999 if (cgltf_json_strcmp(tokens+i, json_chunk,
"diffuseFactor") == 0)
4001 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->
diffuse_factor, 4);
4003 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularFactor") == 0)
4005 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->
specular_factor, 3);
4007 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"glossinessFactor") == 0)
4013 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"diffuseTexture") == 0)
4015 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->
diffuse_texture);
4017 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularGlossinessTexture") == 0)
4023 i = cgltf_skip_json(tokens, i+1);
4035 static int cgltf_parse_json_clearcoat(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_clearcoat* out_clearcoat)
4037 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4038 int size = tokens[i].size;
4041 for (
int j = 0; j <
size; ++
j)
4043 CGLTF_CHECK_KEY(tokens[i]);
4045 if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatFactor") == 0)
4048 out_clearcoat->
clearcoat_factor = cgltf_json_to_float(tokens + i, json_chunk);
4051 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatRoughnessFactor") == 0)
4057 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatTexture") == 0)
4059 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->
clearcoat_texture);
4061 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatRoughnessTexture") == 0)
4065 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatNormalTexture") == 0)
4071 i = cgltf_skip_json(tokens, i+1);
4083 static int cgltf_parse_json_ior(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_ior* out_ior)
4085 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4086 int size = tokens[i].size;
4090 out_ior->
ior = 1.5f;
4092 for (
int j = 0; j <
size; ++
j)
4094 CGLTF_CHECK_KEY(tokens[i]);
4096 if (cgltf_json_strcmp(tokens+i, json_chunk,
"ior") == 0)
4099 out_ior->
ior = cgltf_json_to_float(tokens + i, json_chunk);
4104 i = cgltf_skip_json(tokens, i+1);
4116 static int cgltf_parse_json_specular(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_specular* out_specular)
4118 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4119 int size = tokens[i].size;
4126 for (
int j = 0; j <
size; ++
j)
4128 CGLTF_CHECK_KEY(tokens[i]);
4130 if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularFactor") == 0)
4133 out_specular->
specular_factor = cgltf_json_to_float(tokens + i, json_chunk);
4136 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularColorFactor") == 0)
4138 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_specular->
specular_color_factor, 3);
4140 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularTexture") == 0)
4142 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->
specular_texture);
4144 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"specularColorTexture") == 0)
4146 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->
specular_color_texture);
4150 i = cgltf_skip_json(tokens, i+1);
4162 static int cgltf_parse_json_transmission(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_transmission* out_transmission)
4164 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4165 int size = tokens[i].size;
4168 for (
int j = 0; j <
size; ++
j)
4170 CGLTF_CHECK_KEY(tokens[i]);
4172 if (cgltf_json_strcmp(tokens+i, json_chunk,
"transmissionFactor") == 0)
4178 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"transmissionTexture") == 0)
4180 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_transmission->
transmission_texture);
4184 i = cgltf_skip_json(tokens, i+1);
4196 static int cgltf_parse_json_volume(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_volume* out_volume)
4198 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4199 int size = tokens[i].size;
4202 for (
int j = 0; j <
size; ++
j)
4204 CGLTF_CHECK_KEY(tokens[i]);
4206 if (cgltf_json_strcmp(tokens + i, json_chunk,
"thicknessFactor") == 0)
4209 out_volume->
thickness_factor = cgltf_json_to_float(tokens + i, json_chunk);
4212 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"thicknessTexture") == 0)
4214 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_volume->
thickness_texture);
4216 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"attenuationColor") == 0)
4218 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_volume->
attenuation_color, 3);
4220 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"attenuationDistance") == 0)
4228 i = cgltf_skip_json(tokens, i + 1);
4240 static int cgltf_parse_json_sheen(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_sheen* out_sheen)
4242 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4243 int size = tokens[i].size;
4246 for (
int j = 0; j <
size; ++
j)
4248 CGLTF_CHECK_KEY(tokens[i]);
4250 if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenColorFactor") == 0)
4252 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_sheen->
sheen_color_factor, 3);
4254 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenColorTexture") == 0)
4256 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_sheen->
sheen_color_texture);
4258 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenRoughnessFactor") == 0)
4264 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenRoughnessTexture") == 0)
4270 i = cgltf_skip_json(tokens, i+1);
4282 static int cgltf_parse_json_emissive_strength(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_emissive_strength* out_emissive_strength)
4284 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4285 int size = tokens[i].size;
4291 for (
int j = 0; j <
size; ++
j)
4293 CGLTF_CHECK_KEY(tokens[i]);
4295 if (cgltf_json_strcmp(tokens + i, json_chunk,
"emissiveStrength") == 0)
4298 out_emissive_strength->
emissive_strength = cgltf_json_to_float(tokens + i, json_chunk);
4303 i = cgltf_skip_json(tokens, i + 1);
4315 static int cgltf_parse_json_iridescence(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_iridescence* out_iridescence)
4317 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4318 int size = tokens[i].size;
4326 for (
int j = 0; j <
size; ++
j)
4328 CGLTF_CHECK_KEY(tokens[i]);
4330 if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceFactor") == 0)
4336 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceTexture") == 0)
4338 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_iridescence->
iridescence_texture);
4340 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceIor") == 0)
4343 out_iridescence->
iridescence_ior = cgltf_json_to_float(tokens + i, json_chunk);
4346 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceThicknessMinimum") == 0)
4352 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceThicknessMaximum") == 0)
4358 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceThicknessTexture") == 0)
4364 i = cgltf_skip_json(tokens, i + 1);
4378 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4379 int size = tokens[i].size;
4386 for (
int j = 0; j <
size; ++
j)
4388 CGLTF_CHECK_KEY(tokens[i]);
4390 if (cgltf_json_strcmp(tokens + i, json_chunk,
"diffuseTransmissionFactor") == 0)
4396 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"diffuseTransmissionTexture") == 0)
4400 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"diffuseTransmissionColorFactor") == 0)
4404 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"diffuseTransmissionColorTexture") == 0)
4410 i = cgltf_skip_json(tokens, i + 1);
4422 static int cgltf_parse_json_anisotropy(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_anisotropy* out_anisotropy)
4424 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4425 int size = tokens[i].size;
4429 for (
int j = 0; j <
size; ++
j)
4431 CGLTF_CHECK_KEY(tokens[i]);
4433 if (cgltf_json_strcmp(tokens + i, json_chunk,
"anisotropyStrength") == 0)
4439 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"anisotropyRotation") == 0)
4445 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"anisotropyTexture") == 0)
4447 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_anisotropy->
anisotropy_texture);
4451 i = cgltf_skip_json(tokens, i + 1);
4463 static int cgltf_parse_json_dispersion(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_dispersion* out_dispersion)
4465 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4466 int size = tokens[i].size;
4470 for (
int j = 0; j <
size; ++
j)
4472 CGLTF_CHECK_KEY(tokens[i]);
4474 if (cgltf_json_strcmp(tokens + i, json_chunk,
"dispersion") == 0)
4477 out_dispersion->
dispersion = cgltf_json_to_float(tokens + i, json_chunk);
4482 i = cgltf_skip_json(tokens, i + 1);
4494 static int cgltf_parse_json_image(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_image* out_image)
4496 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4498 int size = tokens[i].size;
4501 for (
int j = 0; j <
size; ++
j)
4503 CGLTF_CHECK_KEY(tokens[i]);
4505 if (cgltf_json_strcmp(tokens + i, json_chunk,
"uri") == 0)
4507 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->
uri);
4509 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
4515 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"mimeType") == 0)
4517 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->
mime_type);
4519 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4521 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->
name);
4523 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4525 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_image->
extras);
4527 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4529 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_image->
extensions_count, &out_image->
extensions);
4533 i = cgltf_skip_json(tokens, i + 1);
4545 static int cgltf_parse_json_sampler(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_sampler* out_sampler)
4548 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4553 int size = tokens[i].size;
4556 for (
int j = 0; j <
size; ++
j)
4558 CGLTF_CHECK_KEY(tokens[i]);
4560 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4562 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_sampler->
name);
4564 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"magFilter") == 0)
4571 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"minFilter") == 0)
4578 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"wrapS") == 0)
4585 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"wrapT") == 0)
4592 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4594 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sampler->
extras);
4596 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4598 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->
extensions_count, &out_sampler->
extensions);
4602 i = cgltf_skip_json(tokens, i + 1);
4614 static int cgltf_parse_json_texture(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_texture* out_texture)
4616 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4618 int size = tokens[i].size;
4621 for (
int j = 0; j <
size; ++
j)
4623 CGLTF_CHECK_KEY(tokens[i]);
4625 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4627 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_texture->
name);
4629 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"sampler") == 0)
4632 out_texture->
sampler = CGLTF_PTRINDEX(
cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk));
4635 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"source") == 0)
4638 out_texture->
image = CGLTF_PTRINDEX(
cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
4641 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4643 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_texture->
extras);
4645 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4649 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4652 return CGLTF_ERROR_JSON;
4655 int extensions_size = tokens[i].size;
4662 return CGLTF_ERROR_NOMEM;
4665 for (
int k = 0; k < extensions_size; ++k)
4667 CGLTF_CHECK_KEY(tokens[i]);
4669 if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_texture_basisu") == 0)
4673 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4674 int num_properties = tokens[i].size;
4677 for (
int t = 0;
t < num_properties; ++
t)
4679 CGLTF_CHECK_KEY(tokens[i]);
4681 if (cgltf_json_strcmp(tokens + i, json_chunk,
"source") == 0)
4689 i = cgltf_skip_json(tokens, i + 1);
4697 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"EXT_texture_webp") == 0)
4701 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4702 int num_properties = tokens[i].size;
4705 for (
int t = 0;
t < num_properties; ++
t)
4707 CGLTF_CHECK_KEY(tokens[i]);
4709 if (cgltf_json_strcmp(tokens + i, json_chunk,
"source") == 0)
4717 i = cgltf_skip_json(tokens, i + 1);
4727 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture->
extensions[out_texture->
extensions_count++]));
4738 i = cgltf_skip_json(tokens, i + 1);
4750 static int cgltf_parse_json_material(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_material* out_material)
4752 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4767 int size = tokens[i].size;
4770 for (
int j = 0; j <
size; ++
j)
4772 CGLTF_CHECK_KEY(tokens[i]);
4774 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4776 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_material->
name);
4778 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"pbrMetallicRoughness") == 0)
4781 i = cgltf_parse_json_pbr_metallic_roughness(options, tokens, i + 1, json_chunk, &out_material->
pbr_metallic_roughness);
4783 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"emissiveFactor") == 0)
4785 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_material->
emissive_factor, 3);
4787 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"normalTexture") == 0)
4789 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4792 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"occlusionTexture") == 0)
4794 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4797 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"emissiveTexture") == 0)
4799 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4802 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"alphaMode") == 0)
4805 if (cgltf_json_strcmp(tokens + i, json_chunk,
"OPAQUE") == 0)
4809 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"MASK") == 0)
4813 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"BLEND") == 0)
4819 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"alphaCutoff") == 0)
4822 out_material->
alpha_cutoff = cgltf_json_to_float(tokens + i, json_chunk);
4825 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"doubleSided") == 0)
4829 cgltf_json_to_bool(tokens + i, json_chunk);
4832 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4834 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_material->
extras);
4836 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4840 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4843 return CGLTF_ERROR_JSON;
4846 int extensions_size = tokens[i].size;
4853 return CGLTF_ERROR_NOMEM;
4856 for (
int k = 0; k < extensions_size; ++k)
4858 CGLTF_CHECK_KEY(tokens[i]);
4860 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_pbrSpecularGlossiness") == 0)
4863 i = cgltf_parse_json_pbr_specular_glossiness(options, tokens, i + 1, json_chunk, &out_material->
pbr_specular_glossiness);
4865 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_unlit") == 0)
4867 out_material->
unlit = 1;
4868 i = cgltf_skip_json(tokens, i+1);
4870 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_clearcoat") == 0)
4873 i = cgltf_parse_json_clearcoat(options, tokens, i + 1, json_chunk, &out_material->
clearcoat);
4875 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_ior") == 0)
4878 i = cgltf_parse_json_ior(tokens, i + 1, json_chunk, &out_material->
ior);
4880 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_specular") == 0)
4883 i = cgltf_parse_json_specular(options, tokens, i + 1, json_chunk, &out_material->
specular);
4885 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_transmission") == 0)
4888 i = cgltf_parse_json_transmission(options, tokens, i + 1, json_chunk, &out_material->
transmission);
4890 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_volume") == 0)
4893 i = cgltf_parse_json_volume(options, tokens, i + 1, json_chunk, &out_material->
volume);
4895 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_sheen") == 0)
4898 i = cgltf_parse_json_sheen(options, tokens, i + 1, json_chunk, &out_material->
sheen);
4900 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_emissive_strength") == 0)
4903 i = cgltf_parse_json_emissive_strength(tokens, i + 1, json_chunk, &out_material->
emissive_strength);
4905 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_iridescence") == 0)
4908 i = cgltf_parse_json_iridescence(options, tokens, i + 1, json_chunk, &out_material->
iridescence);
4910 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_diffuse_transmission") == 0)
4913 i = cgltf_parse_json_diffuse_transmission(options, tokens, i + 1, json_chunk, &out_material->
diffuse_transmission);
4915 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_anisotropy") == 0)
4918 i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->
anisotropy);
4920 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_dispersion") == 0)
4923 i = cgltf_parse_json_dispersion(tokens, i + 1, json_chunk, &out_material->
dispersion);
4927 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->
extensions[out_material->
extensions_count++]));
4938 i = cgltf_skip_json(tokens, i+1);
4950 static int cgltf_parse_json_accessors(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4960 i = cgltf_parse_json_accessor(options, tokens, i, json_chunk, &out_data->
accessors[j]);
4969 static int cgltf_parse_json_materials(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4979 i = cgltf_parse_json_material(options, tokens, i, json_chunk, &out_data->
materials[j]);
4988 static int cgltf_parse_json_images(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4998 i = cgltf_parse_json_image(options, tokens, i, json_chunk, &out_data->
images[j]);
5007 static int cgltf_parse_json_textures(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5017 i = cgltf_parse_json_texture(options, tokens, i, json_chunk, &out_data->
textures[j]);
5026 static int cgltf_parse_json_samplers(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5036 i = cgltf_parse_json_sampler(options, tokens, i, json_chunk, &out_data->
samplers[j]);
5048 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5050 int size = tokens[i].size;
5053 for (
int j = 0; j <
size; ++
j)
5055 CGLTF_CHECK_KEY(tokens[i]);
5057 if (cgltf_json_strcmp(tokens+i, json_chunk,
"buffer") == 0)
5060 out_meshopt_compression->
buffer = CGLTF_PTRINDEX(
cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
5063 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
5066 out_meshopt_compression->
offset = cgltf_json_to_size(tokens+i, json_chunk);
5069 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
5072 out_meshopt_compression->
size = cgltf_json_to_size(tokens+i, json_chunk);
5075 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteStride") == 0)
5078 out_meshopt_compression->
stride = cgltf_json_to_size(tokens+i, json_chunk);
5081 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
5084 out_meshopt_compression->
count = cgltf_json_to_size(tokens+i, json_chunk);
5087 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"mode") == 0)
5090 if (cgltf_json_strcmp(tokens+i, json_chunk,
"ATTRIBUTES") == 0)
5094 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"TRIANGLES") == 0)
5098 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"INDICES") == 0)
5104 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"filter") == 0)
5107 if (cgltf_json_strcmp(tokens+i, json_chunk,
"NONE") == 0)
5111 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"OCTAHEDRAL") == 0)
5115 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"QUATERNION") == 0)
5119 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"EXPONENTIAL") == 0)
5123 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"COLOR") == 0)
5131 i = cgltf_skip_json(tokens, i+1);
5143 static int cgltf_parse_json_buffer_view(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_buffer_view* out_buffer_view)
5145 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5147 int size = tokens[i].size;
5150 for (
int j = 0; j <
size; ++
j)
5152 CGLTF_CHECK_KEY(tokens[i]);
5154 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
5156 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer_view->
name);
5158 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"buffer") == 0)
5161 out_buffer_view->
buffer = CGLTF_PTRINDEX(
cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
5164 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
5167 out_buffer_view->
offset =
5168 cgltf_json_to_size(tokens+i, json_chunk);
5171 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
5174 out_buffer_view->
size =
5175 cgltf_json_to_size(tokens+i, json_chunk);
5178 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteStride") == 0)
5181 out_buffer_view->
stride =
5182 cgltf_json_to_size(tokens+i, json_chunk);
5185 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"target") == 0)
5188 int type = cgltf_json_to_int(tokens+i, json_chunk);
5204 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5206 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_buffer_view->
extras);
5208 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5212 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5215 return CGLTF_ERROR_JSON;
5218 int extensions_size = tokens[i].size;
5224 return CGLTF_ERROR_NOMEM;
5228 for (
int k = 0; k < extensions_size; ++k)
5230 CGLTF_CHECK_KEY(tokens[i]);
5232 if (cgltf_json_strcmp(tokens+i, json_chunk,
"EXT_meshopt_compression") == 0)
5235 i = cgltf_parse_json_meshopt_compression(options, tokens, i + 1, json_chunk, &out_buffer_view->
meshopt_compression);
5237 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_meshopt_compression") == 0)
5241 i = cgltf_parse_json_meshopt_compression(options, tokens, i + 1, json_chunk, &out_buffer_view->
meshopt_compression);
5245 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_buffer_view->
extensions[out_buffer_view->
extensions_count++]));
5256 i = cgltf_skip_json(tokens, i+1);
5268 static int cgltf_parse_json_buffer_views(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5278 i = cgltf_parse_json_buffer_view(options, tokens, i, json_chunk, &out_data->
buffer_views[j]);
5287 static int cgltf_parse_json_buffer(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_buffer* out_buffer)
5289 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5291 int size = tokens[i].size;
5294 for (
int j = 0; j <
size; ++
j)
5296 CGLTF_CHECK_KEY(tokens[i]);
5298 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
5300 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->
name);
5302 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
5306 cgltf_json_to_size(tokens+i, json_chunk);
5309 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"uri") == 0)
5311 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->
uri);
5313 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5315 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_buffer->
extras);
5317 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5319 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_buffer->
extensions_count, &out_buffer->
extensions);
5323 i = cgltf_skip_json(tokens, i+1);
5335 static int cgltf_parse_json_buffers(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5345 i = cgltf_parse_json_buffer(options, tokens, i, json_chunk, &out_data->
buffers[j]);
5354 static int cgltf_parse_json_skin(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_skin* out_skin)
5356 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5358 int size = tokens[i].size;
5361 for (
int j = 0; j <
size; ++
j)
5363 CGLTF_CHECK_KEY(tokens[i]);
5365 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5367 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_skin->
name);
5369 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"joints") == 0)
5371 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_node*), (
void**)&out_skin->
joints, &out_skin->
joints_count);
5377 for (cgltf_size k = 0; k < out_skin->
joints_count; ++k)
5379 out_skin->
joints[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5383 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"skeleton") == 0)
5386 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5387 out_skin->
skeleton = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5390 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"inverseBindMatrices") == 0)
5393 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5397 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5399 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_skin->
extras);
5401 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5403 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_skin->
extensions_count, &out_skin->
extensions);
5407 i = cgltf_skip_json(tokens, i+1);
5419 static int cgltf_parse_json_skins(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5421 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_skin), (
void**)&out_data->
skins, &out_data->
skins_count);
5429 i = cgltf_parse_json_skin(options, tokens, i, json_chunk, &out_data->
skins[j]);
5438 static int cgltf_parse_json_camera(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_camera* out_camera)
5440 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5442 int size = tokens[i].size;
5445 for (
int j = 0; j <
size; ++
j)
5447 CGLTF_CHECK_KEY(tokens[i]);
5449 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5451 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_camera->
name);
5453 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"perspective") == 0)
5457 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5459 int data_size = tokens[i].size;
5464 return CGLTF_ERROR_JSON;
5469 for (
int k = 0; k < data_size; ++k)
5471 CGLTF_CHECK_KEY(tokens[i]);
5473 if (cgltf_json_strcmp(tokens+i, json_chunk,
"aspectRatio") == 0)
5480 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"yfov") == 0)
5486 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"zfar") == 0)
5493 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"znear") == 0)
5499 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5501 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_camera->
data.
perspective.
extras);
5505 i = cgltf_skip_json(tokens, i+1);
5514 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"orthographic") == 0)
5518 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5520 int data_size = tokens[i].size;
5525 return CGLTF_ERROR_JSON;
5530 for (
int k = 0; k < data_size; ++k)
5532 CGLTF_CHECK_KEY(tokens[i]);
5534 if (cgltf_json_strcmp(tokens+i, json_chunk,
"xmag") == 0)
5540 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"ymag") == 0)
5546 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"zfar") == 0)
5552 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"znear") == 0)
5558 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5564 i = cgltf_skip_json(tokens, i+1);
5573 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5575 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_camera->
extras);
5577 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5579 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_camera->
extensions_count, &out_camera->
extensions);
5583 i = cgltf_skip_json(tokens, i+1);
5595 static int cgltf_parse_json_cameras(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5605 i = cgltf_parse_json_camera(options, tokens, i, json_chunk, &out_data->
cameras[j]);
5614 static int cgltf_parse_json_light(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_light* out_light)
5616 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5618 out_light->
color[0] = 1.f;
5619 out_light->
color[1] = 1.f;
5620 out_light->
color[2] = 1.f;
5626 int size = tokens[i].size;
5629 for (
int j = 0; j <
size; ++
j)
5631 CGLTF_CHECK_KEY(tokens[i]);
5633 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5635 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_light->
name);
5637 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"color") == 0)
5639 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_light->
color, 3);
5641 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"intensity") == 0)
5644 out_light->
intensity = cgltf_json_to_float(tokens + i, json_chunk);
5647 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
5650 if (cgltf_json_strcmp(tokens + i, json_chunk,
"directional") == 0)
5654 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"point") == 0)
5658 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"spot") == 0)
5664 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"range") == 0)
5667 out_light->
range = cgltf_json_to_float(tokens + i, json_chunk);
5670 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"spot") == 0)
5674 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5676 int data_size = tokens[i].size;
5679 for (
int k = 0; k < data_size; ++k)
5681 CGLTF_CHECK_KEY(tokens[i]);
5683 if (cgltf_json_strcmp(tokens+i, json_chunk,
"innerConeAngle") == 0)
5689 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"outerConeAngle") == 0)
5697 i = cgltf_skip_json(tokens, i+1);
5706 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5708 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_light->
extras);
5712 i = cgltf_skip_json(tokens, i+1);
5724 static int cgltf_parse_json_lights(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5734 i = cgltf_parse_json_light(options, tokens, i, json_chunk, &out_data->
lights[j]);
5743 static int cgltf_parse_json_node(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_node* out_node)
5745 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5748 out_node->
scale[0] = 1.0f;
5749 out_node->
scale[1] = 1.0f;
5750 out_node->
scale[2] = 1.0f;
5751 out_node->
matrix[0] = 1.0f;
5752 out_node->
matrix[5] = 1.0f;
5753 out_node->
matrix[10] = 1.0f;
5754 out_node->
matrix[15] = 1.0f;
5756 int size = tokens[i].size;
5759 for (
int j = 0; j <
size; ++
j)
5761 CGLTF_CHECK_KEY(tokens[i]);
5763 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5765 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_node->
name);
5767 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"children") == 0)
5777 out_node->
children[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5781 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"mesh") == 0)
5784 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5785 out_node->
mesh = CGLTF_PTRINDEX(
cgltf_mesh, cgltf_json_to_int(tokens + i, json_chunk));
5788 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"skin") == 0)
5791 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5792 out_node->
skin = CGLTF_PTRINDEX(
cgltf_skin, cgltf_json_to_int(tokens + i, json_chunk));
5795 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"camera") == 0)
5798 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5799 out_node->
camera = CGLTF_PTRINDEX(
cgltf_camera, cgltf_json_to_int(tokens + i, json_chunk));
5802 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"translation") == 0)
5805 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->
translation, 3);
5807 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"rotation") == 0)
5810 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->
rotation, 4);
5812 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"scale") == 0)
5815 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->
scale, 3);
5817 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"matrix") == 0)
5820 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->
matrix, 16);
5822 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"weights") == 0)
5830 i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_node->
weights, (
int)out_node->
weights_count);
5832 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5834 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_node->
extras);
5836 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5840 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5843 return CGLTF_ERROR_JSON;
5846 int extensions_size = tokens[i].size;
5852 return CGLTF_ERROR_NOMEM;
5857 for (
int k = 0; k < extensions_size; ++k)
5859 CGLTF_CHECK_KEY(tokens[i]);
5861 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_lights_punctual") == 0)
5865 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5867 int data_size = tokens[i].size;
5870 for (
int m = 0; m < data_size; ++m)
5872 CGLTF_CHECK_KEY(tokens[i]);
5874 if (cgltf_json_strcmp(tokens + i, json_chunk,
"light") == 0)
5877 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5878 out_node->
light = CGLTF_PTRINDEX(
cgltf_light, cgltf_json_to_int(tokens + i, json_chunk));
5883 i = cgltf_skip_json(tokens, i + 1);
5892 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"EXT_mesh_gpu_instancing") == 0)
5895 i = cgltf_parse_json_mesh_gpu_instancing(options, tokens, i + 1, json_chunk, &out_node->
mesh_gpu_instancing);
5899 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_node->
extensions[out_node->
extensions_count++]));
5910 i = cgltf_skip_json(tokens, i+1);
5922 static int cgltf_parse_json_nodes(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5924 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_node), (
void**)&out_data->
nodes, &out_data->
nodes_count);
5932 i = cgltf_parse_json_node(options, tokens, i, json_chunk, &out_data->
nodes[j]);
5941 static int cgltf_parse_json_scene(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_scene* out_scene)
5943 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5945 int size = tokens[i].size;
5948 for (
int j = 0; j <
size; ++
j)
5950 CGLTF_CHECK_KEY(tokens[i]);
5952 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5954 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_scene->
name);
5956 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"nodes") == 0)
5958 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_node*), (
void**)&out_scene->
nodes, &out_scene->
nodes_count);
5964 for (cgltf_size k = 0; k < out_scene->
nodes_count; ++k)
5966 out_scene->
nodes[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5970 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5972 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_scene->
extras);
5974 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5976 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_scene->
extensions_count, &out_scene->
extensions);
5980 i = cgltf_skip_json(tokens, i+1);
5992 static int cgltf_parse_json_scenes(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
6002 i = cgltf_parse_json_scene(options, tokens, i, json_chunk, &out_data->
scenes[j]);
6014 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6016 int size = tokens[i].size;
6019 for (
int j = 0; j <
size; ++
j)
6021 CGLTF_CHECK_KEY(tokens[i]);
6023 if (cgltf_json_strcmp(tokens+i, json_chunk,
"input") == 0)
6026 out_sampler->
input = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
6029 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"output") == 0)
6032 out_sampler->
output = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
6035 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"interpolation") == 0)
6038 if (cgltf_json_strcmp(tokens + i, json_chunk,
"LINEAR") == 0)
6042 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"STEP") == 0)
6046 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"CUBICSPLINE") == 0)
6052 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
6054 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sampler->
extras);
6056 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
6058 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->
extensions_count, &out_sampler->
extensions);
6062 i = cgltf_skip_json(tokens, i+1);
6077 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6079 int size = tokens[i].size;
6082 for (
int j = 0; j <
size; ++
j)
6084 CGLTF_CHECK_KEY(tokens[i]);
6086 if (cgltf_json_strcmp(tokens+i, json_chunk,
"sampler") == 0)
6092 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"target") == 0)
6096 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6098 int target_size = tokens[i].size;
6101 for (
int k = 0; k < target_size; ++k)
6103 CGLTF_CHECK_KEY(tokens[i]);
6105 if (cgltf_json_strcmp(tokens+i, json_chunk,
"node") == 0)
6111 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"path") == 0)
6114 if (cgltf_json_strcmp(tokens+i, json_chunk,
"translation") == 0)
6118 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"rotation") == 0)
6122 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"scale") == 0)
6126 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"weights") == 0)
6132 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
6134 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_channel->
extras);
6136 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
6138 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_channel->
extensions_count, &out_channel->
extensions);
6142 i = cgltf_skip_json(tokens, i+1);
6153 i = cgltf_skip_json(tokens, i+1);
6165 static int cgltf_parse_json_animation(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_animation* out_animation)
6167 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6169 int size = tokens[i].size;
6172 for (
int j = 0; j <
size; ++
j)
6174 CGLTF_CHECK_KEY(tokens[i]);
6176 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
6178 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_animation->
name);
6180 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"samplers") == 0)
6190 i = cgltf_parse_json_animation_sampler(options, tokens, i, json_chunk, &out_animation->
samplers[k]);
6197 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"channels") == 0)
6207 i = cgltf_parse_json_animation_channel(options, tokens, i, json_chunk, &out_animation->
channels[k]);
6214 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
6216 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_animation->
extras);
6218 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
6220 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_animation->
extensions_count, &out_animation->
extensions);
6224 i = cgltf_skip_json(tokens, i+1);
6236 static int cgltf_parse_json_animations(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
6246 i = cgltf_parse_json_animation(options, tokens, i, json_chunk, &out_data->
animations[j]);
6257 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6259 int size = tokens[i].size;
6262 for (
int j = 0; j <
size; ++
j)
6264 CGLTF_CHECK_KEY(tokens[i]);
6266 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
6268 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_variant->
name);
6270 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
6272 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_variant->
extras);
6276 i = cgltf_skip_json(tokens, i+1);
6288 static int cgltf_parse_json_variants(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
6298 i = cgltf_parse_json_variant(options, tokens, i, json_chunk, &out_data->
variants[j]);
6307 static int cgltf_parse_json_asset(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_asset* out_asset)
6309 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6311 int size = tokens[i].size;
6314 for (
int j = 0; j <
size; ++
j)
6316 CGLTF_CHECK_KEY(tokens[i]);
6318 if (cgltf_json_strcmp(tokens+i, json_chunk,
"copyright") == 0)
6320 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->
copyright);
6322 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"generator") == 0)
6324 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->
generator);
6326 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"version") == 0)
6328 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->
version);
6330 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"minVersion") == 0)
6332 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->
min_version);
6334 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
6336 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_asset->
extras);
6338 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
6340 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_asset->
extensions_count, &out_asset->
extensions);
6344 i = cgltf_skip_json(tokens, i+1);
6355 return CGLTF_ERROR_LEGACY;
6384 switch (component_type)
6406 return 8 * component_size;
6408 else if (type ==
cgltf_type_mat3 && (component_size == 1 || component_size == 2))
6410 return 12 * component_size;
6415 static int cgltf_fixup_pointers(
cgltf_data* out_data);
6417 static int cgltf_parse_json_root(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
6419 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6421 int size = tokens[i].size;
6424 for (
int j = 0; j <
size; ++
j)
6426 CGLTF_CHECK_KEY(tokens[i]);
6428 if (cgltf_json_strcmp(tokens + i, json_chunk,
"asset") == 0)
6430 i = cgltf_parse_json_asset(options, tokens, i + 1, json_chunk, &out_data->
asset);
6432 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"meshes") == 0)
6434 i = cgltf_parse_json_meshes(options, tokens, i + 1, json_chunk, out_data);
6436 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"accessors") == 0)
6438 i = cgltf_parse_json_accessors(options, tokens, i + 1, json_chunk, out_data);
6440 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"bufferViews") == 0)
6442 i = cgltf_parse_json_buffer_views(options, tokens, i + 1, json_chunk, out_data);
6444 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"buffers") == 0)
6446 i = cgltf_parse_json_buffers(options, tokens, i + 1, json_chunk, out_data);
6448 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"materials") == 0)
6450 i = cgltf_parse_json_materials(options, tokens, i + 1, json_chunk, out_data);
6452 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"images") == 0)
6454 i = cgltf_parse_json_images(options, tokens, i + 1, json_chunk, out_data);
6456 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"textures") == 0)
6458 i = cgltf_parse_json_textures(options, tokens, i + 1, json_chunk, out_data);
6460 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"samplers") == 0)
6462 i = cgltf_parse_json_samplers(options, tokens, i + 1, json_chunk, out_data);
6464 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"skins") == 0)
6466 i = cgltf_parse_json_skins(options, tokens, i + 1, json_chunk, out_data);
6468 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"cameras") == 0)
6470 i = cgltf_parse_json_cameras(options, tokens, i + 1, json_chunk, out_data);
6472 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"nodes") == 0)
6474 i = cgltf_parse_json_nodes(options, tokens, i + 1, json_chunk, out_data);
6476 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scenes") == 0)
6478 i = cgltf_parse_json_scenes(options, tokens, i + 1, json_chunk, out_data);
6480 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scene") == 0)
6483 out_data->
scene = CGLTF_PTRINDEX(
cgltf_scene, cgltf_json_to_int(tokens + i, json_chunk));
6486 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"animations") == 0)
6488 i = cgltf_parse_json_animations(options, tokens, i + 1, json_chunk, out_data);
6490 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"extras") == 0)
6492 i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_data->
extras);
6494 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
6498 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6501 return CGLTF_ERROR_JSON;
6504 int extensions_size = tokens[i].size;
6510 return CGLTF_ERROR_NOMEM;
6515 for (
int k = 0; k < extensions_size; ++k)
6517 CGLTF_CHECK_KEY(tokens[i]);
6519 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_lights_punctual") == 0)
6523 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6525 int data_size = tokens[i].size;
6528 for (
int m = 0; m < data_size; ++m)
6530 CGLTF_CHECK_KEY(tokens[i]);
6532 if (cgltf_json_strcmp(tokens + i, json_chunk,
"lights") == 0)
6534 i = cgltf_parse_json_lights(options, tokens, i + 1, json_chunk, out_data);
6538 i = cgltf_skip_json(tokens, i + 1);
6547 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_variants") == 0)
6551 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
6553 int data_size = tokens[i].size;
6556 for (
int m = 0; m < data_size; ++m)
6558 CGLTF_CHECK_KEY(tokens[i]);
6560 if (cgltf_json_strcmp(tokens + i, json_chunk,
"variants") == 0)
6562 i = cgltf_parse_json_variants(options, tokens, i + 1, json_chunk, out_data);
6566 i = cgltf_skip_json(tokens, i + 1);
6586 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensionsUsed") == 0)
6590 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensionsRequired") == 0)
6596 i = cgltf_skip_json(tokens, i + 1);
6610 jsmn_parser parser = { 0, 0, 0 };
6614 int token_count = jsmn_parse(&parser, (
const char*)json_chunk, size, NULL, 0);
6616 if (token_count <= 0)
6633 int token_count = jsmn_parse(&parser, (
const char*)json_chunk, size, tokens, options->
json_token_count);
6635 if (token_count <= 0)
6643 tokens[token_count].type = JSMN_UNDEFINED;
6657 int i = cgltf_parse_json_root(options, tokens, 0, json_chunk, data);
6673 if (cgltf_fixup_pointers(data) < 0)
6679 data->
json = (
const char*)json_chunk;
6687 static int cgltf_fixup_pointers(
cgltf_data* data)
6804 for (cgltf_size i = 0; i < data->
skins_count; ++i)
6815 for (cgltf_size i = 0; i < data->
nodes_count; ++i)
6823 return CGLTF_ERROR_JSON;
6851 return CGLTF_ERROR_JSON;
6905 static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
6906 jsmntok_t *tokens,
size_t num_tokens) {
6908 if (parser->toknext >= num_tokens) {
6911 tok = &tokens[parser->toknext++];
6912 tok->start = tok->end = -1;
6914 #ifdef JSMN_PARENT_LINKS
6923 static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
6924 ptrdiff_t start, ptrdiff_t end) {
6926 token->start =
start;
6934 static int jsmn_parse_primitive(jsmn_parser *parser,
const char *js,
6935 size_t len, jsmntok_t *tokens,
size_t num_tokens) {
6939 start = parser->pos;
6941 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
6942 switch (js[parser->pos]) {
6947 case '\t' :
case '\r' :
case '\n' :
case ' ' :
6948 case ',' :
case ']' :
case '}' :
6951 if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
6952 parser->pos =
start;
6953 return JSMN_ERROR_INVAL;
6958 parser->pos =
start;
6959 return JSMN_ERROR_PART;
6963 if (tokens == NULL) {
6967 token = jsmn_alloc_token(parser, tokens, num_tokens);
6968 if (token == NULL) {
6969 parser->pos =
start;
6970 return JSMN_ERROR_NOMEM;
6972 jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
6973 #ifdef JSMN_PARENT_LINKS
6974 token->parent = parser->toksuper;
6983 static int jsmn_parse_string(jsmn_parser *parser,
const char *js,
6984 size_t len, jsmntok_t *tokens,
size_t num_tokens) {
6987 ptrdiff_t start = parser->pos;
6992 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
6993 char c = js[parser->pos];
6997 if (tokens == NULL) {
7000 token = jsmn_alloc_token(parser, tokens, num_tokens);
7001 if (token == NULL) {
7002 parser->pos =
start;
7003 return JSMN_ERROR_NOMEM;
7005 jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
7006 #ifdef JSMN_PARENT_LINKS
7007 token->parent = parser->toksuper;
7013 if (c ==
'\\' && parser->pos + 1 < len) {
7016 switch (js[parser->pos]) {
7018 case '\"':
case '/' :
case '\\' :
case 'b' :
7019 case 'f' :
case 'r' :
case 'n' :
case 't' :
7024 for(i = 0; i < 4 && parser->pos < len && js[parser->pos] !=
'\0'; i++) {
7026 if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) ||
7027 (js[parser->pos] >= 65 && js[parser->pos] <= 70) ||
7028 (js[parser->pos] >= 97 && js[parser->pos] <= 102))) {
7029 parser->pos =
start;
7030 return JSMN_ERROR_INVAL;
7038 parser->pos =
start;
7039 return JSMN_ERROR_INVAL;
7043 parser->pos =
start;
7044 return JSMN_ERROR_PART;
7050 static int jsmn_parse(jsmn_parser *parser,
const char *js,
size_t len,
7051 jsmntok_t *tokens,
size_t num_tokens) {
7055 int count = parser->toknext;
7057 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
7061 c = js[parser->pos];
7065 if (tokens == NULL) {
7068 token = jsmn_alloc_token(parser, tokens, num_tokens);
7070 return JSMN_ERROR_NOMEM;
7071 if (parser->toksuper != -1) {
7072 tokens[parser->toksuper].size++;
7073 #ifdef JSMN_PARENT_LINKS
7074 token->parent = parser->toksuper;
7077 token->type = (c ==
'{' ? JSMN_OBJECT : JSMN_ARRAY);
7078 token->start = parser->pos;
7079 parser->toksuper = parser->toknext - 1;
7084 type = (c ==
'}' ? JSMN_OBJECT : JSMN_ARRAY);
7085 #ifdef JSMN_PARENT_LINKS
7086 if (parser->toknext < 1) {
7087 return JSMN_ERROR_INVAL;
7089 token = &tokens[parser->toknext - 1];
7091 if (token->start != -1 && token->end == -1) {
7092 if (token->type != type) {
7093 return JSMN_ERROR_INVAL;
7095 token->end = parser->pos + 1;
7096 parser->toksuper = token->parent;
7099 if (token->parent == -1) {
7100 if(token->type != type || parser->toksuper == -1) {
7101 return JSMN_ERROR_INVAL;
7105 token = &tokens[token->parent];
7108 for (i = parser->toknext - 1; i >= 0; i--) {
7110 if (token->start != -1 && token->end == -1) {
7111 if (token->type != type) {
7112 return JSMN_ERROR_INVAL;
7114 parser->toksuper = -1;
7115 token->end = parser->pos + 1;
7120 if (i == -1)
return JSMN_ERROR_INVAL;
7121 for (; i >= 0; i--) {
7123 if (token->start != -1 && token->end == -1) {
7124 parser->toksuper = i;
7131 r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
7132 if (r < 0)
return r;
7134 if (parser->toksuper != -1 && tokens != NULL)
7135 tokens[parser->toksuper].size++;
7137 case '\t' :
case '\r' :
case '\n' :
case ' ':
7140 parser->toksuper = parser->toknext - 1;
7143 if (tokens != NULL && parser->toksuper != -1 &&
7144 tokens[parser->toksuper].type != JSMN_ARRAY &&
7145 tokens[parser->toksuper].type != JSMN_OBJECT) {
7146 #ifdef JSMN_PARENT_LINKS
7147 parser->toksuper = tokens[parser->toksuper].parent;
7149 for (i = parser->toknext - 1; i >= 0; i--) {
7150 if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
7151 if (tokens[i].start != -1 && tokens[i].end == -1) {
7152 parser->toksuper = i;
7162 case '-':
case '0':
case '1' :
case '2':
case '3' :
case '4':
7163 case '5':
case '6':
case '7' :
case '8':
case '9':
7164 case 't':
case 'f':
case 'n' :
7166 if (tokens != NULL && parser->toksuper != -1) {
7167 jsmntok_t *
t = &tokens[parser->toksuper];
7168 if (t->type == JSMN_OBJECT ||
7169 (t->type == JSMN_STRING && t->size != 0)) {
7170 return JSMN_ERROR_INVAL;
7177 r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
7178 if (r < 0)
return r;
7180 if (parser->toksuper != -1 && tokens != NULL)
7181 tokens[parser->toksuper].size++;
7187 return JSMN_ERROR_INVAL;
7192 if (tokens != NULL) {
7193 for (i = parser->toknext - 1; i >= 0; i--) {
7195 if (tokens[i].start != -1 && tokens[i].end == -1) {
7196 return JSMN_ERROR_PART;
7208 static void jsmn_init(jsmn_parser *parser) {
7210 parser->toknext = 0;
7211 parser->toksuper = -1;
cgltf_extension * extensions
cgltf_size cgltf_decode_string(char *string)
struct cgltf_light cgltf_light
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
cgltf_material * materials
cgltf_extension * extensions
cgltf_size extensions_count
cgltf_texture_view emissive_texture
GLsizei GLenum const void * indices
struct cgltf_scene cgltf_scene
cgltf_component_type component_type
void(* free_func)(void *user, void *ptr)
cgltf_material_mapping * mappings
cgltf_bool has_emissive_strength
cgltf_extension * extensions
cgltf_size animations_count
cgltf_bool has_pbr_specular_glossiness
cgltf_size target_names_count
cgltf_extension * extensions
struct cgltf_asset cgltf_asset
struct cgltf_image cgltf_image
struct cgltf_diffuse_transmission cgltf_diffuse_transmission
long long int cgltf_ssize
cgltf_texture_view occlusion_texture
cgltf_material_variant * variants
cgltf_camera_perspective perspective
cgltf_attribute * attributes
cgltf_bool has_meshopt_compression
cgltf_bool has_iridescence
struct cgltf_morph_target cgltf_morph_target
struct cgltf_meshopt_compression cgltf_meshopt_compression
cgltf_texture_view specular_color_texture
cgltf_size cgltf_camera_index(const cgltf_data *data, const cgltf_camera *object)
cgltf_texture_view iridescence_texture
cgltf_texture_view clearcoat_roughness_texture
cgltf_float iridescence_ior
struct cgltf_anisotropy cgltf_anisotropy
cgltf_float glossiness_factor
cgltf_extension * extensions
GLsizei const GLchar *const * string
GLsizei const GLfloat * value
struct cgltf_texture cgltf_texture
cgltf_size channels_count
cgltf_buffer_view_type type
GLsizei const GLchar *const * path
struct cgltf_iridescence cgltf_iridescence
cgltf_size cgltf_num_components(cgltf_type type)
cgltf_animation_path_type target_path
cgltf_result cgltf_copy_extras_json(const cgltf_data *data, const cgltf_extras *extras, char *dest, cgltf_size *dest_size)
cgltf_size extensions_count
cgltf_texture_view transmission_texture
cgltf_primitive * primitives
cgltf_buffer_view * values_buffer_view
struct cgltf_skin cgltf_skin
cgltf_extension * extensions
cgltf_attribute * attributes
GLuint GLsizei GLsizei * length
cgltf_bool has_dispersion
cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor *accessor, cgltf_float *out, cgltf_size float_count)
cgltf_component_type indices_component_type
struct cgltf_texture_transform cgltf_texture_transform
cgltf_size extensions_count
cgltf_float transmission_factor
cgltf_float diffuse_transmission_color_factor[3]
cgltf_memory_options memory
struct cgltf_accessor cgltf_accessor
cgltf_size data_extensions_count
struct cgltf_data cgltf_data
**But if you need a result
struct cgltf_file_options cgltf_file_options
struct cgltf_clearcoat cgltf_clearcoat
cgltf_size extensions_count
struct cgltf_attribute cgltf_attribute
cgltf_size cgltf_buffer_view_index(const cgltf_data *data, const cgltf_buffer_view *object)
cgltf_result cgltf_load_buffer_base64(const cgltf_options *options, cgltf_size size, const char *base64, void **out_data)
cgltf_size cgltf_texture_index(const cgltf_data *data, const cgltf_texture *object)
cgltf_float iridescence_thickness_min
cgltf_size extensions_count
cgltf_meshopt_compression_filter
constexpr auto in(type t, int set) -> bool
cgltf_size cgltf_animation_index(const cgltf_data *data, const cgltf_animation *object)
cgltf_extension * extensions
cgltf_iridescence iridescence
cgltf_float clearcoat_roughness_factor
cgltf_float anisotropy_rotation
struct cgltf_animation_channel cgltf_animation_channel
struct cgltf_dispersion cgltf_dispersion
struct cgltf_extension cgltf_extension
cgltf_size extensions_used_count
cgltf_texture_view normal_texture
struct cgltf_accessor_sparse cgltf_accessor_sparse
cgltf_size attributes_count
cgltf_size cgltf_decode_uri(char *uri)
cgltf_size cgltf_accessor_read_index(const cgltf_accessor *accessor, cgltf_size index)
struct cgltf_pbr_metallic_roughness cgltf_pbr_metallic_roughness
cgltf_float spot_inner_cone_angle
cgltf_texture_view thickness_texture
cgltf_buffer_view * buffer_view
GLint GLint GLsizei GLint GLenum GLenum type
cgltf_float emissive_strength
cgltf_size mappings_count
cgltf_size cgltf_light_index(const cgltf_data *data, const cgltf_light *object)
cgltf_size extensions_count
cgltf_size values_byte_offset
cgltf_size primitives_count
struct cgltf_animation_sampler cgltf_animation_sampler
cgltf_float sheen_roughness_factor
cgltf_size extensions_count
struct cgltf_animation cgltf_animation
cgltf_camera_orthographic orthographic
struct cgltf_specular cgltf_specular
cgltf_float emissive_factor[3]
cgltf_size attributes_count
char ** extensions_required
cgltf_primitive_type type
cgltf_size cgltf_node_index(const cgltf_data *data, const cgltf_node *object)
OIIO_UTIL_API FILE * fopen(string_view path, string_view mode)
Version of fopen that can handle UTF-8 paths even on Windows.
cgltf_emissive_strength emissive_strength
cgltf_texture_view specular_texture
cgltf_animation * animations
cgltf_float iridescence_thickness_max
OIIO_UTIL_API uint64_t file_size(string_view path) noexcept
cgltf_meshopt_compression meshopt_compression
cgltf_result cgltf_parse(const cgltf_options *options, const void *data, cgltf_size size, cgltf_data **out_data)
cgltf_result cgltf_load_buffers(const cgltf_options *options, cgltf_data *data, const char *gltf_path)
cgltf_dispersion dispersion
cgltf_size indices_byte_offset
cgltf_meshopt_compression_mode
struct cgltf_transmission cgltf_transmission
cgltf_size cgltf_animation_channel_index(const cgltf_animation *animation, const cgltf_animation_channel *object)
cgltf_size cgltf_accessor_index(const cgltf_data *data, const cgltf_accessor *object)
void cgltf_free(cgltf_data *data)
cgltf_buffer_view * buffer_views
cgltf_bool cgltf_accessor_read_uint(const cgltf_accessor *accessor, cgltf_size index, cgltf_uint *out, cgltf_size element_size)
cgltf_texture_transform transform
cgltf_accessor_sparse sparse
struct cgltf_texture_view cgltf_texture_view
cgltf_float iridescence_factor
cgltf_extension * extensions
cgltf_size extensions_count
const cgltf_accessor * cgltf_find_accessor(const cgltf_primitive *prim, cgltf_attribute_type type, cgltf_int index)
cgltf_size buffer_views_count
cgltf_size cgltf_buffer_index(const cgltf_data *data, const cgltf_buffer *object)
struct cgltf_material cgltf_material
union cgltf_camera::@7 data
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor *accessor, void *out, cgltf_size out_component_size, cgltf_size index_count)
cgltf_size materials_count
cgltf_size extensions_required_count
cgltf_extension * extensions
cgltf_result(* read)(const struct cgltf_memory_options *memory_options, const struct cgltf_file_options *file_options, const char *path, cgltf_size *size, void **data)
GLuint const GLchar * name
cgltf_size accessors_count
cgltf_morph_target * targets
cgltf_extension * extensions
GLint GLenum GLboolean normalized
cgltf_texture_view anisotropy_texture
cgltf_size extensions_count
cgltf_size extensions_count
cgltf_material * material
struct cgltf_camera_perspective cgltf_camera_perspective
struct cgltf_ior cgltf_ior
cgltf_animation_path_type
cgltf_size samplers_count
cgltf_pbr_specular_glossiness pbr_specular_glossiness
cgltf_float attenuation_color[3]
cgltf_buffer_view * indices_buffer_view
cgltf_size cgltf_component_size(cgltf_component_type component_type)
cgltf_bool has_transmission
struct cgltf_pbr_specular_glossiness cgltf_pbr_specular_glossiness
cgltf_meshopt_compression_filter filter
cgltf_extension * extensions
GT_API const UT_StringHolder version
struct cgltf_buffer_view cgltf_buffer_view
cgltf_alpha_mode alpha_mode
struct cgltf_draco_mesh_compression cgltf_draco_mesh_compression
cgltf_size cgltf_scene_index(const cgltf_data *data, const cgltf_scene *object)
void *(* alloc_func)(void *user, cgltf_size size)
cgltf_size textures_count
cgltf_extension * extensions
__hostdev__ uint64_t last(uint32_t i) const
struct cgltf_primitive cgltf_primitive
cgltf_material * material
cgltf_texture_view specular_glossiness_texture
cgltf_texture_view sheen_roughness_texture
cgltf_bool has_mesh_gpu_instancing
cgltf_size cgltf_material_index(const cgltf_data *data, const cgltf_material *object)
OIIO_UTIL_API int fseek(FILE *file, int64_t offset, int whence)
void cgltf_node_transform_local(const cgltf_node *node, cgltf_float *out_matrix)
cgltf_diffuse_transmission diffuse_transmission
cgltf_size extensions_count
cgltf_anisotropy anisotropy
cgltf_extension * extensions
cgltf_size extensions_count
cgltf_data_free_method data_free_method
cgltf_result cgltf_parse_file(const cgltf_options *options, const char *path, cgltf_data **out_data)
cgltf_extension * extensions
cgltf_size extensions_count
cgltf_accessor * inverse_bind_matrices
cgltf_float anisotropy_strength
cgltf_size extensions_count
cgltf_filter_type min_filter
cgltf_texture_view diffuse_transmission_texture
cgltf_float clearcoat_factor
struct cgltf_mesh_gpu_instancing cgltf_mesh_gpu_instancing
cgltf_size cgltf_animation_sampler_index(const cgltf_animation *animation, const cgltf_animation_sampler *object)
cgltf_pbr_metallic_roughness pbr_metallic_roughness
struct cgltf_sampler cgltf_sampler
cgltf_size attributes_count
cgltf_bool has_anisotropy
GLenum GLsizei GLsizei GLint * values
cgltf_texture_view clearcoat_normal_texture
cgltf_attribute * attributes
cgltf_interpolation_type interpolation
cgltf_attribute * attributes
cgltf_animation_sampler * sampler
cgltf_animation_sampler * samplers
cgltf_animation_channel * channels
cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type)
cgltf_float specular_factor
cgltf_size samplers_count
cgltf_bool cgltf_accessor_read_float(const cgltf_accessor *accessor, cgltf_size index, cgltf_float *out, cgltf_size element_size)
cgltf_size cgltf_skin_index(const cgltf_data *data, const cgltf_skin *object)
cgltf_float spot_outer_cone_angle
cgltf_float diffuse_transmission_factor
cgltf_extension * data_extensions
cgltf_size cgltf_mesh_index(const cgltf_data *data, const cgltf_mesh *object)
OIIO_UTIL_API int64_t ftell(FILE *file)
Version of ftell that works with 64 bit offsets on all systems.
cgltf_memory_options memory
cgltf_draco_mesh_compression draco_mesh_compression
cgltf_result cgltf_validate(cgltf_data *data)
cgltf_texture_view iridescence_thickness_texture
cgltf_bool has_diffuse_transmission
cgltf_texture_view clearcoat_texture
cgltf_extension * extensions
cgltf_clearcoat clearcoat
cgltf_float diffuse_factor[4]
struct cgltf_material_mapping cgltf_material_mapping
cgltf_texture_view diffuse_transmission_color_texture
cgltf_image * basisu_image
cgltf_mesh_gpu_instancing mesh_gpu_instancing
struct cgltf_mesh cgltf_mesh
cgltf_transmission transmission
cgltf_texture_view diffuse_texture
struct cgltf_extras cgltf_extras
struct cgltf_sheen cgltf_sheen
const uint8_t * cgltf_buffer_view_data(const cgltf_buffer_view *view)
struct cgltf_options cgltf_options
struct cgltf_camera_orthographic cgltf_camera_orthographic
cgltf_bool has_draco_mesh_compression
cgltf_filter_type mag_filter
cgltf_buffer_view * buffer_view
cgltf_texture_view sheen_color_texture
cgltf_size cgltf_image_index(const cgltf_data *data, const cgltf_image *object)
cgltf_float thickness_factor
cgltf_file_type file_type
cgltf_float translation[3]
cgltf_bool has_pbr_metallic_roughness
cgltf_size extensions_count
cgltf_size attributes_count
cgltf_float specular_color_factor[3]
cgltf_float attenuation_distance
cgltf_extension * extensions
void write(T &out, bool v)
void cgltf_node_transform_world(const cgltf_node *node, cgltf_float *out_matrix)
cgltf_float sheen_color_factor[3]
cgltf_attribute_type type
cgltf_bool has_translation
struct cgltf_material_variant cgltf_material_variant
struct cgltf_buffer cgltf_buffer
cgltf_size variants_count
cgltf_bool has_aspect_ratio
struct cgltf_memory_options cgltf_memory_options
cgltf_buffer_view * buffer_view
cgltf_accessor * accessors
cgltf_size children_count
struct cgltf_camera cgltf_camera
OIIO_UTIL_API std::string extension(string_view filepath, bool include_dot=true) noexcept
struct cgltf_emissive_strength cgltf_emissive_strength
cgltf_size cgltf_sampler_index(const cgltf_data *data, const cgltf_sampler *object)
cgltf_size json_token_count
cgltf_size extensions_count
void(* release)(const struct cgltf_memory_options *memory_options, const struct cgltf_file_options *file_options, void *data, cgltf_size size)
cgltf_meshopt_compression_mode mode
cgltf_size extensions_count
cgltf_float specular_factor[3]
cgltf_extension * extensions
struct cgltf_volume cgltf_volume