92 #ifndef CGLTF_H_INCLUDED__
93 #define CGLTF_H_INCLUDED__
133 void* (*alloc_func)(
void* user, cgltf_size
size);
822 const char* gltf_path);
859 #if defined(__INTELLISENSE__) || defined(__JETBRAINS_IDE__)
861 #define CGLTF_IMPLEMENTATION
864 #ifdef CGLTF_IMPLEMENTATION
872 #if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF) || !defined(CGLTF_ATOLL)
876 #if CGLTF_VALIDATE_ENABLE_ASSERTS
881 #define JSMN_PARENT_LINKS
900 JSMN_ERROR_NOMEM = -1,
902 JSMN_ERROR_INVAL = -2,
911 #ifdef JSMN_PARENT_LINKS
917 unsigned int toknext;
920 static void jsmn_init(jsmn_parser *parser);
921 static int jsmn_parse(jsmn_parser *parser,
const char *js,
size_t len, jsmntok_t *tokens,
size_t num_tokens);
928 static const cgltf_size GlbChunkHeaderSize = 8;
929 static const uint32_t GlbVersion = 2;
930 static const uint32_t GlbMagic = 0x46546C67;
931 static const uint32_t GlbMagicJsonChunk = 0x4E4F534A;
932 static const uint32_t GlbMagicBinChunk = 0x004E4942;
935 #define CGLTF_MALLOC(size) malloc(size)
938 #define CGLTF_FREE(ptr) free(ptr)
941 #define CGLTF_ATOI(str) atoi(str)
944 #define CGLTF_ATOF(str) atof(str)
947 #define CGLTF_ATOLL(str) atoll(str)
949 #ifndef CGLTF_VALIDATE_ENABLE_ASSERTS
950 #define CGLTF_VALIDATE_ENABLE_ASSERTS 0
956 return CGLTF_MALLOC(size);
959 static void cgltf_default_free(
void* user,
void*
ptr)
967 if (SIZE_MAX / element_size < count)
976 memset(result, 0, element_size * count);
984 void (*memory_free)(
void*,
void*) = memory_options->
free_func ? memory_options->
free_func : &cgltf_default_free;
986 FILE* file =
fopen(path,
"rb");
999 __int64
length = _ftelli64(file);
1001 long length =
ftell(file);
1014 char* file_data = (
char*)memory_alloc(memory_options->
user_data, file_size);
1021 cgltf_size read_size = fread(file_data, 1, file_size, file);
1025 if (read_size != file_size)
1027 memory_free(memory_options->
user_data, file_data);
1046 void (*memfree)(
void*,
void*) = memory_options->
free_func ? memory_options->
free_func : &cgltf_default_free;
1047 memfree(memory_options->
user_data, data);
1054 if (size < GlbHeaderSize)
1059 if (options == NULL)
1076 memcpy(&tmp, data, 4);
1077 if (tmp != GlbMagic)
1091 cgltf_result json_result = cgltf_parse_json(&fixed_options, (
const uint8_t*)data, size, out_data);
1102 const uint8_t*
ptr = (
const uint8_t*)data;
1104 memcpy(&tmp, ptr + 4, 4);
1106 if (version != GlbVersion)
1112 memcpy(&tmp, ptr + 8, 4);
1118 const uint8_t* json_chunk = ptr + GlbHeaderSize;
1120 if (GlbHeaderSize + GlbChunkHeaderSize > size)
1126 uint32_t json_length;
1127 memcpy(&json_length, json_chunk, 4);
1128 if (GlbHeaderSize + GlbChunkHeaderSize + json_length > size)
1134 memcpy(&tmp, json_chunk + 4, 4);
1135 if (tmp != GlbMagicJsonChunk)
1140 json_chunk += GlbChunkHeaderSize;
1142 const void* bin = 0;
1145 if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size)
1148 const uint8_t* bin_chunk = json_chunk + json_length;
1151 uint32_t bin_length;
1152 memcpy(&bin_length, bin_chunk, 4);
1153 if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize + bin_length > size)
1159 memcpy(&tmp, bin_chunk + 4, 4);
1160 if (tmp != GlbMagicBinChunk)
1165 bin_chunk += GlbChunkHeaderSize;
1168 bin_size = bin_length;
1171 cgltf_result json_result = cgltf_parse_json(&fixed_options, json_chunk, json_length, out_data);
1178 (*out_data)->bin = bin;
1179 (*out_data)->bin_size = bin_size;
1186 if (options == NULL)
1194 void* file_data = NULL;
1195 cgltf_size file_size = 0;
1202 result =
cgltf_parse(options, file_data, file_size, out_data);
1206 file_release(&options->
memory, &options->
file, file_data);
1210 (*out_data)->file_data = file_data;
1215 static void cgltf_combine_paths(
char* path,
const char* base,
const char* uri)
1217 const char* s0 = strrchr(base,
'/');
1218 const char* s1 = strrchr(base,
'\\');
1219 const char* slash = s0 ? (s1 && s1 > s0 ? s1 : s0) : s1;
1223 size_t prefix = slash - base + 1;
1225 strncpy(path, base, prefix);
1226 strcpy(path + prefix, uri);
1234 static cgltf_result cgltf_load_buffer_file(
const cgltf_options* options, cgltf_size size,
const char* uri,
const char* gltf_path,
void** out_data)
1240 char* path = (
char*)memory_alloc(options->
memory.
user_data, strlen(uri) + strlen(gltf_path) + 1);
1246 cgltf_combine_paths(path, gltf_path, uri);
1251 void* file_data = NULL;
1266 unsigned char* data = (
unsigned char*)memory_alloc(options->
memory.
user_data, size);
1273 unsigned int buffer_bits = 0;
1275 for (cgltf_size i = 0; i <
size; ++i)
1277 while (buffer_bits < 8)
1279 char ch = *base64++;
1282 (unsigned)(ch -
'A') < 26 ? (ch -
'A') :
1283 (
unsigned)(ch -
'a') < 26 ? (ch -
'a') + 26 :
1284 (unsigned)(ch -
'0') < 10 ? (ch -
'0') + 52 :
1295 buffer = (buffer << 6) | index;
1299 data[i] = (
unsigned char)(buffer >> (buffer_bits - 8));
1308 static int cgltf_unhex(
char ch)
1311 (
unsigned)(ch -
'0') < 10 ? (ch -
'0') :
1312 (unsigned)(ch -
'A') < 6 ? (ch -
'A') + 10 :
1313 (
unsigned)(ch -
'a') < 6 ? (ch -
'a') + 10 :
1319 char*
read =
string + strcspn(
string,
"\\");
1330 cgltf_size written = read -
last;
1331 memmove(write, last, written);
1342 case '\"': *write++ =
'\"';
break;
1343 case '/': *write++ =
'/';
break;
1344 case '\\': *write++ =
'\\';
break;
1345 case 'b': *write++ =
'\b';
break;
1346 case 'f': *write++ =
'\f';
break;
1347 case 'r': *write++ =
'\r';
break;
1348 case 'n': *write++ =
'\n';
break;
1349 case 't': *write++ =
'\t';
break;
1354 for (cgltf_size i = 0; i < 4; ++i)
1356 character = (character << 4) + cgltf_unhex(*read++);
1359 if (character <= 0x7F)
1361 *write++ = character & 0xFF;
1363 else if (character <= 0x7FF)
1365 *write++ = 0xC0 | ((character >> 6) & 0xFF);
1366 *write++ = 0x80 | (character & 0x3F);
1370 *write++ = 0xE0 | ((character >> 12) & 0xFF);
1371 *write++ = 0x80 | ((character >> 6) & 0x3F);
1372 *write++ = 0x80 | (character & 0x3F);
1381 read += strcspn(read,
"\\");
1397 int ch1 = cgltf_unhex(i[1]);
1401 int ch2 = cgltf_unhex(i[2]);
1405 *write++ = (char)(ch1 * 16 + ch2);
1421 if (options == NULL)
1451 if (strncmp(uri,
"data:", 5) == 0)
1453 const char* comma = strchr(uri,
',');
1455 if (comma && comma - uri >= 7 && strncmp(comma - 7,
";base64", 7) == 0)
1470 else if (strstr(uri,
"://") == NULL && gltf_path)
1493 char* data = (
char*)buffer_view->
buffer->
data + offset + buffer_view->
offset;
1494 cgltf_size bound = 0;
1496 switch (component_type)
1499 for (
size_t i = 0; i <
count; ++i)
1501 cgltf_size
v = ((
unsigned char*)data)[i];
1502 bound = bound > v ? bound :
v;
1507 for (
size_t i = 0; i <
count; ++i)
1509 cgltf_size
v = ((
unsigned short*)data)[i];
1510 bound = bound > v ? bound :
v;
1515 for (
size_t i = 0; i <
count; ++i)
1517 cgltf_size
v = ((
unsigned int*)data)[i];
1518 bound = bound > v ? bound :
v;
1529 #if CGLTF_VALIDATE_ENABLE_ASSERTS
1530 #define CGLTF_ASSERT_IF(cond, result) assert(!(cond)); if (cond) return result;
1532 #define CGLTF_ASSERT_IF(cond, result) if (cond) return result;
1545 cgltf_size req_size = accessor->
offset + accessor->
stride * (accessor->
count - 1) + element_size;
1641 CGLTF_ASSERT_IF(indices &&
1661 for (cgltf_size i = 0; i < data->
nodes_count; ++i)
1669 for (cgltf_size i = 0; i < data->
nodes_count; ++i)
1702 cgltf_size components = 1;
1728 *dest_size = json_size + 1;
1734 if (*dest_size + 1 < json_size)
1737 dest[*dest_size - 1] = 0;
1742 dest[json_size] = 0;
1750 for (cgltf_size i = 0; i < extensions_count; ++i)
1952 for (cgltf_size i = 0; i < data->
skins_count; ++i)
1977 for (cgltf_size i = 0; i < data->
nodes_count; ++i)
2051 memcpy(lm, node->
matrix,
sizeof(
float) * 16);
2064 float sx = node->
scale[0];
2065 float sy = node->
scale[1];
2066 float sz = node->
scale[2];
2068 lm[0] = (1 - 2 * qy*qy - 2 * qz*qz) * sx;
2069 lm[1] = (2 * qx*qy + 2 * qz*qw) * sx;
2070 lm[2] = (2 * qx*qz - 2 * qy*qw) * sx;
2073 lm[4] = (2 * qx*qy - 2 * qz*qw) * sy;
2074 lm[5] = (1 - 2 * qx*qx - 2 * qz*qz) * sy;
2075 lm[6] = (2 * qy*qz + 2 * qx*qw) * sy;
2078 lm[8] = (2 * qx*qz + 2 * qy*qw) * sz;
2079 lm[9] = (2 * qy*qz - 2 * qx*qw) * sz;
2080 lm[10] = (1 - 2 * qx*qx - 2 * qy*qy) * sz;
2102 for (
int i = 0; i < 4; ++i)
2104 float l0 = lm[i * 4 + 0];
2105 float l1 = lm[i * 4 + 1];
2106 float l2 = lm[i * 4 + 2];
2108 float r0 = l0 * pm[0] + l1 * pm[4] + l2 * pm[8];
2109 float r1 = l0 * pm[1] + l1 * pm[5] + l2 * pm[9];
2110 float r2 = l0 * pm[2] + l1 * pm[6] + l2 * pm[10];
2127 switch (component_type)
2130 return *((
const int16_t*) in);
2132 return *((
const uint16_t*) in);
2134 return *((
const uint32_t*) in);
2138 return *((
const int8_t*) in);
2140 return *((
const uint8_t*) in);
2146 static cgltf_size cgltf_component_read_index(
const void* in,
cgltf_component_type component_type)
2148 switch (component_type)
2151 return *((
const uint16_t*) in);
2153 return *((
const uint32_t*) in);
2155 return (cgltf_size)*((
const float*) in);
2157 return *((
const uint8_t*) in);
2167 return *((
const float*) in);
2172 switch (component_type)
2176 return *((
const int16_t*) in) / (
cgltf_float)32767;
2178 return *((
const uint16_t*) in) / (
cgltf_float)65535;
2188 return (
cgltf_float)cgltf_component_read_integer(in, component_type);
2197 if (element_size < num_components) {
2203 cgltf_size component_size = cgltf_component_size(component_type);
2207 out[0] = cgltf_component_read_float(element, component_type, normalized);
2208 out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
2209 out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
2210 out[3] = cgltf_component_read_float(element + 5, component_type, normalized);
2216 out[0] = cgltf_component_read_float(element, component_type, normalized);
2217 out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
2218 out[2] = cgltf_component_read_float(element + 2, component_type, normalized);
2219 out[3] = cgltf_component_read_float(element + 4, component_type, normalized);
2220 out[4] = cgltf_component_read_float(element + 5, component_type, normalized);
2221 out[5] = cgltf_component_read_float(element + 6, component_type, normalized);
2222 out[6] = cgltf_component_read_float(element + 8, component_type, normalized);
2223 out[7] = cgltf_component_read_float(element + 9, component_type, normalized);
2224 out[8] = cgltf_component_read_float(element + 10, component_type, normalized);
2230 out[0] = cgltf_component_read_float(element, component_type, normalized);
2231 out[1] = cgltf_component_read_float(element + 2, component_type, normalized);
2232 out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
2233 out[3] = cgltf_component_read_float(element + 8, component_type, normalized);
2234 out[4] = cgltf_component_read_float(element + 10, component_type, normalized);
2235 out[5] = cgltf_component_read_float(element + 12, component_type, normalized);
2236 out[6] = cgltf_component_read_float(element + 16, component_type, normalized);
2237 out[7] = cgltf_component_read_float(element + 18, component_type, normalized);
2238 out[8] = cgltf_component_read_float(element + 20, component_type, normalized);
2242 for (cgltf_size i = 0; i < num_components; ++i)
2244 out[i] = cgltf_component_read_float(element + component_size * i, component_type, normalized);
2252 return (
const uint8_t*)view->
data;
2257 const uint8_t* result = (
const uint8_t*)view->
buffer->
data;
2270 memset(out, 0, element_size *
sizeof(
cgltf_float));
2273 const uint8_t* element = cgltf_buffer_view_data(accessor->
buffer_view);
2274 if (element == NULL)
2285 cgltf_size available_floats = accessor->
count * floats_per_element;
2288 return available_floats;
2291 float_count = available_floats < float_count ? available_floats : float_count;
2292 cgltf_size element_count = float_count / floats_per_element;
2298 for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element)
2314 if (index_data == NULL || reader_head == NULL)
2323 for (cgltf_size reader_index = 0; reader_index < sparse->
count; reader_index++, index_data += index_stride)
2326 float* writer_head = out + writer_index * floats_per_element;
2333 reader_head += dense.
stride;
2337 return element_count * floats_per_element;
2342 switch (component_type)
2345 return *((
const int8_t*) in);
2348 return *((
const uint8_t*) in);
2351 return *((
const int16_t*) in);
2354 return *((
const uint16_t*) in);
2357 return *((
const uint32_t*) in);
2368 if (element_size < num_components)
2379 cgltf_size component_size = cgltf_component_size(component_type);
2381 for (cgltf_size i = 0; i < num_components; ++i)
2383 out[i] = cgltf_component_read_uint(element + component_size * i, component_type);
2396 memset(out, 0, element_size *
sizeof(
cgltf_uint ));
2399 const uint8_t* element = cgltf_buffer_view_data(accessor->
buffer_view);
2400 if (element == NULL)
2405 return cgltf_element_read_uint(element, accessor->
type, accessor->
component_type, out, element_size);
2418 const uint8_t* element = cgltf_buffer_view_data(accessor->
buffer_view);
2419 if (element == NULL)
2424 return cgltf_component_read_index(element, accessor->
component_type);
2427 #define CGLTF_ERROR_JSON -1
2428 #define CGLTF_ERROR_NOMEM -2
2429 #define CGLTF_ERROR_LEGACY -3
2431 #define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; }
2432 #define CGLTF_CHECK_TOKTYPE_RETTYPE(tok_, type_, ret_) if ((tok_).type != (type_)) { return (ret_)CGLTF_ERROR_JSON; }
2433 #define CGLTF_CHECK_KEY(tok_) if ((tok_).type != JSMN_STRING || (tok_).size == 0) { return CGLTF_ERROR_JSON; }
2435 #define CGLTF_PTRINDEX(type, idx) (type*)((cgltf_size)idx + 1)
2436 #define CGLTF_PTRFIXUP(var, data, size) if (var) { if ((cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1]; }
2437 #define CGLTF_PTRFIXUP_REQ(var, data, size) if (!var || (cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1];
2439 static int cgltf_json_strcmp(jsmntok_t
const* tok,
const uint8_t* json_chunk,
const char* str)
2441 CGLTF_CHECK_TOKTYPE(*tok, JSMN_STRING);
2442 size_t const str_len = strlen(str);
2443 size_t const name_length = tok->end - tok->start;
2444 return (str_len == name_length) ? strncmp((
const char*)json_chunk + tok->start, str, str_len) : 128;
2447 static int cgltf_json_to_int(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2449 CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
2451 int size = (
cgltf_size)(tok->end - tok->start) <
sizeof(tmp) ? tok->end - tok->start : (
int)(
sizeof(tmp) - 1);
2452 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2454 return CGLTF_ATOI(tmp);
2457 static cgltf_size cgltf_json_to_size(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2459 CGLTF_CHECK_TOKTYPE_RETTYPE(*tok, JSMN_PRIMITIVE, cgltf_size);
2461 int size = (
cgltf_size)(tok->end - tok->start) <
sizeof(tmp) ? tok->end - tok->start : (
int)(
sizeof(tmp) - 1);
2462 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2464 return (cgltf_size)CGLTF_ATOLL(tmp);
2467 static cgltf_float cgltf_json_to_float(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2469 CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
2471 int size = (
cgltf_size)(tok->end - tok->start) <
sizeof(tmp) ? tok->end - tok->start : (
int)(
sizeof(tmp) - 1);
2472 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2477 static cgltf_bool cgltf_json_to_bool(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2479 int size = tok->end - tok->start;
2480 return size == 4 && memcmp(json_chunk + tok->start,
"true", 4) == 0;
2483 static int cgltf_skip_json(jsmntok_t
const* tokens,
int i)
2489 switch (tokens[i].type)
2492 end += tokens[i].size * 2;
2496 end += tokens[i].size;
2499 case JSMN_PRIMITIVE:
2513 static void cgltf_fill_float_array(
float* out_array,
int size,
float value)
2515 for (
int j = 0; j <
size; ++
j)
2521 static int cgltf_parse_json_float_array(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
float* out_array,
int size)
2523 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2524 if (tokens[i].size != size)
2526 return CGLTF_ERROR_JSON;
2529 for (
int j = 0; j <
size; ++
j)
2531 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
2532 out_array[
j] = cgltf_json_to_float(tokens + i, json_chunk);
2538 static int cgltf_parse_json_string(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
char** out_string)
2540 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
2543 return CGLTF_ERROR_JSON;
2545 int size = tokens[i].end - tokens[i].start;
2549 return CGLTF_ERROR_NOMEM;
2551 strncpy(result, (
const char*)json_chunk + tokens[i].
start, size);
2557 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)
2560 if (tokens[i].type != JSMN_ARRAY)
2562 return tokens[i].type == JSMN_OBJECT ? CGLTF_ERROR_LEGACY : CGLTF_ERROR_JSON;
2566 return CGLTF_ERROR_JSON;
2568 int size = tokens[i].size;
2569 void* result = cgltf_calloc(options, element_size, size);
2572 return CGLTF_ERROR_NOMEM;
2579 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)
2581 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2582 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
char*), (
void**)out_array, out_size);
2588 for (cgltf_size j = 0; j < *out_size; ++
j)
2590 i = cgltf_parse_json_string(options, tokens, i, json_chunk, j + (*out_array));
2607 const char* us = strchr(name,
'_');
2608 size_t len = us ? (size_t)(us - name) : strlen(name);
2610 if (len == 8 && strncmp(name,
"POSITION", 8) == 0)
2614 else if (len == 6 && strncmp(name,
"NORMAL", 6) == 0)
2618 else if (len == 7 && strncmp(name,
"TANGENT", 7) == 0)
2622 else if (len == 8 && strncmp(name,
"TEXCOORD", 8) == 0)
2626 else if (len == 5 && strncmp(name,
"COLOR", 5) == 0)
2630 else if (len == 6 && strncmp(name,
"JOINTS", 6) == 0)
2634 else if (len == 7 && strncmp(name,
"WEIGHTS", 7) == 0)
2645 *out_index = CGLTF_ATOI(us + 1);
2649 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)
2651 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2653 if (*out_attributes)
2655 return CGLTF_ERROR_JSON;
2658 *out_attributes_count = tokens[i].size;
2662 if (!*out_attributes)
2664 return CGLTF_ERROR_NOMEM;
2667 for (cgltf_size j = 0; j < *out_attributes_count; ++
j)
2669 CGLTF_CHECK_KEY(tokens[i]);
2671 i = cgltf_parse_json_string(options, tokens, i, json_chunk, &(*out_attributes)[j].name);
2674 return CGLTF_ERROR_JSON;
2677 cgltf_parse_attribute_type((*out_attributes)[j].name, &(*out_attributes)[j].type, &(*out_attributes)[j].index);
2679 (*out_attributes)[
j].data = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
2686 static int cgltf_parse_json_extras(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_extras* out_extras)
2691 i = cgltf_skip_json(tokens, i);
2695 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)
2697 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
2698 CGLTF_CHECK_TOKTYPE(tokens[i+1], JSMN_OBJECT);
2699 if (out_extension->
name)
2701 return CGLTF_ERROR_JSON;
2704 cgltf_size name_length = tokens[i].end - tokens[i].start;
2706 if (!out_extension->
name)
2708 return CGLTF_ERROR_NOMEM;
2710 strncpy(out_extension->
name, (
const char*)json_chunk + tokens[i].start, name_length);
2711 out_extension->
name[name_length] = 0;
2714 size_t start = tokens[i].start;
2715 size_t size = tokens[i].end -
start;
2717 if (!out_extension->
data)
2719 return CGLTF_ERROR_NOMEM;
2721 strncpy(out_extension->
data, (
const char*)json_chunk + start, size);
2724 i = cgltf_skip_json(tokens, i);
2729 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)
2733 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2736 return CGLTF_ERROR_JSON;
2739 int extensions_size = tokens[i].size;
2740 *out_extensions_count = 0;
2743 if (!*out_extensions)
2745 return CGLTF_ERROR_NOMEM;
2750 for (
int j = 0; j < extensions_size; ++
j)
2752 CGLTF_CHECK_KEY(tokens[i]);
2754 cgltf_size extension_index = (*out_extensions_count)++;
2756 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, extension);
2768 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2770 int size = tokens[i].size;
2773 for (
int j = 0; j <
size; ++
j)
2775 CGLTF_CHECK_KEY(tokens[i]);
2777 if (cgltf_json_strcmp(tokens + i, json_chunk,
"attributes") == 0)
2779 i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_draco_mesh_compression->
attributes, &out_draco_mesh_compression->
attributes_count);
2781 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"bufferView") == 0)
2799 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2801 int size = tokens[i].size;
2804 for (
int j = 0; j <
size; ++
j)
2806 CGLTF_CHECK_KEY(tokens[i]);
2808 if (cgltf_json_strcmp(tokens + i, json_chunk,
"attributes") == 0)
2810 i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_mesh_gpu_instancing->
attributes, &out_mesh_gpu_instancing->
attributes_count);
2812 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"bufferView") == 0)
2828 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)
2831 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2833 int size = tokens[i].size;
2836 for (
int j = 0; j <
size; ++
j)
2838 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2840 int obj_size = tokens[i].size;
2844 int variants_tok = -1;
2847 for (
int k = 0; k < obj_size; ++k)
2849 CGLTF_CHECK_KEY(tokens[i]);
2851 if (cgltf_json_strcmp(tokens + i, json_chunk,
"material") == 0)
2854 material = cgltf_json_to_int(tokens + i, json_chunk);
2857 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"variants") == 0)
2860 CGLTF_CHECK_TOKTYPE(tokens[variants_tok], JSMN_ARRAY);
2862 i = cgltf_skip_json(tokens, i+1);
2864 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
2866 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &extras);
2870 i = cgltf_skip_json(tokens, i+1);
2879 if (material < 0 || variants_tok < 0)
2881 return CGLTF_ERROR_JSON;
2886 for (
int k = 0; k < tokens[variants_tok].size; ++k)
2888 int variant = cgltf_json_to_int(&tokens[variants_tok + 1 + k], json_chunk);
2901 (*offset) += tokens[variants_tok].size;
2908 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)
2910 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2912 int size = tokens[i].size;
2915 for (
int j = 0; j <
size; ++
j)
2917 CGLTF_CHECK_KEY(tokens[i]);
2919 if (cgltf_json_strcmp(tokens + i, json_chunk,
"mappings") == 0)
2923 return CGLTF_ERROR_JSON;
2926 cgltf_size mappings_offset = 0;
2927 int k = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, NULL, &mappings_offset);
2936 mappings_offset = 0;
2937 i = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, out_prim->
mappings, &mappings_offset);
2941 i = cgltf_skip_json(tokens, i+1);
2953 static int cgltf_parse_json_primitive(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_primitive* out_prim)
2955 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2959 int size = tokens[i].size;
2962 for (
int j = 0; j <
size; ++
j)
2964 CGLTF_CHECK_KEY(tokens[i]);
2966 if (cgltf_json_strcmp(tokens+i, json_chunk,
"mode") == 0)
2971 cgltf_json_to_int(tokens+i, json_chunk);
2974 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"indices") == 0)
2980 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"material") == 0)
2986 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"attributes") == 0)
2990 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"targets") == 0)
3007 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3009 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_prim->
extras);
3011 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3015 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3018 return CGLTF_ERROR_JSON;
3021 int extensions_size = tokens[i].size;
3027 return CGLTF_ERROR_NOMEM;
3031 for (
int k = 0; k < extensions_size; ++k)
3033 CGLTF_CHECK_KEY(tokens[i]);
3035 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_draco_mesh_compression") == 0)
3038 i = cgltf_parse_json_draco_mesh_compression(options, tokens, i + 1, json_chunk, &out_prim->
draco_mesh_compression);
3040 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_variants") == 0)
3042 i = cgltf_parse_json_material_mappings(options, tokens, i + 1, json_chunk, out_prim);
3046 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_prim->
extensions[out_prim->
extensions_count++]));
3057 i = cgltf_skip_json(tokens, i+1);
3069 static int cgltf_parse_json_mesh(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_mesh* out_mesh)
3071 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3073 int size = tokens[i].size;
3076 for (
int j = 0; j <
size; ++
j)
3078 CGLTF_CHECK_KEY(tokens[i]);
3080 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
3082 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_mesh->
name);
3084 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"primitives") == 0)
3092 for (cgltf_size prim_index = 0; prim_index < out_mesh->
primitives_count; ++prim_index)
3094 i = cgltf_parse_json_primitive(options, tokens, i, json_chunk, &out_mesh->
primitives[prim_index]);
3101 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"weights") == 0)
3109 i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_mesh->
weights, (
int)out_mesh->
weights_count);
3111 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3118 if (tokens[i].type == JSMN_OBJECT)
3120 int extras_size = tokens[i].size;
3123 for (
int k = 0; k < extras_size; ++k)
3125 CGLTF_CHECK_KEY(tokens[i]);
3127 if (cgltf_json_strcmp(tokens+i, json_chunk,
"targetNames") == 0 && tokens[i+1].type == JSMN_ARRAY)
3133 i = cgltf_skip_json(tokens, i+1);
3144 i = cgltf_skip_json(tokens, i);
3147 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3149 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_mesh->
extensions_count, &out_mesh->
extensions);
3153 i = cgltf_skip_json(tokens, i+1);
3165 static int cgltf_parse_json_meshes(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
3175 i = cgltf_parse_json_mesh(options, tokens, i, json_chunk, &out_data->
meshes[j]);
3184 static cgltf_component_type cgltf_json_to_component_type(jsmntok_t
const* tok,
const uint8_t* json_chunk)
3186 int type = cgltf_json_to_int(tok, json_chunk);
3209 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3211 int size = tokens[i].size;
3214 for (
int j = 0; j <
size; ++
j)
3216 CGLTF_CHECK_KEY(tokens[i]);
3218 if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
3221 out_sparse->
count = cgltf_json_to_int(tokens + i, json_chunk);
3224 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"indices") == 0)
3227 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3229 int indices_size = tokens[i].size;
3232 for (
int k = 0; k < indices_size; ++k)
3234 CGLTF_CHECK_KEY(tokens[i]);
3236 if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3242 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3248 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"componentType") == 0)
3254 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3256 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->
indices_extras);
3258 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3264 i = cgltf_skip_json(tokens, i+1);
3273 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"values") == 0)
3276 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3278 int values_size = tokens[i].size;
3281 for (
int k = 0; k < values_size; ++k)
3283 CGLTF_CHECK_KEY(tokens[i]);
3285 if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3291 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3297 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3299 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->
values_extras);
3301 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3307 i = cgltf_skip_json(tokens, i+1);
3316 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3318 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->
extras);
3320 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3322 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->
extensions_count, &out_sparse->
extensions);
3326 i = cgltf_skip_json(tokens, i+1);
3338 static int cgltf_parse_json_accessor(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_accessor* out_accessor)
3340 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3342 int size = tokens[i].size;
3345 for (
int j = 0; j <
size; ++
j)
3347 CGLTF_CHECK_KEY(tokens[i]);
3349 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
3351 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_accessor->
name);
3353 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3359 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3363 cgltf_json_to_size(tokens+i, json_chunk);
3366 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"componentType") == 0)
3369 out_accessor->
component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
3372 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"normalized") == 0)
3375 out_accessor->
normalized = cgltf_json_to_bool(tokens+i, json_chunk);
3378 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
3381 out_accessor->
count =
3382 cgltf_json_to_int(tokens+i, json_chunk);
3385 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
3388 if (cgltf_json_strcmp(tokens+i, json_chunk,
"SCALAR") == 0)
3392 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC2") == 0)
3396 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC3") == 0)
3400 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC4") == 0)
3404 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT2") == 0)
3408 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT3") == 0)
3412 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT4") == 0)
3418 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"min") == 0)
3423 int min_size = tokens[i].size > 16 ? 16 : tokens[i].size;
3424 i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->
min, min_size);
3426 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"max") == 0)
3431 int max_size = tokens[i].size > 16 ? 16 : tokens[i].size;
3432 i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->
max, max_size);
3434 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"sparse") == 0)
3437 i = cgltf_parse_json_accessor_sparse(options, tokens, i + 1, json_chunk, &out_accessor->
sparse);
3439 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3441 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_accessor->
extras);
3443 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3445 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_accessor->
extensions_count, &out_accessor->
extensions);
3449 i = cgltf_skip_json(tokens, i+1);
3461 static int cgltf_parse_json_texture_transform(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_texture_transform* out_texture_transform)
3463 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3465 int size = tokens[i].size;
3468 for (
int j = 0; j <
size; ++
j)
3470 CGLTF_CHECK_KEY(tokens[i]);
3472 if (cgltf_json_strcmp(tokens + i, json_chunk,
"offset") == 0)
3474 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->
offset, 2);
3476 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"rotation") == 0)
3479 out_texture_transform->
rotation = cgltf_json_to_float(tokens + i, json_chunk);
3482 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scale") == 0)
3484 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->
scale, 2);
3486 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"texCoord") == 0)
3490 out_texture_transform->
texcoord = cgltf_json_to_int(tokens + i, json_chunk);
3495 i = cgltf_skip_json(tokens, i + 1);
3507 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)
3509 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3511 out_texture_view->
scale = 1.0f;
3512 cgltf_fill_float_array(out_texture_view->
transform.
scale, 2, 1.0f);
3514 int size = tokens[i].size;
3517 for (
int j = 0; j <
size; ++
j)
3519 CGLTF_CHECK_KEY(tokens[i]);
3521 if (cgltf_json_strcmp(tokens + i, json_chunk,
"index") == 0)
3524 out_texture_view->
texture = CGLTF_PTRINDEX(
cgltf_texture, cgltf_json_to_int(tokens + i, json_chunk));
3527 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"texCoord") == 0)
3530 out_texture_view->
texcoord = cgltf_json_to_int(tokens + i, json_chunk);
3533 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scale") == 0)
3536 out_texture_view->
scale = cgltf_json_to_float(tokens + i, json_chunk);
3539 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"strength") == 0)
3542 out_texture_view->
scale = cgltf_json_to_float(tokens + i, json_chunk);
3545 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3547 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_texture_view->
extras);
3549 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3553 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3556 return CGLTF_ERROR_JSON;
3559 int extensions_size = tokens[i].size;
3565 return CGLTF_ERROR_NOMEM;
3570 for (
int k = 0; k < extensions_size; ++k)
3572 CGLTF_CHECK_KEY(tokens[i]);
3574 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_texture_transform") == 0)
3577 i = cgltf_parse_json_texture_transform(tokens, i + 1, json_chunk, &out_texture_view->
transform);
3581 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture_view->
extensions[out_texture_view->
extensions_count++]));
3592 i = cgltf_skip_json(tokens, i + 1);
3606 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3608 int size = tokens[i].size;
3611 for (
int j = 0; j <
size; ++
j)
3613 CGLTF_CHECK_KEY(tokens[i]);
3615 if (cgltf_json_strcmp(tokens+i, json_chunk,
"metallicFactor") == 0)
3619 cgltf_json_to_float(tokens + i, json_chunk);
3622 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"roughnessFactor") == 0)
3626 cgltf_json_to_float(tokens+i, json_chunk);
3629 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"baseColorFactor") == 0)
3631 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->
base_color_factor, 4);
3633 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"baseColorTexture") == 0)
3635 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
3638 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"metallicRoughnessTexture") == 0)
3640 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
3643 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3645 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_pbr->
extras);
3649 i = cgltf_skip_json(tokens, i+1);
3663 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3664 int size = tokens[i].size;
3667 for (
int j = 0; j <
size; ++
j)
3669 CGLTF_CHECK_KEY(tokens[i]);
3671 if (cgltf_json_strcmp(tokens+i, json_chunk,
"diffuseFactor") == 0)
3673 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->
diffuse_factor, 4);
3675 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularFactor") == 0)
3677 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->
specular_factor, 3);
3679 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"glossinessFactor") == 0)
3685 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"diffuseTexture") == 0)
3687 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->
diffuse_texture);
3689 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularGlossinessTexture") == 0)
3695 i = cgltf_skip_json(tokens, i+1);
3707 static int cgltf_parse_json_clearcoat(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_clearcoat* out_clearcoat)
3709 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3710 int size = tokens[i].size;
3713 for (
int j = 0; j <
size; ++
j)
3715 CGLTF_CHECK_KEY(tokens[i]);
3717 if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatFactor") == 0)
3720 out_clearcoat->
clearcoat_factor = cgltf_json_to_float(tokens + i, json_chunk);
3723 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatRoughnessFactor") == 0)
3729 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatTexture") == 0)
3731 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->
clearcoat_texture);
3733 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatRoughnessTexture") == 0)
3737 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatNormalTexture") == 0)
3743 i = cgltf_skip_json(tokens, i+1);
3755 static int cgltf_parse_json_ior(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_ior* out_ior)
3757 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3758 int size = tokens[i].size;
3762 out_ior->
ior = 1.5f;
3764 for (
int j = 0; j <
size; ++
j)
3766 CGLTF_CHECK_KEY(tokens[i]);
3768 if (cgltf_json_strcmp(tokens+i, json_chunk,
"ior") == 0)
3771 out_ior->
ior = cgltf_json_to_float(tokens + i, json_chunk);
3776 i = cgltf_skip_json(tokens, i+1);
3788 static int cgltf_parse_json_specular(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_specular* out_specular)
3790 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3791 int size = tokens[i].size;
3798 for (
int j = 0; j <
size; ++
j)
3800 CGLTF_CHECK_KEY(tokens[i]);
3802 if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularFactor") == 0)
3805 out_specular->
specular_factor = cgltf_json_to_float(tokens + i, json_chunk);
3808 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularColorFactor") == 0)
3810 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_specular->
specular_color_factor, 3);
3812 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularTexture") == 0)
3814 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->
specular_texture);
3816 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"specularColorTexture") == 0)
3818 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->
specular_color_texture);
3822 i = cgltf_skip_json(tokens, i+1);
3834 static int cgltf_parse_json_transmission(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_transmission* out_transmission)
3836 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3837 int size = tokens[i].size;
3840 for (
int j = 0; j <
size; ++
j)
3842 CGLTF_CHECK_KEY(tokens[i]);
3844 if (cgltf_json_strcmp(tokens+i, json_chunk,
"transmissionFactor") == 0)
3850 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"transmissionTexture") == 0)
3852 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_transmission->
transmission_texture);
3856 i = cgltf_skip_json(tokens, i+1);
3868 static int cgltf_parse_json_volume(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_volume* out_volume)
3870 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3871 int size = tokens[i].size;
3874 for (
int j = 0; j <
size; ++
j)
3876 CGLTF_CHECK_KEY(tokens[i]);
3878 if (cgltf_json_strcmp(tokens + i, json_chunk,
"thicknessFactor") == 0)
3881 out_volume->
thickness_factor = cgltf_json_to_float(tokens + i, json_chunk);
3884 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"thicknessTexture") == 0)
3886 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_volume->
thickness_texture);
3888 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"attenuationColor") == 0)
3890 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_volume->
attenuation_color, 3);
3892 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"attenuationDistance") == 0)
3900 i = cgltf_skip_json(tokens, i + 1);
3912 static int cgltf_parse_json_sheen(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_sheen* out_sheen)
3914 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3915 int size = tokens[i].size;
3918 for (
int j = 0; j <
size; ++
j)
3920 CGLTF_CHECK_KEY(tokens[i]);
3922 if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenColorFactor") == 0)
3924 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_sheen->
sheen_color_factor, 3);
3926 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenColorTexture") == 0)
3928 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_sheen->
sheen_color_texture);
3930 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenRoughnessFactor") == 0)
3936 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenRoughnessTexture") == 0)
3942 i = cgltf_skip_json(tokens, i+1);
3954 static int cgltf_parse_json_emissive_strength(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_emissive_strength* out_emissive_strength)
3956 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3957 int size = tokens[i].size;
3963 for (
int j = 0; j <
size; ++
j)
3965 CGLTF_CHECK_KEY(tokens[i]);
3967 if (cgltf_json_strcmp(tokens + i, json_chunk,
"emissiveStrength") == 0)
3970 out_emissive_strength->
emissive_strength = cgltf_json_to_float(tokens + i, json_chunk);
3975 i = cgltf_skip_json(tokens, i + 1);
3987 static int cgltf_parse_json_iridescence(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_iridescence* out_iridescence)
3989 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3990 int size = tokens[i].size;
3998 for (
int j = 0; j <
size; ++
j)
4000 CGLTF_CHECK_KEY(tokens[i]);
4002 if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceFactor") == 0)
4008 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceTexture") == 0)
4010 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_iridescence->
iridescence_texture);
4012 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceIor") == 0)
4015 out_iridescence->
iridescence_ior = cgltf_json_to_float(tokens + i, json_chunk);
4018 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceThicknessMinimum") == 0)
4024 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceThicknessMaximum") == 0)
4030 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"iridescenceThicknessTexture") == 0)
4036 i = cgltf_skip_json(tokens, i + 1);
4048 static int cgltf_parse_json_image(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_image* out_image)
4050 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4052 int size = tokens[i].size;
4055 for (
int j = 0; j <
size; ++
j)
4057 CGLTF_CHECK_KEY(tokens[i]);
4059 if (cgltf_json_strcmp(tokens + i, json_chunk,
"uri") == 0)
4061 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->
uri);
4063 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
4069 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"mimeType") == 0)
4071 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->
mime_type);
4073 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4075 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->
name);
4077 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4079 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_image->
extras);
4081 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4083 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_image->
extensions_count, &out_image->
extensions);
4087 i = cgltf_skip_json(tokens, i + 1);
4099 static int cgltf_parse_json_sampler(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_sampler* out_sampler)
4102 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4104 out_sampler->
wrap_s = 10497;
4105 out_sampler->
wrap_t = 10497;
4107 int size = tokens[i].size;
4110 for (
int j = 0; j <
size; ++
j)
4112 CGLTF_CHECK_KEY(tokens[i]);
4114 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4116 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_sampler->
name);
4118 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"magFilter") == 0)
4122 = cgltf_json_to_int(tokens + i, json_chunk);
4125 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"minFilter") == 0)
4129 = cgltf_json_to_int(tokens + i, json_chunk);
4132 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"wrapS") == 0)
4136 = cgltf_json_to_int(tokens + i, json_chunk);
4139 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"wrapT") == 0)
4143 = cgltf_json_to_int(tokens + i, json_chunk);
4146 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4148 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sampler->
extras);
4150 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4152 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->
extensions_count, &out_sampler->
extensions);
4156 i = cgltf_skip_json(tokens, i + 1);
4168 static int cgltf_parse_json_texture(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_texture* out_texture)
4170 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4172 int size = tokens[i].size;
4175 for (
int j = 0; j <
size; ++
j)
4177 CGLTF_CHECK_KEY(tokens[i]);
4179 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4181 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_texture->
name);
4183 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"sampler") == 0)
4186 out_texture->
sampler = CGLTF_PTRINDEX(
cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk));
4189 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"source") == 0)
4192 out_texture->
image = CGLTF_PTRINDEX(
cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
4195 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4197 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_texture->
extras);
4199 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4203 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4206 return CGLTF_ERROR_JSON;
4209 int extensions_size = tokens[i].size;
4216 return CGLTF_ERROR_NOMEM;
4219 for (
int k = 0; k < extensions_size; ++k)
4221 CGLTF_CHECK_KEY(tokens[i]);
4223 if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_texture_basisu") == 0)
4227 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4228 int num_properties = tokens[i].size;
4231 for (
int t = 0;
t < num_properties; ++
t)
4233 CGLTF_CHECK_KEY(tokens[i]);
4235 if (cgltf_json_strcmp(tokens + i, json_chunk,
"source") == 0)
4243 i = cgltf_skip_json(tokens, i + 1);
4253 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture->
extensions[out_texture->
extensions_count++]));
4264 i = cgltf_skip_json(tokens, i + 1);
4276 static int cgltf_parse_json_material(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_material* out_material)
4278 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4293 int size = tokens[i].size;
4296 for (
int j = 0; j <
size; ++
j)
4298 CGLTF_CHECK_KEY(tokens[i]);
4300 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4302 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_material->
name);
4304 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"pbrMetallicRoughness") == 0)
4307 i = cgltf_parse_json_pbr_metallic_roughness(options, tokens, i + 1, json_chunk, &out_material->
pbr_metallic_roughness);
4309 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"emissiveFactor") == 0)
4311 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_material->
emissive_factor, 3);
4313 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"normalTexture") == 0)
4315 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4318 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"occlusionTexture") == 0)
4320 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4323 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"emissiveTexture") == 0)
4325 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4328 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"alphaMode") == 0)
4331 if (cgltf_json_strcmp(tokens + i, json_chunk,
"OPAQUE") == 0)
4335 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"MASK") == 0)
4339 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"BLEND") == 0)
4345 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"alphaCutoff") == 0)
4348 out_material->
alpha_cutoff = cgltf_json_to_float(tokens + i, json_chunk);
4351 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"doubleSided") == 0)
4355 cgltf_json_to_bool(tokens + i, json_chunk);
4358 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4360 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_material->
extras);
4362 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4366 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4369 return CGLTF_ERROR_JSON;
4372 int extensions_size = tokens[i].size;
4379 return CGLTF_ERROR_NOMEM;
4382 for (
int k = 0; k < extensions_size; ++k)
4384 CGLTF_CHECK_KEY(tokens[i]);
4386 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_pbrSpecularGlossiness") == 0)
4389 i = cgltf_parse_json_pbr_specular_glossiness(options, tokens, i + 1, json_chunk, &out_material->
pbr_specular_glossiness);
4391 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_unlit") == 0)
4393 out_material->
unlit = 1;
4394 i = cgltf_skip_json(tokens, i+1);
4396 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_clearcoat") == 0)
4399 i = cgltf_parse_json_clearcoat(options, tokens, i + 1, json_chunk, &out_material->
clearcoat);
4401 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_ior") == 0)
4404 i = cgltf_parse_json_ior(tokens, i + 1, json_chunk, &out_material->
ior);
4406 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_specular") == 0)
4409 i = cgltf_parse_json_specular(options, tokens, i + 1, json_chunk, &out_material->
specular);
4411 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_transmission") == 0)
4414 i = cgltf_parse_json_transmission(options, tokens, i + 1, json_chunk, &out_material->
transmission);
4416 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_volume") == 0)
4419 i = cgltf_parse_json_volume(options, tokens, i + 1, json_chunk, &out_material->
volume);
4421 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_sheen") == 0)
4424 i = cgltf_parse_json_sheen(options, tokens, i + 1, json_chunk, &out_material->
sheen);
4426 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_emissive_strength") == 0)
4429 i = cgltf_parse_json_emissive_strength(tokens, i + 1, json_chunk, &out_material->
emissive_strength);
4431 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_iridescence") == 0)
4434 i = cgltf_parse_json_iridescence(options, tokens, i + 1, json_chunk, &out_material->
iridescence);
4438 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->
extensions[out_material->
extensions_count++]));
4449 i = cgltf_skip_json(tokens, i+1);
4461 static int cgltf_parse_json_accessors(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4471 i = cgltf_parse_json_accessor(options, tokens, i, json_chunk, &out_data->
accessors[j]);
4480 static int cgltf_parse_json_materials(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4490 i = cgltf_parse_json_material(options, tokens, i, json_chunk, &out_data->
materials[j]);
4499 static int cgltf_parse_json_images(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4509 i = cgltf_parse_json_image(options, tokens, i, json_chunk, &out_data->
images[j]);
4518 static int cgltf_parse_json_textures(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4528 i = cgltf_parse_json_texture(options, tokens, i, json_chunk, &out_data->
textures[j]);
4537 static int cgltf_parse_json_samplers(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4547 i = cgltf_parse_json_sampler(options, tokens, i, json_chunk, &out_data->
samplers[j]);
4559 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4561 int size = tokens[i].size;
4564 for (
int j = 0; j <
size; ++
j)
4566 CGLTF_CHECK_KEY(tokens[i]);
4568 if (cgltf_json_strcmp(tokens+i, json_chunk,
"buffer") == 0)
4571 out_meshopt_compression->
buffer = CGLTF_PTRINDEX(
cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
4574 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
4577 out_meshopt_compression->
offset = cgltf_json_to_size(tokens+i, json_chunk);
4580 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
4583 out_meshopt_compression->
size = cgltf_json_to_size(tokens+i, json_chunk);
4586 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteStride") == 0)
4589 out_meshopt_compression->
stride = cgltf_json_to_size(tokens+i, json_chunk);
4592 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
4595 out_meshopt_compression->
count = cgltf_json_to_int(tokens+i, json_chunk);
4598 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"mode") == 0)
4601 if (cgltf_json_strcmp(tokens+i, json_chunk,
"ATTRIBUTES") == 0)
4605 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"TRIANGLES") == 0)
4609 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"INDICES") == 0)
4615 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"filter") == 0)
4618 if (cgltf_json_strcmp(tokens+i, json_chunk,
"NONE") == 0)
4622 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"OCTAHEDRAL") == 0)
4626 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"QUATERNION") == 0)
4630 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"EXPONENTIAL") == 0)
4638 i = cgltf_skip_json(tokens, i+1);
4650 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)
4652 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4654 int size = tokens[i].size;
4657 for (
int j = 0; j <
size; ++
j)
4659 CGLTF_CHECK_KEY(tokens[i]);
4661 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4663 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer_view->
name);
4665 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"buffer") == 0)
4668 out_buffer_view->
buffer = CGLTF_PTRINDEX(
cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
4671 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
4674 out_buffer_view->
offset =
4675 cgltf_json_to_size(tokens+i, json_chunk);
4678 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
4681 out_buffer_view->
size =
4682 cgltf_json_to_size(tokens+i, json_chunk);
4685 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteStride") == 0)
4688 out_buffer_view->
stride =
4689 cgltf_json_to_size(tokens+i, json_chunk);
4692 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"target") == 0)
4695 int type = cgltf_json_to_int(tokens+i, json_chunk);
4711 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4713 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_buffer_view->
extras);
4715 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4719 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4722 return CGLTF_ERROR_JSON;
4725 int extensions_size = tokens[i].size;
4731 return CGLTF_ERROR_NOMEM;
4735 for (
int k = 0; k < extensions_size; ++k)
4737 CGLTF_CHECK_KEY(tokens[i]);
4739 if (cgltf_json_strcmp(tokens+i, json_chunk,
"EXT_meshopt_compression") == 0)
4742 i = cgltf_parse_json_meshopt_compression(options, tokens, i + 1, json_chunk, &out_buffer_view->
meshopt_compression);
4746 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_buffer_view->
extensions[out_buffer_view->
extensions_count++]));
4757 i = cgltf_skip_json(tokens, i+1);
4769 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)
4779 i = cgltf_parse_json_buffer_view(options, tokens, i, json_chunk, &out_data->
buffer_views[j]);
4788 static int cgltf_parse_json_buffer(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_buffer* out_buffer)
4790 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4792 int size = tokens[i].size;
4795 for (
int j = 0; j <
size; ++
j)
4797 CGLTF_CHECK_KEY(tokens[i]);
4799 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4801 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->
name);
4803 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
4807 cgltf_json_to_size(tokens+i, json_chunk);
4810 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"uri") == 0)
4812 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->
uri);
4814 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4816 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_buffer->
extras);
4818 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4820 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_buffer->
extensions_count, &out_buffer->
extensions);
4824 i = cgltf_skip_json(tokens, i+1);
4836 static int cgltf_parse_json_buffers(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4846 i = cgltf_parse_json_buffer(options, tokens, i, json_chunk, &out_data->
buffers[j]);
4855 static int cgltf_parse_json_skin(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_skin* out_skin)
4857 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4859 int size = tokens[i].size;
4862 for (
int j = 0; j <
size; ++
j)
4864 CGLTF_CHECK_KEY(tokens[i]);
4866 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4868 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_skin->
name);
4870 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"joints") == 0)
4872 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_node*), (
void**)&out_skin->
joints, &out_skin->
joints_count);
4878 for (cgltf_size k = 0; k < out_skin->
joints_count; ++k)
4880 out_skin->
joints[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
4884 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"skeleton") == 0)
4887 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
4888 out_skin->
skeleton = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
4891 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"inverseBindMatrices") == 0)
4894 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
4898 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4900 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_skin->
extras);
4902 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4904 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_skin->
extensions_count, &out_skin->
extensions);
4908 i = cgltf_skip_json(tokens, i+1);
4920 static int cgltf_parse_json_skins(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4922 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_skin), (
void**)&out_data->
skins, &out_data->
skins_count);
4930 i = cgltf_parse_json_skin(options, tokens, i, json_chunk, &out_data->
skins[j]);
4939 static int cgltf_parse_json_camera(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_camera* out_camera)
4941 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4943 int size = tokens[i].size;
4946 for (
int j = 0; j <
size; ++
j)
4948 CGLTF_CHECK_KEY(tokens[i]);
4950 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4952 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_camera->
name);
4954 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
4957 if (cgltf_json_strcmp(tokens + i, json_chunk,
"perspective") == 0)
4961 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"orthographic") == 0)
4967 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"perspective") == 0)
4971 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4973 int data_size = tokens[i].size;
4978 for (
int k = 0; k < data_size; ++k)
4980 CGLTF_CHECK_KEY(tokens[i]);
4982 if (cgltf_json_strcmp(tokens+i, json_chunk,
"aspectRatio") == 0)
4989 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"yfov") == 0)
4995 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"zfar") == 0)
5002 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"znear") == 0)
5008 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5014 i = cgltf_skip_json(tokens, i+1);
5023 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"orthographic") == 0)
5027 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5029 int data_size = tokens[i].size;
5034 for (
int k = 0; k < data_size; ++k)
5036 CGLTF_CHECK_KEY(tokens[i]);
5038 if (cgltf_json_strcmp(tokens+i, json_chunk,
"xmag") == 0)
5044 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"ymag") == 0)
5050 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"zfar") == 0)
5056 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"znear") == 0)
5062 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5068 i = cgltf_skip_json(tokens, i+1);
5077 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5079 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->
extras);
5081 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5083 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_camera->
extensions_count, &out_camera->
extensions);
5087 i = cgltf_skip_json(tokens, i+1);
5099 static int cgltf_parse_json_cameras(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5109 i = cgltf_parse_json_camera(options, tokens, i, json_chunk, &out_data->
cameras[j]);
5118 static int cgltf_parse_json_light(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_light* out_light)
5120 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5122 out_light->
color[0] = 1.f;
5123 out_light->
color[1] = 1.f;
5124 out_light->
color[2] = 1.f;
5130 int size = tokens[i].size;
5133 for (
int j = 0; j <
size; ++
j)
5135 CGLTF_CHECK_KEY(tokens[i]);
5137 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5139 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_light->
name);
5141 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"color") == 0)
5143 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_light->
color, 3);
5145 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"intensity") == 0)
5148 out_light->
intensity = cgltf_json_to_float(tokens + i, json_chunk);
5151 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
5154 if (cgltf_json_strcmp(tokens + i, json_chunk,
"directional") == 0)
5158 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"point") == 0)
5162 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"spot") == 0)
5168 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"range") == 0)
5171 out_light->
range = cgltf_json_to_float(tokens + i, json_chunk);
5174 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"spot") == 0)
5178 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5180 int data_size = tokens[i].size;
5183 for (
int k = 0; k < data_size; ++k)
5185 CGLTF_CHECK_KEY(tokens[i]);
5187 if (cgltf_json_strcmp(tokens+i, json_chunk,
"innerConeAngle") == 0)
5193 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"outerConeAngle") == 0)
5201 i = cgltf_skip_json(tokens, i+1);
5210 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5212 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_light->
extras);
5216 i = cgltf_skip_json(tokens, i+1);
5228 static int cgltf_parse_json_lights(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5238 i = cgltf_parse_json_light(options, tokens, i, json_chunk, &out_data->
lights[j]);
5247 static int cgltf_parse_json_node(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_node* out_node)
5249 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5252 out_node->
scale[0] = 1.0f;
5253 out_node->
scale[1] = 1.0f;
5254 out_node->
scale[2] = 1.0f;
5255 out_node->
matrix[0] = 1.0f;
5256 out_node->
matrix[5] = 1.0f;
5257 out_node->
matrix[10] = 1.0f;
5258 out_node->
matrix[15] = 1.0f;
5260 int size = tokens[i].size;
5263 for (
int j = 0; j <
size; ++
j)
5265 CGLTF_CHECK_KEY(tokens[i]);
5267 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5269 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_node->
name);
5271 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"children") == 0)
5281 out_node->
children[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5285 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"mesh") == 0)
5288 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5289 out_node->
mesh = CGLTF_PTRINDEX(
cgltf_mesh, cgltf_json_to_int(tokens + i, json_chunk));
5292 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"skin") == 0)
5295 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5296 out_node->
skin = CGLTF_PTRINDEX(
cgltf_skin, cgltf_json_to_int(tokens + i, json_chunk));
5299 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"camera") == 0)
5302 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5303 out_node->
camera = CGLTF_PTRINDEX(
cgltf_camera, cgltf_json_to_int(tokens + i, json_chunk));
5306 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"translation") == 0)