92#ifndef CGLTF_H_INCLUDED__
93#define CGLTF_H_INCLUDED__
101typedef size_t cgltf_size;
102typedef float cgltf_float;
103typedef int cgltf_int;
104typedef unsigned int cgltf_uint;
105typedef int cgltf_bool;
107typedef enum cgltf_file_type
109 cgltf_file_type_invalid,
110 cgltf_file_type_gltf,
114typedef enum cgltf_result
116 cgltf_result_success,
117 cgltf_result_data_too_short,
118 cgltf_result_unknown_format,
119 cgltf_result_invalid_json,
120 cgltf_result_invalid_gltf,
121 cgltf_result_invalid_options,
122 cgltf_result_file_not_found,
123 cgltf_result_io_error,
124 cgltf_result_out_of_memory,
125 cgltf_result_legacy_gltf,
130 void* (*alloc)(
void* user, cgltf_size size);
131 void (*free) (
void* user,
void* ptr);
144 cgltf_file_type type;
145 cgltf_size json_token_count;
150typedef enum cgltf_buffer_view_type
152 cgltf_buffer_view_type_invalid,
153 cgltf_buffer_view_type_indices,
154 cgltf_buffer_view_type_vertices,
155} cgltf_buffer_view_type;
157typedef enum cgltf_attribute_type
159 cgltf_attribute_type_invalid,
160 cgltf_attribute_type_position,
161 cgltf_attribute_type_normal,
162 cgltf_attribute_type_tangent,
163 cgltf_attribute_type_texcoord,
164 cgltf_attribute_type_color,
165 cgltf_attribute_type_joints,
166 cgltf_attribute_type_weights,
167} cgltf_attribute_type;
169typedef enum cgltf_component_type
171 cgltf_component_type_invalid,
172 cgltf_component_type_r_8,
173 cgltf_component_type_r_8u,
174 cgltf_component_type_r_16,
175 cgltf_component_type_r_16u,
176 cgltf_component_type_r_32u,
177 cgltf_component_type_r_32f,
178} cgltf_component_type;
180typedef enum cgltf_type
192typedef enum cgltf_primitive_type
194 cgltf_primitive_type_points,
195 cgltf_primitive_type_lines,
196 cgltf_primitive_type_line_loop,
197 cgltf_primitive_type_line_strip,
198 cgltf_primitive_type_triangles,
199 cgltf_primitive_type_triangle_strip,
200 cgltf_primitive_type_triangle_fan,
201} cgltf_primitive_type;
203typedef enum cgltf_alpha_mode
205 cgltf_alpha_mode_opaque,
206 cgltf_alpha_mode_mask,
207 cgltf_alpha_mode_blend,
210typedef enum cgltf_animation_path_type {
211 cgltf_animation_path_type_invalid,
212 cgltf_animation_path_type_translation,
213 cgltf_animation_path_type_rotation,
214 cgltf_animation_path_type_scale,
215 cgltf_animation_path_type_weights,
216} cgltf_animation_path_type;
218typedef enum cgltf_interpolation_type {
219 cgltf_interpolation_type_linear,
220 cgltf_interpolation_type_step,
221 cgltf_interpolation_type_cubic_spline,
222} cgltf_interpolation_type;
224typedef enum cgltf_camera_type {
225 cgltf_camera_type_invalid,
226 cgltf_camera_type_perspective,
227 cgltf_camera_type_orthographic,
230typedef enum cgltf_light_type {
231 cgltf_light_type_invalid,
232 cgltf_light_type_directional,
233 cgltf_light_type_point,
234 cgltf_light_type_spot,
237typedef enum cgltf_data_free_method {
238 cgltf_data_free_method_none,
239 cgltf_data_free_method_file_release,
240 cgltf_data_free_method_memory_free,
241} cgltf_data_free_method;
244 cgltf_size start_offset;
245 cgltf_size end_offset;
259 cgltf_data_free_method data_free_method;
261 cgltf_size extensions_count;
265typedef enum cgltf_meshopt_compression_mode {
266 cgltf_meshopt_compression_mode_invalid,
267 cgltf_meshopt_compression_mode_attributes,
268 cgltf_meshopt_compression_mode_triangles,
269 cgltf_meshopt_compression_mode_indices,
270} cgltf_meshopt_compression_mode;
272typedef enum cgltf_meshopt_compression_filter {
273 cgltf_meshopt_compression_filter_none,
274 cgltf_meshopt_compression_filter_octahedral,
275 cgltf_meshopt_compression_filter_quaternion,
276 cgltf_meshopt_compression_filter_exponential,
277} cgltf_meshopt_compression_filter;
286 cgltf_meshopt_compression_mode mode;
287 cgltf_meshopt_compression_filter filter;
297 cgltf_buffer_view_type type;
299 cgltf_bool has_meshopt_compression;
302 cgltf_size extensions_count;
310 cgltf_size indices_byte_offset;
311 cgltf_component_type indices_component_type;
313 cgltf_size values_byte_offset;
317 cgltf_size extensions_count;
319 cgltf_size indices_extensions_count;
321 cgltf_size values_extensions_count;
328 cgltf_component_type component_type;
329 cgltf_bool normalized;
339 cgltf_bool is_sparse;
342 cgltf_size extensions_count;
349 cgltf_attribute_type type;
361 cgltf_size extensions_count;
368 cgltf_int mag_filter;
369 cgltf_int min_filter;
373 cgltf_size extensions_count;
382 cgltf_bool has_basisu;
385 cgltf_size extensions_count;
391 cgltf_float offset[2];
392 cgltf_float rotation;
393 cgltf_float scale[2];
394 cgltf_bool has_texcoord;
403 cgltf_bool has_transform;
406 cgltf_size extensions_count;
415 cgltf_float base_color_factor[4];
416 cgltf_float metallic_factor;
417 cgltf_float roughness_factor;
427 cgltf_float diffuse_factor[4];
428 cgltf_float specular_factor[3];
429 cgltf_float glossiness_factor;
438 cgltf_float clearcoat_factor;
439 cgltf_float clearcoat_roughness_factor;
445 cgltf_float transmission_factor;
457 cgltf_float specular_color_factor[3];
458 cgltf_float specular_factor;
464 cgltf_float thickness_factor;
465 cgltf_float attenuation_color[3];
466 cgltf_float attenuation_distance;
472 cgltf_float sheen_color_factor[3];
474 cgltf_float sheen_roughness_factor;
479 cgltf_float emissive_strength;
485 cgltf_bool has_pbr_metallic_roughness;
486 cgltf_bool has_pbr_specular_glossiness;
487 cgltf_bool has_clearcoat;
488 cgltf_bool has_transmission;
489 cgltf_bool has_volume;
491 cgltf_bool has_specular;
492 cgltf_bool has_sheen;
493 cgltf_bool has_emissive_strength;
506 cgltf_float emissive_factor[3];
507 cgltf_alpha_mode alpha_mode;
508 cgltf_float alpha_cutoff;
509 cgltf_bool double_sided;
512 cgltf_size extensions_count;
525 cgltf_size attributes_count;
531 cgltf_size attributes_count;
535 cgltf_primitive_type type;
539 cgltf_size attributes_count;
541 cgltf_size targets_count;
543 cgltf_bool has_draco_mesh_compression;
546 cgltf_size mappings_count;
547 cgltf_size extensions_count;
554 cgltf_size primitives_count;
555 cgltf_float* weights;
556 cgltf_size weights_count;
558 cgltf_size target_names_count;
560 cgltf_size extensions_count;
569 cgltf_size joints_count;
573 cgltf_size extensions_count;
578 cgltf_bool has_aspect_ratio;
579 cgltf_float aspect_ratio;
597 cgltf_camera_type type;
603 cgltf_size extensions_count;
609 cgltf_float color[3];
610 cgltf_float intensity;
611 cgltf_light_type type;
613 cgltf_float spot_inner_cone_angle;
614 cgltf_float spot_outer_cone_angle;
622 cgltf_size children_count;
627 cgltf_float* weights;
628 cgltf_size weights_count;
629 cgltf_bool has_translation;
630 cgltf_bool has_rotation;
631 cgltf_bool has_scale;
632 cgltf_bool has_matrix;
633 cgltf_float translation[3];
634 cgltf_float rotation[4];
635 cgltf_float scale[3];
636 cgltf_float matrix[16];
638 cgltf_size extensions_count;
645 cgltf_size nodes_count;
647 cgltf_size extensions_count;
654 cgltf_interpolation_type interpolation;
656 cgltf_size extensions_count;
663 cgltf_animation_path_type target_path;
665 cgltf_size extensions_count;
672 cgltf_size samplers_count;
674 cgltf_size channels_count;
676 cgltf_size extensions_count;
692 cgltf_size extensions_count;
698 cgltf_file_type file_type;
704 cgltf_size meshes_count;
707 cgltf_size materials_count;
710 cgltf_size accessors_count;
713 cgltf_size buffer_views_count;
716 cgltf_size buffers_count;
719 cgltf_size images_count;
722 cgltf_size textures_count;
725 cgltf_size samplers_count;
728 cgltf_size skins_count;
731 cgltf_size cameras_count;
734 cgltf_size lights_count;
737 cgltf_size nodes_count;
740 cgltf_size scenes_count;
745 cgltf_size animations_count;
748 cgltf_size variants_count;
752 cgltf_size data_extensions_count;
755 char** extensions_used;
756 cgltf_size extensions_used_count;
758 char** extensions_required;
759 cgltf_size extensions_required_count;
762 cgltf_size json_size;
771cgltf_result cgltf_parse(
777cgltf_result cgltf_parse_file(
782cgltf_result cgltf_load_buffers(
785 const char* gltf_path);
787cgltf_result cgltf_load_buffer_base64(
const cgltf_options* options, cgltf_size size,
const char* base64,
void** out_data);
789cgltf_size cgltf_decode_string(
char*
string);
790cgltf_size cgltf_decode_uri(
char* uri);
796void cgltf_node_transform_local(
const cgltf_node* node, cgltf_float* out_matrix);
797void cgltf_node_transform_world(
const cgltf_node* node, cgltf_float* out_matrix);
799cgltf_bool cgltf_accessor_read_float(
const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size);
800cgltf_bool cgltf_accessor_read_uint(
const cgltf_accessor* accessor, cgltf_size index, cgltf_uint* out, cgltf_size element_size);
801cgltf_size cgltf_accessor_read_index(
const cgltf_accessor* accessor, cgltf_size index);
803cgltf_size cgltf_num_components(cgltf_type type);
805cgltf_size cgltf_accessor_unpack_floats(
const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count);
807cgltf_result cgltf_copy_extras_json(
const cgltf_data* data,
const cgltf_extras* extras,
char* dest, cgltf_size* dest_size);
822#if defined(__INTELLISENSE__) || defined(__JETBRAINS_IDE__)
824#define CGLTF_IMPLEMENTATION
827#ifdef CGLTF_IMPLEMENTATION
835#if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF) || !defined(CGLTF_ATOLL)
840#define JSMN_PARENT_LINKS
859 JSMN_ERROR_NOMEM = -1,
861 JSMN_ERROR_INVAL = -2,
870#ifdef JSMN_PARENT_LINKS
876 unsigned int toknext;
879static void jsmn_init(jsmn_parser *parser);
880static int jsmn_parse(jsmn_parser *parser,
const char *js,
size_t len, jsmntok_t *tokens,
size_t num_tokens);
886static const cgltf_size GlbHeaderSize = 12;
887static const cgltf_size GlbChunkHeaderSize = 8;
888static const uint32_t GlbVersion = 2;
889static const uint32_t GlbMagic = 0x46546C67;
890static const uint32_t GlbMagicJsonChunk = 0x4E4F534A;
891static const uint32_t GlbMagicBinChunk = 0x004E4942;
894#define CGLTF_MALLOC(size) malloc(size)
897#define CGLTF_FREE(ptr) free(ptr)
900#define CGLTF_ATOI(str) atoi(str)
903#define CGLTF_ATOF(str) atof(str)
906#define CGLTF_ATOLL(str) atoll(str)
908#ifndef CGLTF_VALIDATE_ENABLE_ASSERTS
909#define CGLTF_VALIDATE_ENABLE_ASSERTS 0
912static void* cgltf_default_alloc(
void* user, cgltf_size size)
915 return CGLTF_MALLOC(size);
918static void cgltf_default_free(
void* user,
void* ptr)
924static void* cgltf_calloc(
cgltf_options* options,
size_t element_size, cgltf_size count)
926 if (SIZE_MAX / element_size < count)
930 void* result = options->memory.alloc(options->memory.user_data, element_size * count);
935 memset(result, 0, element_size * count);
939static cgltf_result cgltf_default_file_read(
const struct cgltf_memory_options* memory_options,
const struct cgltf_file_options* file_options,
const char* path, cgltf_size* size,
void** data)
942 void* (*memory_alloc)(
void*, cgltf_size) = memory_options->alloc ? memory_options->alloc : &cgltf_default_alloc;
943 void (*memory_free)(
void*,
void*) = memory_options->free ? memory_options->free : &cgltf_default_free;
945 FILE* file = fopen(path,
"rb");
948 return cgltf_result_file_not_found;
951 cgltf_size file_size = size ? *size : 0;
955 fseek(file, 0, SEEK_END);
958 __int64 length = _ftelli64(file);
960 long length = ftell(file);
966 return cgltf_result_io_error;
969 fseek(file, 0, SEEK_SET);
970 file_size = (cgltf_size)length;
973 char* file_data = (
char*)memory_alloc(memory_options->user_data, file_size);
977 return cgltf_result_out_of_memory;
980 cgltf_size read_size = fread(file_data, 1, file_size, file);
984 if (read_size != file_size)
986 memory_free(memory_options->user_data, file_data);
987 return cgltf_result_io_error;
999 return cgltf_result_success;
1005 void (*memfree)(
void*,
void*) = memory_options->free ? memory_options->free : &cgltf_default_free;
1006 memfree(memory_options->user_data, data);
1009static cgltf_result cgltf_parse_json(
cgltf_options* options,
const uint8_t* json_chunk, cgltf_size size,
cgltf_data** out_data);
1011cgltf_result cgltf_parse(
const cgltf_options* options,
const void* data, cgltf_size size,
cgltf_data** out_data)
1013 if (size < GlbHeaderSize)
1015 return cgltf_result_data_too_short;
1018 if (options == NULL)
1020 return cgltf_result_invalid_options;
1024 if (fixed_options.memory.alloc == NULL)
1026 fixed_options.memory.alloc = &cgltf_default_alloc;
1028 if (fixed_options.memory.free == NULL)
1030 fixed_options.memory.free = &cgltf_default_free;
1035 memcpy(&tmp, data, 4);
1036 if (tmp != GlbMagic)
1038 if (fixed_options.type == cgltf_file_type_invalid)
1040 fixed_options.type = cgltf_file_type_gltf;
1042 else if (fixed_options.type == cgltf_file_type_glb)
1044 return cgltf_result_unknown_format;
1048 if (fixed_options.type == cgltf_file_type_gltf)
1050 cgltf_result json_result = cgltf_parse_json(&fixed_options, (
const uint8_t*)data, size, out_data);
1051 if (json_result != cgltf_result_success)
1056 (*out_data)->file_type = cgltf_file_type_gltf;
1058 return cgltf_result_success;
1061 const uint8_t* ptr = (
const uint8_t*)data;
1063 memcpy(&tmp, ptr + 4, 4);
1064 uint32_t version = tmp;
1065 if (version != GlbVersion)
1067 return version < GlbVersion ? cgltf_result_legacy_gltf : cgltf_result_unknown_format;
1071 memcpy(&tmp, ptr + 8, 4);
1074 return cgltf_result_data_too_short;
1077 const uint8_t* json_chunk = ptr + GlbHeaderSize;
1079 if (GlbHeaderSize + GlbChunkHeaderSize > size)
1081 return cgltf_result_data_too_short;
1085 uint32_t json_length;
1086 memcpy(&json_length, json_chunk, 4);
1087 if (GlbHeaderSize + GlbChunkHeaderSize + json_length > size)
1089 return cgltf_result_data_too_short;
1093 memcpy(&tmp, json_chunk + 4, 4);
1094 if (tmp != GlbMagicJsonChunk)
1096 return cgltf_result_unknown_format;
1099 json_chunk += GlbChunkHeaderSize;
1101 const void* bin = 0;
1102 cgltf_size bin_size = 0;
1104 if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size)
1107 const uint8_t* bin_chunk = json_chunk + json_length;
1110 uint32_t bin_length;
1111 memcpy(&bin_length, bin_chunk, 4);
1112 if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize + bin_length > size)
1114 return cgltf_result_data_too_short;
1118 memcpy(&tmp, bin_chunk + 4, 4);
1119 if (tmp != GlbMagicBinChunk)
1121 return cgltf_result_unknown_format;
1124 bin_chunk += GlbChunkHeaderSize;
1127 bin_size = bin_length;
1130 cgltf_result json_result = cgltf_parse_json(&fixed_options, json_chunk, json_length, out_data);
1131 if (json_result != cgltf_result_success)
1136 (*out_data)->file_type = cgltf_file_type_glb;
1137 (*out_data)->bin = bin;
1138 (*out_data)->bin_size = bin_size;
1140 return cgltf_result_success;
1145 if (options == NULL)
1147 return cgltf_result_invalid_options;
1150 cgltf_result (*file_read)(
const struct cgltf_memory_options*,
const struct cgltf_file_options*,
const char*, cgltf_size*,
void**) = options->file.read ? options->file.read : &cgltf_default_file_read;
1153 void* file_data = NULL;
1154 cgltf_size file_size = 0;
1155 cgltf_result result = file_read(&options->memory, &options->file, path, &file_size, &file_data);
1156 if (result != cgltf_result_success)
1161 result = cgltf_parse(options, file_data, file_size, out_data);
1163 if (result != cgltf_result_success)
1165 file_release(&options->memory, &options->file, file_data);
1169 (*out_data)->file_data = file_data;
1171 return cgltf_result_success;
1174static void cgltf_combine_paths(
char* path,
const char* base,
const char* uri)
1176 const char* s0 = strrchr(base,
'/');
1177 const char* s1 = strrchr(base,
'\\');
1178 const char* slash = s0 ? (s1 && s1 > s0 ? s1 : s0) : s1;
1182 size_t prefix = slash - base + 1;
1184 strncpy(path, base, prefix);
1185 strcpy(path + prefix, uri);
1193static cgltf_result cgltf_load_buffer_file(
const cgltf_options* options, cgltf_size size,
const char* uri,
const char* gltf_path,
void** out_data)
1195 void* (*memory_alloc)(
void*, cgltf_size) = options->memory.alloc ? options->memory.alloc : &cgltf_default_alloc;
1196 void (*memory_free)(
void*,
void*) = options->memory.free ? options->memory.free : &cgltf_default_free;
1197 cgltf_result (*file_read)(
const struct cgltf_memory_options*,
const struct cgltf_file_options*,
const char*, cgltf_size*,
void**) = options->file.read ? options->file.read : &cgltf_default_file_read;
1199 char* path = (
char*)memory_alloc(options->memory.user_data, strlen(uri) + strlen(gltf_path) + 1);
1202 return cgltf_result_out_of_memory;
1205 cgltf_combine_paths(path, gltf_path, uri);
1208 cgltf_decode_uri(path + strlen(path) - strlen(uri));
1210 void* file_data = NULL;
1211 cgltf_result result = file_read(&options->memory, &options->file, path, &size, &file_data);
1213 memory_free(options->memory.user_data, path);
1215 *out_data = (result == cgltf_result_success) ? file_data : NULL;
1220cgltf_result cgltf_load_buffer_base64(
const cgltf_options* options, cgltf_size size,
const char* base64,
void** out_data)
1222 void* (*memory_alloc)(
void*, cgltf_size) = options->memory.alloc ? options->memory.alloc : &cgltf_default_alloc;
1223 void (*memory_free)(
void*,
void*) = options->memory.free ? options->memory.free : &cgltf_default_free;
1225 unsigned char* data = (
unsigned char*)memory_alloc(options->memory.user_data, size);
1228 return cgltf_result_out_of_memory;
1231 unsigned int buffer = 0;
1232 unsigned int buffer_bits = 0;
1234 for (cgltf_size i = 0; i < size; ++i)
1236 while (buffer_bits < 8)
1238 char ch = *base64++;
1241 (unsigned)(ch -
'A') < 26 ? (ch -
'A') :
1242 (
unsigned)(ch -
'a') < 26 ? (ch -
'a') + 26 :
1243 (unsigned)(ch -
'0') < 10 ? (ch -
'0') + 52 :
1250 memory_free(options->memory.user_data, data);
1251 return cgltf_result_io_error;
1254 buffer = (buffer << 6) | index;
1258 data[i] = (
unsigned char)(buffer >> (buffer_bits - 8));
1264 return cgltf_result_success;
1267static int cgltf_unhex(
char ch)
1270 (
unsigned)(ch -
'0') < 10 ? (ch -
'0') :
1271 (unsigned)(ch -
'A') < 6 ? (ch -
'A') + 10 :
1272 (
unsigned)(ch -
'a') < 6 ? (ch -
'a') + 10 :
1276cgltf_size cgltf_decode_string(
char*
string)
1278 char* read =
string + strcspn(
string,
"\\");
1281 return read - string;
1283 char* write = string;
1284 char* last = string;
1289 cgltf_size written = read - last;
1290 memmove(write, last, written);
1301 case '\"': *write++ =
'\"';
break;
1302 case '/': *write++ =
'/';
break;
1303 case '\\': *write++ =
'\\';
break;
1304 case 'b': *write++ =
'\b';
break;
1305 case 'f': *write++ =
'\f';
break;
1306 case 'r': *write++ =
'\r';
break;
1307 case 'n': *write++ =
'\n';
break;
1308 case 't': *write++ =
'\t';
break;
1313 for (cgltf_size i = 0; i < 4; ++i)
1315 character = (character << 4) + cgltf_unhex(*read++);
1318 if (character <= 0x7F)
1320 *write++ = character & 0xFF;
1322 else if (character <= 0x7FF)
1324 *write++ = 0xC0 | ((character >> 6) & 0xFF);
1325 *write++ = 0x80 | (character & 0x3F);
1329 *write++ = 0xE0 | ((character >> 12) & 0xFF);
1330 *write++ = 0x80 | ((character >> 6) & 0x3F);
1331 *write++ = 0x80 | (character & 0x3F);
1340 read += strcspn(read,
"\\");
1344 return write - string;
1347cgltf_size cgltf_decode_uri(
char* uri)
1356 int ch1 = cgltf_unhex(i[1]);
1360 int ch2 = cgltf_unhex(i[2]);
1364 *write++ = (char)(ch1 * 16 + ch2);
1380 if (options == NULL)
1382 return cgltf_result_invalid_options;
1385 if (data->buffers_count && data->buffers[0].data == NULL && data->buffers[0].uri == NULL && data->bin)
1387 if (data->bin_size < data->buffers[0].size)
1389 return cgltf_result_data_too_short;
1392 data->buffers[0].data = (
void*)data->bin;
1393 data->buffers[0].data_free_method = cgltf_data_free_method_none;
1396 for (cgltf_size i = 0; i < data->buffers_count; ++i)
1398 if (data->buffers[i].data)
1403 const char* uri = data->buffers[i].uri;
1410 if (strncmp(uri,
"data:", 5) == 0)
1412 const char* comma = strchr(uri,
',');
1414 if (comma && comma - uri >= 7 && strncmp(comma - 7,
";base64", 7) == 0)
1416 cgltf_result res = cgltf_load_buffer_base64(options, data->buffers[i].size, comma + 1, &data->buffers[i].data);
1417 data->buffers[i].data_free_method = cgltf_data_free_method_memory_free;
1419 if (res != cgltf_result_success)
1426 return cgltf_result_unknown_format;
1429 else if (strstr(uri,
"://") == NULL && gltf_path)
1431 cgltf_result res = cgltf_load_buffer_file(options, data->buffers[i].size, uri, gltf_path, &data->buffers[i].data);
1432 data->buffers[i].data_free_method = cgltf_data_free_method_file_release;
1434 if (res != cgltf_result_success)
1441 return cgltf_result_unknown_format;
1445 return cgltf_result_success;
1448static cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type);
1450static cgltf_size cgltf_calc_index_bound(
cgltf_buffer_view* buffer_view, cgltf_size offset, cgltf_component_type component_type, cgltf_size count)
1452 char* data = (
char*)buffer_view->buffer->data + offset + buffer_view->offset;
1453 cgltf_size bound = 0;
1455 switch (component_type)
1457 case cgltf_component_type_r_8u:
1458 for (
size_t i = 0; i < count; ++i)
1460 cgltf_size v = ((
unsigned char*)data)[i];
1461 bound = bound > v ? bound : v;
1465 case cgltf_component_type_r_16u:
1466 for (
size_t i = 0; i < count; ++i)
1468 cgltf_size v = ((
unsigned short*)data)[i];
1469 bound = bound > v ? bound : v;
1473 case cgltf_component_type_r_32u:
1474 for (
size_t i = 0; i < count; ++i)
1476 cgltf_size v = ((
unsigned int*)data)[i];
1477 bound = bound > v ? bound : v;
1488#if CGLTF_VALIDATE_ENABLE_ASSERTS
1489#define CGLTF_ASSERT_IF(cond, result) assert(!(cond)); if (cond) return result;
1491#define CGLTF_ASSERT_IF(cond, result) if (cond) return result;
1496 for (cgltf_size i = 0; i < data->accessors_count; ++i)
1500 cgltf_size element_size = cgltf_calc_size(accessor->type, accessor->component_type);
1502 if (accessor->buffer_view)
1504 cgltf_size req_size = accessor->offset + accessor->stride * (accessor->count - 1) + element_size;
1506 CGLTF_ASSERT_IF(accessor->buffer_view->size < req_size, cgltf_result_data_too_short);
1509 if (accessor->is_sparse)
1513 cgltf_size indices_component_size = cgltf_calc_size(cgltf_type_scalar, sparse->indices_component_type);
1514 cgltf_size indices_req_size = sparse->indices_byte_offset + indices_component_size * sparse->count;
1515 cgltf_size values_req_size = sparse->values_byte_offset + element_size * sparse->count;
1517 CGLTF_ASSERT_IF(sparse->indices_buffer_view->size < indices_req_size ||
1518 sparse->values_buffer_view->size < values_req_size, cgltf_result_data_too_short);
1520 CGLTF_ASSERT_IF(sparse->indices_component_type != cgltf_component_type_r_8u &&
1521 sparse->indices_component_type != cgltf_component_type_r_16u &&
1522 sparse->indices_component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
1524 if (sparse->indices_buffer_view->buffer->data)
1526 cgltf_size index_bound = cgltf_calc_index_bound(sparse->indices_buffer_view, sparse->indices_byte_offset, sparse->indices_component_type, sparse->count);
1528 CGLTF_ASSERT_IF(index_bound >= accessor->count, cgltf_result_data_too_short);
1533 for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
1535 cgltf_size req_size = data->buffer_views[i].offset + data->buffer_views[i].size;
1537 CGLTF_ASSERT_IF(data->buffer_views[i].buffer && data->buffer_views[i].buffer->size < req_size, cgltf_result_data_too_short);
1539 if (data->buffer_views[i].has_meshopt_compression)
1543 CGLTF_ASSERT_IF(mc->buffer == NULL || mc->buffer->size < mc->offset + mc->size, cgltf_result_data_too_short);
1545 CGLTF_ASSERT_IF(data->buffer_views[i].stride && mc->stride != data->buffer_views[i].stride, cgltf_result_invalid_gltf);
1547 CGLTF_ASSERT_IF(data->buffer_views[i].size != mc->stride * mc->count, cgltf_result_invalid_gltf);
1549 CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_invalid, cgltf_result_invalid_gltf);
1551 CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_attributes && !(mc->stride % 4 == 0 && mc->stride <= 256), cgltf_result_invalid_gltf);
1553 CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_triangles && mc->count % 3 != 0, cgltf_result_invalid_gltf);
1555 CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->stride != 2 && mc->stride != 4, cgltf_result_invalid_gltf);
1557 CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->filter != cgltf_meshopt_compression_filter_none, cgltf_result_invalid_gltf);
1559 CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8, cgltf_result_invalid_gltf);
1561 CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8, cgltf_result_invalid_gltf);
1565 for (cgltf_size i = 0; i < data->meshes_count; ++i)
1567 if (data->meshes[i].weights)
1569 CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].weights_count, cgltf_result_invalid_gltf);
1572 if (data->meshes[i].target_names)
1574 CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].target_names_count, cgltf_result_invalid_gltf);
1577 for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
1579 CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count, cgltf_result_invalid_gltf);
1581 if (data->meshes[i].primitives[j].attributes_count)
1583 cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data;
1585 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
1587 CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
1590 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
1592 for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
1594 CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf);
1600 CGLTF_ASSERT_IF(indices &&
1601 indices->component_type != cgltf_component_type_r_8u &&
1602 indices->component_type != cgltf_component_type_r_16u &&
1603 indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
1605 if (indices && indices->buffer_view && indices->buffer_view->buffer->data)
1607 cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count);
1609 CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short);
1612 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
1614 CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf);
1620 for (cgltf_size i = 0; i < data->nodes_count; ++i)
1622 if (data->nodes[i].weights && data->nodes[i].mesh)
1624 CGLTF_ASSERT_IF (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf);
1628 for (cgltf_size i = 0; i < data->nodes_count; ++i)
1635 CGLTF_ASSERT_IF(p1 == p2, cgltf_result_invalid_gltf);
1638 p2 = p2->parent ? p2->parent->parent : NULL;
1642 for (cgltf_size i = 0; i < data->scenes_count; ++i)
1644 for (cgltf_size j = 0; j < data->scenes[i].nodes_count; ++j)
1646 CGLTF_ASSERT_IF(data->scenes[i].nodes[j]->parent, cgltf_result_invalid_gltf);
1650 for (cgltf_size i = 0; i < data->animations_count; ++i)
1652 for (cgltf_size j = 0; j < data->animations[i].channels_count; ++j)
1656 if (!channel->target_node)
1661 cgltf_size components = 1;
1663 if (channel->target_path == cgltf_animation_path_type_weights)
1665 CGLTF_ASSERT_IF(!channel->target_node->mesh || !channel->target_node->mesh->primitives_count, cgltf_result_invalid_gltf);
1667 components = channel->target_node->mesh->primitives[0].targets_count;
1670 cgltf_size values = channel->sampler->interpolation == cgltf_interpolation_type_cubic_spline ? 3 : 1;
1672 CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_data_too_short);
1676 return cgltf_result_success;
1679cgltf_result cgltf_copy_extras_json(
const cgltf_data* data,
const cgltf_extras* extras,
char* dest, cgltf_size* dest_size)
1681 cgltf_size json_size = extras->end_offset - extras->start_offset;
1687 *dest_size = json_size + 1;
1688 return cgltf_result_success;
1690 return cgltf_result_invalid_options;
1693 if (*dest_size + 1 < json_size)
1695 strncpy(dest, data->json + extras->start_offset, *dest_size - 1);
1696 dest[*dest_size - 1] = 0;
1700 strncpy(dest, data->json + extras->start_offset, json_size);
1701 dest[json_size] = 0;
1704 return cgltf_result_success;
1709 for (cgltf_size i = 0; i < extensions_count; ++i)
1711 data->memory.free(data->memory.user_data, extensions[i].name);
1712 data->memory.free(data->memory.user_data, extensions[i].data);
1714 data->memory.free(data->memory.user_data, extensions);
1726 data->memory.free(data->memory.user_data, data->asset.copyright);
1727 data->memory.free(data->memory.user_data, data->asset.generator);
1728 data->memory.free(data->memory.user_data, data->asset.version);
1729 data->memory.free(data->memory.user_data, data->asset.min_version);
1731 cgltf_free_extensions(data, data->asset.extensions, data->asset.extensions_count);
1733 for (cgltf_size i = 0; i < data->accessors_count; ++i)
1735 data->memory.free(data->memory.user_data, data->accessors[i].name);
1737 if(data->accessors[i].is_sparse)
1739 cgltf_free_extensions(data, data->accessors[i].sparse.extensions, data->accessors[i].sparse.extensions_count);
1740 cgltf_free_extensions(data, data->accessors[i].sparse.indices_extensions, data->accessors[i].sparse.indices_extensions_count);
1741 cgltf_free_extensions(data, data->accessors[i].sparse.values_extensions, data->accessors[i].sparse.values_extensions_count);
1743 cgltf_free_extensions(data, data->accessors[i].extensions, data->accessors[i].extensions_count);
1745 data->memory.free(data->memory.user_data, data->accessors);
1747 for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
1749 data->memory.free(data->memory.user_data, data->buffer_views[i].name);
1750 data->memory.free(data->memory.user_data, data->buffer_views[i].data);
1752 cgltf_free_extensions(data, data->buffer_views[i].extensions, data->buffer_views[i].extensions_count);
1754 data->memory.free(data->memory.user_data, data->buffer_views);
1756 for (cgltf_size i = 0; i < data->buffers_count; ++i)
1758 data->memory.free(data->memory.user_data, data->buffers[i].name);
1760 if (data->buffers[i].data_free_method == cgltf_data_free_method_file_release)
1762 file_release(&data->memory, &data->file, data->buffers[i].data);
1764 else if (data->buffers[i].data_free_method == cgltf_data_free_method_memory_free)
1766 data->memory.free(data->memory.user_data, data->buffers[i].data);
1769 data->memory.free(data->memory.user_data, data->buffers[i].uri);
1771 cgltf_free_extensions(data, data->buffers[i].extensions, data->buffers[i].extensions_count);
1774 data->memory.free(data->memory.user_data, data->buffers);
1776 for (cgltf_size i = 0; i < data->meshes_count; ++i)
1778 data->memory.free(data->memory.user_data, data->meshes[i].name);
1780 for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
1782 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
1784 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].attributes[k].name);
1787 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].attributes);
1789 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
1791 for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
1793 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].targets[k].attributes[m].name);
1796 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].targets[k].attributes);
1799 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].targets);
1801 if (data->meshes[i].primitives[j].has_draco_mesh_compression)
1803 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].draco_mesh_compression.attributes_count; ++k)
1805 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes[k].name);
1808 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes);
1811 data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].mappings);
1813 cgltf_free_extensions(data, data->meshes[i].primitives[j].extensions, data->meshes[i].primitives[j].extensions_count);
1816 data->memory.free(data->memory.user_data, data->meshes[i].primitives);
1817 data->memory.free(data->memory.user_data, data->meshes[i].weights);
1819 for (cgltf_size j = 0; j < data->meshes[i].target_names_count; ++j)
1821 data->memory.free(data->memory.user_data, data->meshes[i].target_names[j]);
1824 cgltf_free_extensions(data, data->meshes[i].extensions, data->meshes[i].extensions_count);
1826 data->memory.free(data->memory.user_data, data->meshes[i].target_names);
1829 data->memory.free(data->memory.user_data, data->meshes);
1831 for (cgltf_size i = 0; i < data->materials_count; ++i)
1833 data->memory.free(data->memory.user_data, data->materials[i].name);
1835 if(data->materials[i].has_pbr_metallic_roughness)
1837 cgltf_free_extensions(data, data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.extensions, data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.extensions_count);
1838 cgltf_free_extensions(data, data->materials[i].pbr_metallic_roughness.base_color_texture.extensions, data->materials[i].pbr_metallic_roughness.base_color_texture.extensions_count);
1840 if(data->materials[i].has_pbr_specular_glossiness)
1842 cgltf_free_extensions(data, data->materials[i].pbr_specular_glossiness.diffuse_texture.extensions, data->materials[i].pbr_specular_glossiness.diffuse_texture.extensions_count);
1843 cgltf_free_extensions(data, data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.extensions, data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.extensions_count);
1845 if(data->materials[i].has_clearcoat)
1847 cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_texture.extensions, data->materials[i].clearcoat.clearcoat_texture.extensions_count);
1848 cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_roughness_texture.extensions, data->materials[i].clearcoat.clearcoat_roughness_texture.extensions_count);
1849 cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_normal_texture.extensions, data->materials[i].clearcoat.clearcoat_normal_texture.extensions_count);
1851 if(data->materials[i].has_specular)
1853 cgltf_free_extensions(data, data->materials[i].specular.specular_texture.extensions, data->materials[i].specular.specular_texture.extensions_count);
1854 cgltf_free_extensions(data, data->materials[i].specular.specular_color_texture.extensions, data->materials[i].specular.specular_color_texture.extensions_count);
1856 if(data->materials[i].has_transmission)
1858 cgltf_free_extensions(data, data->materials[i].transmission.transmission_texture.extensions, data->materials[i].transmission.transmission_texture.extensions_count);
1860 if (data->materials[i].has_volume)
1862 cgltf_free_extensions(data, data->materials[i].volume.thickness_texture.extensions, data->materials[i].volume.thickness_texture.extensions_count);
1864 if(data->materials[i].has_sheen)
1866 cgltf_free_extensions(data, data->materials[i].sheen.sheen_color_texture.extensions, data->materials[i].sheen.sheen_color_texture.extensions_count);
1867 cgltf_free_extensions(data, data->materials[i].sheen.sheen_roughness_texture.extensions, data->materials[i].sheen.sheen_roughness_texture.extensions_count);
1870 cgltf_free_extensions(data, data->materials[i].normal_texture.extensions, data->materials[i].normal_texture.extensions_count);
1871 cgltf_free_extensions(data, data->materials[i].occlusion_texture.extensions, data->materials[i].occlusion_texture.extensions_count);
1872 cgltf_free_extensions(data, data->materials[i].emissive_texture.extensions, data->materials[i].emissive_texture.extensions_count);
1874 cgltf_free_extensions(data, data->materials[i].extensions, data->materials[i].extensions_count);
1877 data->memory.free(data->memory.user_data, data->materials);
1879 for (cgltf_size i = 0; i < data->images_count; ++i)
1881 data->memory.free(data->memory.user_data, data->images[i].name);
1882 data->memory.free(data->memory.user_data, data->images[i].uri);
1883 data->memory.free(data->memory.user_data, data->images[i].mime_type);
1885 cgltf_free_extensions(data, data->images[i].extensions, data->images[i].extensions_count);
1888 data->memory.free(data->memory.user_data, data->images);
1890 for (cgltf_size i = 0; i < data->textures_count; ++i)
1892 data->memory.free(data->memory.user_data, data->textures[i].name);
1893 cgltf_free_extensions(data, data->textures[i].extensions, data->textures[i].extensions_count);
1896 data->memory.free(data->memory.user_data, data->textures);
1898 for (cgltf_size i = 0; i < data->samplers_count; ++i)
1900 data->memory.free(data->memory.user_data, data->samplers[i].name);
1901 cgltf_free_extensions(data, data->samplers[i].extensions, data->samplers[i].extensions_count);
1904 data->memory.free(data->memory.user_data, data->samplers);
1906 for (cgltf_size i = 0; i < data->skins_count; ++i)
1908 data->memory.free(data->memory.user_data, data->skins[i].name);
1909 data->memory.free(data->memory.user_data, data->skins[i].joints);
1911 cgltf_free_extensions(data, data->skins[i].extensions, data->skins[i].extensions_count);
1914 data->memory.free(data->memory.user_data, data->skins);
1916 for (cgltf_size i = 0; i < data->cameras_count; ++i)
1918 data->memory.free(data->memory.user_data, data->cameras[i].name);
1919 cgltf_free_extensions(data, data->cameras[i].extensions, data->cameras[i].extensions_count);
1922 data->memory.free(data->memory.user_data, data->cameras);
1924 for (cgltf_size i = 0; i < data->lights_count; ++i)
1926 data->memory.free(data->memory.user_data, data->lights[i].name);
1929 data->memory.free(data->memory.user_data, data->lights);
1931 for (cgltf_size i = 0; i < data->nodes_count; ++i)
1933 data->memory.free(data->memory.user_data, data->nodes[i].name);
1934 data->memory.free(data->memory.user_data, data->nodes[i].children);
1935 data->memory.free(data->memory.user_data, data->nodes[i].weights);
1936 cgltf_free_extensions(data, data->nodes[i].extensions, data->nodes[i].extensions_count);
1939 data->memory.free(data->memory.user_data, data->nodes);
1941 for (cgltf_size i = 0; i < data->scenes_count; ++i)
1943 data->memory.free(data->memory.user_data, data->scenes[i].name);
1944 data->memory.free(data->memory.user_data, data->scenes[i].nodes);
1946 cgltf_free_extensions(data, data->scenes[i].extensions, data->scenes[i].extensions_count);
1949 data->memory.free(data->memory.user_data, data->scenes);
1951 for (cgltf_size i = 0; i < data->animations_count; ++i)
1953 data->memory.free(data->memory.user_data, data->animations[i].name);
1954 for (cgltf_size j = 0; j < data->animations[i].samplers_count; ++j)
1956 cgltf_free_extensions(data, data->animations[i].samplers[j].extensions, data->animations[i].samplers[j].extensions_count);
1958 data->memory.free(data->memory.user_data, data->animations[i].samplers);
1960 for (cgltf_size j = 0; j < data->animations[i].channels_count; ++j)
1962 cgltf_free_extensions(data, data->animations[i].channels[j].extensions, data->animations[i].channels[j].extensions_count);
1964 data->memory.free(data->memory.user_data, data->animations[i].channels);
1966 cgltf_free_extensions(data, data->animations[i].extensions, data->animations[i].extensions_count);
1969 data->memory.free(data->memory.user_data, data->animations);
1971 for (cgltf_size i = 0; i < data->variants_count; ++i)
1973 data->memory.free(data->memory.user_data, data->variants[i].name);
1976 data->memory.free(data->memory.user_data, data->variants);
1978 cgltf_free_extensions(data, data->data_extensions, data->data_extensions_count);
1980 for (cgltf_size i = 0; i < data->extensions_used_count; ++i)
1982 data->memory.free(data->memory.user_data, data->extensions_used[i]);
1985 data->memory.free(data->memory.user_data, data->extensions_used);
1987 for (cgltf_size i = 0; i < data->extensions_required_count; ++i)
1989 data->memory.free(data->memory.user_data, data->extensions_required[i]);
1992 data->memory.free(data->memory.user_data, data->extensions_required);
1994 file_release(&data->memory, &data->file, data->file_data);
1996 data->memory.free(data->memory.user_data, data);
1999void cgltf_node_transform_local(
const cgltf_node* node, cgltf_float* out_matrix)
2001 cgltf_float* lm = out_matrix;
2003 if (node->has_matrix)
2005 memcpy(lm, node->matrix,
sizeof(
float) * 16);
2009 float tx = node->translation[0];
2010 float ty = node->translation[1];
2011 float tz = node->translation[2];
2013 float qx = node->rotation[0];
2014 float qy = node->rotation[1];
2015 float qz = node->rotation[2];
2016 float qw = node->rotation[3];
2018 float sx = node->scale[0];
2019 float sy = node->scale[1];
2020 float sz = node->scale[2];
2022 lm[0] = (1 - 2 * qy*qy - 2 * qz*qz) * sx;
2023 lm[1] = (2 * qx*qy + 2 * qz*qw) * sx;
2024 lm[2] = (2 * qx*qz - 2 * qy*qw) * sx;
2027 lm[4] = (2 * qx*qy - 2 * qz*qw) * sy;
2028 lm[5] = (1 - 2 * qx*qx - 2 * qz*qz) * sy;
2029 lm[6] = (2 * qy*qz + 2 * qx*qw) * sy;
2032 lm[8] = (2 * qx*qz + 2 * qy*qw) * sz;
2033 lm[9] = (2 * qy*qz - 2 * qx*qw) * sz;
2034 lm[10] = (1 - 2 * qx*qx - 2 * qy*qy) * sz;
2044void cgltf_node_transform_world(
const cgltf_node* node, cgltf_float* out_matrix)
2046 cgltf_float* lm = out_matrix;
2047 cgltf_node_transform_local(node, lm);
2054 cgltf_node_transform_local(parent, pm);
2056 for (
int i = 0; i < 4; ++i)
2058 float l0 = lm[i * 4 + 0];
2059 float l1 = lm[i * 4 + 1];
2060 float l2 = lm[i * 4 + 2];
2062 float r0 = l0 * pm[0] + l1 * pm[4] + l2 * pm[8];
2063 float r1 = l0 * pm[1] + l1 * pm[5] + l2 * pm[9];
2064 float r2 = l0 * pm[2] + l1 * pm[6] + l2 * pm[10];
2075 parent = parent->parent;
2079static cgltf_size cgltf_component_read_index(
const void* in, cgltf_component_type component_type)
2081 switch (component_type)
2083 case cgltf_component_type_r_16:
2084 return *((
const int16_t*) in);
2085 case cgltf_component_type_r_16u:
2086 return *((
const uint16_t*) in);
2087 case cgltf_component_type_r_32u:
2088 return *((
const uint32_t*) in);
2089 case cgltf_component_type_r_32f:
2090 return (cgltf_size)*((
const float*) in);
2091 case cgltf_component_type_r_8:
2092 return *((
const int8_t*) in);
2093 case cgltf_component_type_r_8u:
2094 return *((
const uint8_t*) in);
2100static cgltf_float cgltf_component_read_float(
const void* in, cgltf_component_type component_type, cgltf_bool normalized)
2102 if (component_type == cgltf_component_type_r_32f)
2104 return *((
const float*) in);
2109 switch (component_type)
2112 case cgltf_component_type_r_16:
2113 return *((
const int16_t*) in) / (cgltf_float)32767;
2114 case cgltf_component_type_r_16u:
2115 return *((
const uint16_t*) in) / (cgltf_float)65535;
2116 case cgltf_component_type_r_8:
2117 return *((
const int8_t*) in) / (cgltf_float)127;
2118 case cgltf_component_type_r_8u:
2119 return *((
const uint8_t*) in) / (cgltf_float)255;
2125 return (cgltf_float)cgltf_component_read_index(in, component_type);
2128static cgltf_size cgltf_component_size(cgltf_component_type component_type);
2130static cgltf_bool cgltf_element_read_float(
const uint8_t* element, cgltf_type type, cgltf_component_type component_type, cgltf_bool normalized, cgltf_float* out, cgltf_size element_size)
2132 cgltf_size num_components = cgltf_num_components(type);
2134 if (element_size < num_components) {
2140 cgltf_size component_size = cgltf_component_size(component_type);
2142 if (type == cgltf_type_mat2 && component_size == 1)
2144 out[0] = cgltf_component_read_float(element, component_type, normalized);
2145 out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
2146 out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
2147 out[3] = cgltf_component_read_float(element + 5, component_type, normalized);
2151 if (type == cgltf_type_mat3 && component_size == 1)
2153 out[0] = cgltf_component_read_float(element, component_type, normalized);
2154 out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
2155 out[2] = cgltf_component_read_float(element + 2, component_type, normalized);
2156 out[3] = cgltf_component_read_float(element + 4, component_type, normalized);
2157 out[4] = cgltf_component_read_float(element + 5, component_type, normalized);
2158 out[5] = cgltf_component_read_float(element + 6, component_type, normalized);
2159 out[6] = cgltf_component_read_float(element + 8, component_type, normalized);
2160 out[7] = cgltf_component_read_float(element + 9, component_type, normalized);
2161 out[8] = cgltf_component_read_float(element + 10, component_type, normalized);
2165 if (type == cgltf_type_mat3 && component_size == 2)
2167 out[0] = cgltf_component_read_float(element, component_type, normalized);
2168 out[1] = cgltf_component_read_float(element + 2, component_type, normalized);
2169 out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
2170 out[3] = cgltf_component_read_float(element + 8, component_type, normalized);
2171 out[4] = cgltf_component_read_float(element + 10, component_type, normalized);
2172 out[5] = cgltf_component_read_float(element + 12, component_type, normalized);
2173 out[6] = cgltf_component_read_float(element + 16, component_type, normalized);
2174 out[7] = cgltf_component_read_float(element + 18, component_type, normalized);
2175 out[8] = cgltf_component_read_float(element + 20, component_type, normalized);
2179 for (cgltf_size i = 0; i < num_components; ++i)
2181 out[i] = cgltf_component_read_float(element + component_size * i, component_type, normalized);
2189 return (
const uint8_t*)view->data;
2191 if (!view->buffer->data)
2194 const uint8_t* result = (
const uint8_t*)view->buffer->data;
2195 result += view->offset;
2199cgltf_bool cgltf_accessor_read_float(
const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size)
2201 if (accessor->is_sparse)
2205 if (accessor->buffer_view == NULL)
2207 memset(out, 0, element_size *
sizeof(cgltf_float));
2210 const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
2211 if (element == NULL)
2215 element += accessor->offset + accessor->stride * index;
2216 return cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, out, element_size);
2219cgltf_size cgltf_accessor_unpack_floats(
const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count)
2221 cgltf_size floats_per_element = cgltf_num_components(accessor->type);
2222 cgltf_size available_floats = accessor->count * floats_per_element;
2225 return available_floats;
2228 float_count = available_floats < float_count ? available_floats : float_count;
2229 cgltf_size element_count = float_count / floats_per_element;
2232 cgltf_float* dest = out;
2234 dense.is_sparse = 0;
2235 for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element)
2237 if (!cgltf_accessor_read_float(&dense, index, dest, floats_per_element))
2244 if (accessor->is_sparse)
2248 const uint8_t* index_data = cgltf_buffer_view_data(sparse->indices_buffer_view);
2249 const uint8_t* reader_head = cgltf_buffer_view_data(sparse->values_buffer_view);
2251 if (index_data == NULL || reader_head == NULL)
2256 index_data += sparse->indices_byte_offset;
2257 reader_head += sparse->values_byte_offset;
2259 cgltf_size index_stride = cgltf_component_size(sparse->indices_component_type);
2260 for (cgltf_size reader_index = 0; reader_index < sparse->count; reader_index++, index_data += index_stride)
2262 size_t writer_index = cgltf_component_read_index(index_data, sparse->indices_component_type);
2263 float* writer_head = out + writer_index * floats_per_element;
2265 if (!cgltf_element_read_float(reader_head, dense.type, dense.component_type, dense.normalized, writer_head, floats_per_element))
2270 reader_head += dense.stride;
2274 return element_count * floats_per_element;
2277static cgltf_uint cgltf_component_read_uint(
const void* in, cgltf_component_type component_type)
2279 switch (component_type)
2281 case cgltf_component_type_r_8:
2282 return *((
const int8_t*) in);
2284 case cgltf_component_type_r_8u:
2285 return *((
const uint8_t*) in);
2287 case cgltf_component_type_r_16:
2288 return *((
const int16_t*) in);
2290 case cgltf_component_type_r_16u:
2291 return *((
const uint16_t*) in);
2293 case cgltf_component_type_r_32u:
2294 return *((
const uint32_t*) in);
2301static cgltf_bool cgltf_element_read_uint(
const uint8_t* element, cgltf_type type, cgltf_component_type component_type, cgltf_uint* out, cgltf_size element_size)
2303 cgltf_size num_components = cgltf_num_components(type);
2305 if (element_size < num_components)
2311 if (type == cgltf_type_mat2 || type == cgltf_type_mat3 || type == cgltf_type_mat4)
2316 cgltf_size component_size = cgltf_component_size(component_type);
2318 for (cgltf_size i = 0; i < num_components; ++i)
2320 out[i] = cgltf_component_read_uint(element + component_size * i, component_type);
2325cgltf_bool cgltf_accessor_read_uint(
const cgltf_accessor* accessor, cgltf_size index, cgltf_uint* out, cgltf_size element_size)
2327 if (accessor->is_sparse)
2331 if (accessor->buffer_view == NULL)
2333 memset(out, 0, element_size *
sizeof( cgltf_uint ));
2336 const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
2337 if (element == NULL)
2341 element += accessor->offset + accessor->stride * index;
2342 return cgltf_element_read_uint(element, accessor->type, accessor->component_type, out, element_size);
2345cgltf_size cgltf_accessor_read_index(
const cgltf_accessor* accessor, cgltf_size index)
2347 if (accessor->is_sparse)
2351 if (accessor->buffer_view == NULL)
2355 const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
2356 if (element == NULL)
2360 element += accessor->offset + accessor->stride * index;
2361 return cgltf_component_read_index(element, accessor->component_type);
2364#define CGLTF_ERROR_JSON -1
2365#define CGLTF_ERROR_NOMEM -2
2366#define CGLTF_ERROR_LEGACY -3
2368#define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; }
2369#define CGLTF_CHECK_TOKTYPE_RETTYPE(tok_, type_, ret_) if ((tok_).type != (type_)) { return (ret_)CGLTF_ERROR_JSON; }
2370#define CGLTF_CHECK_KEY(tok_) if ((tok_).type != JSMN_STRING || (tok_).size == 0) { return CGLTF_ERROR_JSON; }
2372#define CGLTF_PTRINDEX(type, idx) (type*)((cgltf_size)idx + 1)
2373#define CGLTF_PTRFIXUP(var, data, size) if (var) { if ((cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1]; }
2374#define CGLTF_PTRFIXUP_REQ(var, data, size) if (!var || (cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1];
2376static int cgltf_json_strcmp(jsmntok_t
const* tok,
const uint8_t* json_chunk,
const char* str)
2378 CGLTF_CHECK_TOKTYPE(*tok, JSMN_STRING);
2379 size_t const str_len = strlen(str);
2380 size_t const name_length = tok->end - tok->start;
2381 return (str_len == name_length) ? strncmp((
const char*)json_chunk + tok->start, str, str_len) : 128;
2384static int cgltf_json_to_int(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2386 CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
2388 int size = (cgltf_size)(tok->end - tok->start) <
sizeof(tmp) ? tok->end - tok->start : (
int)(
sizeof(tmp) - 1);
2389 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2391 return CGLTF_ATOI(tmp);
2394static cgltf_size cgltf_json_to_size(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2396 CGLTF_CHECK_TOKTYPE_RETTYPE(*tok, JSMN_PRIMITIVE, cgltf_size);
2398 int size = (cgltf_size)(tok->end - tok->start) <
sizeof(tmp) ? tok->end - tok->start : (
int)(
sizeof(tmp) - 1);
2399 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2401 return (cgltf_size)CGLTF_ATOLL(tmp);
2404static cgltf_float cgltf_json_to_float(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2406 CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
2408 int size = (cgltf_size)(tok->end - tok->start) <
sizeof(tmp) ? tok->end - tok->start : (
int)(
sizeof(tmp) - 1);
2409 strncpy(tmp, (
const char*)json_chunk + tok->start, size);
2411 return (cgltf_float)CGLTF_ATOF(tmp);
2414static cgltf_bool cgltf_json_to_bool(jsmntok_t
const* tok,
const uint8_t* json_chunk)
2416 int size = tok->end - tok->start;
2417 return size == 4 && memcmp(json_chunk + tok->start,
"true", 4) == 0;
2420static int cgltf_skip_json(jsmntok_t
const* tokens,
int i)
2426 switch (tokens[i].type)
2429 end += tokens[i].size * 2;
2433 end += tokens[i].size;
2436 case JSMN_PRIMITIVE:
2450static void cgltf_fill_float_array(
float* out_array,
int size,
float value)
2452 for (
int j = 0; j < size; ++j)
2454 out_array[j] = value;
2458static int cgltf_parse_json_float_array(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
float* out_array,
int size)
2460 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2461 if (tokens[i].size != size)
2463 return CGLTF_ERROR_JSON;
2466 for (
int j = 0; j < size; ++j)
2468 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
2469 out_array[j] = cgltf_json_to_float(tokens + i, json_chunk);
2475static int cgltf_parse_json_string(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
char** out_string)
2477 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
2480 return CGLTF_ERROR_JSON;
2482 int size = tokens[i].end - tokens[i].start;
2483 char* result = (
char*)options->memory.alloc(options->memory.user_data, size + 1);
2486 return CGLTF_ERROR_NOMEM;
2488 strncpy(result, (
const char*)json_chunk + tokens[i].start, size);
2490 *out_string = result;
2494static 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)
2497 if (tokens[i].type != JSMN_ARRAY)
2499 return tokens[i].type == JSMN_OBJECT ? CGLTF_ERROR_LEGACY : CGLTF_ERROR_JSON;
2503 return CGLTF_ERROR_JSON;
2505 int size = tokens[i].size;
2506 void* result = cgltf_calloc(options, element_size, size);
2509 return CGLTF_ERROR_NOMEM;
2511 *out_array = result;
2516static 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)
2518 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2519 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
char*), (
void**)out_array, out_size);
2525 for (cgltf_size j = 0; j < *out_size; ++j)
2527 i = cgltf_parse_json_string(options, tokens, i, json_chunk, j + (*out_array));
2536static void cgltf_parse_attribute_type(
const char* name, cgltf_attribute_type* out_type,
int* out_index)
2538 const char* us = strchr(name,
'_');
2539 size_t len = us ? (size_t)(us - name) : strlen(name);
2541 if (len == 8 && strncmp(name,
"POSITION", 8) == 0)
2543 *out_type = cgltf_attribute_type_position;
2545 else if (len == 6 && strncmp(name,
"NORMAL", 6) == 0)
2547 *out_type = cgltf_attribute_type_normal;
2549 else if (len == 7 && strncmp(name,
"TANGENT", 7) == 0)
2551 *out_type = cgltf_attribute_type_tangent;
2553 else if (len == 8 && strncmp(name,
"TEXCOORD", 8) == 0)
2555 *out_type = cgltf_attribute_type_texcoord;
2557 else if (len == 5 && strncmp(name,
"COLOR", 5) == 0)
2559 *out_type = cgltf_attribute_type_color;
2561 else if (len == 6 && strncmp(name,
"JOINTS", 6) == 0)
2563 *out_type = cgltf_attribute_type_joints;
2565 else if (len == 7 && strncmp(name,
"WEIGHTS", 7) == 0)
2567 *out_type = cgltf_attribute_type_weights;
2571 *out_type = cgltf_attribute_type_invalid;
2574 if (us && *out_type != cgltf_attribute_type_invalid)
2576 *out_index = CGLTF_ATOI(us + 1);
2580static 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)
2582 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2584 if (*out_attributes)
2586 return CGLTF_ERROR_JSON;
2589 *out_attributes_count = tokens[i].size;
2593 if (!*out_attributes)
2595 return CGLTF_ERROR_NOMEM;
2598 for (cgltf_size j = 0; j < *out_attributes_count; ++j)
2600 CGLTF_CHECK_KEY(tokens[i]);
2602 i = cgltf_parse_json_string(options, tokens, i, json_chunk, &(*out_attributes)[j].name);
2605 return CGLTF_ERROR_JSON;
2608 cgltf_parse_attribute_type((*out_attributes)[j].name, &(*out_attributes)[j].type, &(*out_attributes)[j].index);
2610 (*out_attributes)[j].data = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
2617static int cgltf_parse_json_extras(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_extras* out_extras)
2620 out_extras->start_offset = tokens[i].start;
2621 out_extras->end_offset = tokens[i].end;
2622 i = cgltf_skip_json(tokens, i);
2626static int cgltf_parse_json_unprocessed_extension(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_extension* out_extension)
2628 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
2629 CGLTF_CHECK_TOKTYPE(tokens[i+1], JSMN_OBJECT);
2630 if (out_extension->name)
2632 return CGLTF_ERROR_JSON;
2635 cgltf_size name_length = tokens[i].end - tokens[i].start;
2636 out_extension->name = (
char*)options->memory.alloc(options->memory.user_data, name_length + 1);
2637 if (!out_extension->name)
2639 return CGLTF_ERROR_NOMEM;
2641 strncpy(out_extension->name, (
const char*)json_chunk + tokens[i].start, name_length);
2642 out_extension->name[name_length] = 0;
2645 size_t start = tokens[i].start;
2646 size_t size = tokens[i].end - start;
2647 out_extension->data = (
char*)options->memory.alloc(options->memory.user_data, size + 1);
2648 if (!out_extension->data)
2650 return CGLTF_ERROR_NOMEM;
2652 strncpy(out_extension->data, (
const char*)json_chunk + start, size);
2653 out_extension->data[size] =
'\0';
2655 i = cgltf_skip_json(tokens, i);
2660static 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)
2664 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2667 return CGLTF_ERROR_JSON;
2670 int extensions_size = tokens[i].size;
2671 *out_extensions_count = 0;
2674 if (!*out_extensions)
2676 return CGLTF_ERROR_NOMEM;
2681 for (
int j = 0; j < extensions_size; ++j)
2683 CGLTF_CHECK_KEY(tokens[i]);
2685 cgltf_size extension_index = (*out_extensions_count)++;
2687 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, extension);
2699 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2701 int size = tokens[i].size;
2704 for (
int j = 0; j < size; ++j)
2706 CGLTF_CHECK_KEY(tokens[i]);
2708 if (cgltf_json_strcmp(tokens + i, json_chunk,
"attributes") == 0)
2710 i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_draco_mesh_compression->attributes, &out_draco_mesh_compression->attributes_count);
2712 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"bufferView") == 0)
2715 out_draco_mesh_compression->buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
2728static 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)
2731 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
2733 int size = tokens[i].size;
2736 for (
int j = 0; j < size; ++j)
2738 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2740 int obj_size = tokens[i].size;
2744 int variants_tok = -1;
2747 for (
int k = 0; k < obj_size; ++k)
2749 CGLTF_CHECK_KEY(tokens[i]);
2751 if (cgltf_json_strcmp(tokens + i, json_chunk,
"material") == 0)
2754 material = cgltf_json_to_int(tokens + i, json_chunk);
2757 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"variants") == 0)
2760 CGLTF_CHECK_TOKTYPE(tokens[variants_tok], JSMN_ARRAY);
2762 i = cgltf_skip_json(tokens, i+1);
2764 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
2766 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &extras);
2770 i = cgltf_skip_json(tokens, i+1);
2779 if (material < 0 || variants_tok < 0)
2781 return CGLTF_ERROR_JSON;
2786 for (
int k = 0; k < tokens[variants_tok].size; ++k)
2788 int variant = cgltf_json_to_int(&tokens[variants_tok + 1 + k], json_chunk);
2792 out_mappings[*offset].material = CGLTF_PTRINDEX(
cgltf_material, material);
2793 out_mappings[*offset].variant = variant;
2794 out_mappings[*offset].extras = extras;
2801 (*offset) += tokens[variants_tok].size;
2808static int cgltf_parse_json_material_mappings(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_primitive* out_prim)
2810 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2812 int size = tokens[i].size;
2815 for (
int j = 0; j < size; ++j)
2817 CGLTF_CHECK_KEY(tokens[i]);
2819 if (cgltf_json_strcmp(tokens + i, json_chunk,
"mappings") == 0)
2821 if (out_prim->mappings)
2823 return CGLTF_ERROR_JSON;
2826 cgltf_size mappings_offset = 0;
2827 int k = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, NULL, &mappings_offset);
2833 out_prim->mappings_count = mappings_offset;
2836 mappings_offset = 0;
2837 i = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, out_prim->mappings, &mappings_offset);
2841 i = cgltf_skip_json(tokens, i+1);
2853static int cgltf_parse_json_primitive(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_primitive* out_prim)
2855 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2857 out_prim->type = cgltf_primitive_type_triangles;
2859 int size = tokens[i].size;
2862 for (
int j = 0; j < size; ++j)
2864 CGLTF_CHECK_KEY(tokens[i]);
2866 if (cgltf_json_strcmp(tokens+i, json_chunk,
"mode") == 0)
2870 = (cgltf_primitive_type)
2871 cgltf_json_to_int(tokens+i, json_chunk);
2874 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"indices") == 0)
2877 out_prim->indices = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
2880 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"material") == 0)
2883 out_prim->material = CGLTF_PTRINDEX(
cgltf_material, cgltf_json_to_int(tokens + i, json_chunk));
2886 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"attributes") == 0)
2888 i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_prim->attributes, &out_prim->attributes_count);
2890 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"targets") == 0)
2892 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_morph_target), (
void**)&out_prim->targets, &out_prim->targets_count);
2898 for (cgltf_size k = 0; k < out_prim->targets_count; ++k)
2900 i = cgltf_parse_json_attribute_list(options, tokens, i, json_chunk, &out_prim->targets[k].attributes, &out_prim->targets[k].attributes_count);
2907 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
2909 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_prim->extras);
2911 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
2915 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2916 if(out_prim->extensions)
2918 return CGLTF_ERROR_JSON;
2921 int extensions_size = tokens[i].size;
2922 out_prim->extensions_count = 0;
2925 if (!out_prim->extensions)
2927 return CGLTF_ERROR_NOMEM;
2931 for (
int k = 0; k < extensions_size; ++k)
2933 CGLTF_CHECK_KEY(tokens[i]);
2935 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_draco_mesh_compression") == 0)
2937 out_prim->has_draco_mesh_compression = 1;
2938 i = cgltf_parse_json_draco_mesh_compression(options, tokens, i + 1, json_chunk, &out_prim->draco_mesh_compression);
2940 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_variants") == 0)
2942 i = cgltf_parse_json_material_mappings(options, tokens, i + 1, json_chunk, out_prim);
2946 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_prim->extensions[out_prim->extensions_count++]));
2957 i = cgltf_skip_json(tokens, i+1);
2969static int cgltf_parse_json_mesh(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_mesh* out_mesh)
2971 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
2973 int size = tokens[i].size;
2976 for (
int j = 0; j < size; ++j)
2978 CGLTF_CHECK_KEY(tokens[i]);
2980 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
2982 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_mesh->name);
2984 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"primitives") == 0)
2986 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_primitive), (
void**)&out_mesh->primitives, &out_mesh->primitives_count);
2992 for (cgltf_size prim_index = 0; prim_index < out_mesh->primitives_count; ++prim_index)
2994 i = cgltf_parse_json_primitive(options, tokens, i, json_chunk, &out_mesh->primitives[prim_index]);
3001 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"weights") == 0)
3003 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(cgltf_float), (
void**)&out_mesh->weights, &out_mesh->weights_count);
3009 i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_mesh->weights, (
int)out_mesh->weights_count);
3011 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3015 out_mesh->extras.start_offset = tokens[i].start;
3016 out_mesh->extras.end_offset = tokens[i].end;
3018 if (tokens[i].type == JSMN_OBJECT)
3020 int extras_size = tokens[i].size;
3023 for (
int k = 0; k < extras_size; ++k)
3025 CGLTF_CHECK_KEY(tokens[i]);
3027 if (cgltf_json_strcmp(tokens+i, json_chunk,
"targetNames") == 0 && tokens[i+1].type == JSMN_ARRAY)
3029 i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_mesh->target_names, &out_mesh->target_names_count);
3033 i = cgltf_skip_json(tokens, i+1);
3044 i = cgltf_skip_json(tokens, i);
3047 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3049 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_mesh->extensions_count, &out_mesh->extensions);
3053 i = cgltf_skip_json(tokens, i+1);
3065static int cgltf_parse_json_meshes(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
3067 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_mesh), (
void**)&out_data->meshes, &out_data->meshes_count);
3073 for (cgltf_size j = 0; j < out_data->meshes_count; ++j)
3075 i = cgltf_parse_json_mesh(options, tokens, i, json_chunk, &out_data->meshes[j]);
3084static cgltf_component_type cgltf_json_to_component_type(jsmntok_t
const* tok,
const uint8_t* json_chunk)
3086 int type = cgltf_json_to_int(tok, json_chunk);
3091 return cgltf_component_type_r_8;
3093 return cgltf_component_type_r_8u;
3095 return cgltf_component_type_r_16;
3097 return cgltf_component_type_r_16u;
3099 return cgltf_component_type_r_32u;
3101 return cgltf_component_type_r_32f;
3103 return cgltf_component_type_invalid;
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,
"count") == 0)
3121 out_sparse->count = cgltf_json_to_int(tokens + i, json_chunk);
3124 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"indices") == 0)
3127 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3129 int indices_size = tokens[i].size;
3132 for (
int k = 0; k < indices_size; ++k)
3134 CGLTF_CHECK_KEY(tokens[i]);
3136 if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3139 out_sparse->indices_buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
3142 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3145 out_sparse->indices_byte_offset = cgltf_json_to_size(tokens + i, json_chunk);
3148 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"componentType") == 0)
3151 out_sparse->indices_component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
3154 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3156 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->indices_extras);
3158 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3160 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->indices_extensions_count, &out_sparse->indices_extensions);
3164 i = cgltf_skip_json(tokens, i+1);
3173 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"values") == 0)
3176 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3178 int values_size = tokens[i].size;
3181 for (
int k = 0; k < values_size; ++k)
3183 CGLTF_CHECK_KEY(tokens[i]);
3185 if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3188 out_sparse->values_buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
3191 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3194 out_sparse->values_byte_offset = cgltf_json_to_size(tokens + i, json_chunk);
3197 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3199 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->values_extras);
3201 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3203 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->values_extensions_count, &out_sparse->values_extensions);
3207 i = cgltf_skip_json(tokens, i+1);
3216 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3218 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->extras);
3220 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3222 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->extensions_count, &out_sparse->extensions);
3226 i = cgltf_skip_json(tokens, i+1);
3238static int cgltf_parse_json_accessor(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_accessor* out_accessor)
3240 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3242 int size = tokens[i].size;
3245 for (
int j = 0; j < size; ++j)
3247 CGLTF_CHECK_KEY(tokens[i]);
3249 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
3251 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_accessor->name);
3253 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3256 out_accessor->buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
3259 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
3262 out_accessor->offset =
3263 cgltf_json_to_size(tokens+i, json_chunk);
3266 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"componentType") == 0)
3269 out_accessor->component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
3272 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"normalized") == 0)
3275 out_accessor->normalized = cgltf_json_to_bool(tokens+i, json_chunk);
3278 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
3281 out_accessor->count =
3282 cgltf_json_to_int(tokens+i, json_chunk);
3285 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
3288 if (cgltf_json_strcmp(tokens+i, json_chunk,
"SCALAR") == 0)
3290 out_accessor->type = cgltf_type_scalar;
3292 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC2") == 0)
3294 out_accessor->type = cgltf_type_vec2;
3296 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC3") == 0)
3298 out_accessor->type = cgltf_type_vec3;
3300 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"VEC4") == 0)
3302 out_accessor->type = cgltf_type_vec4;
3304 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT2") == 0)
3306 out_accessor->type = cgltf_type_mat2;
3308 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT3") == 0)
3310 out_accessor->type = cgltf_type_mat3;
3312 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"MAT4") == 0)
3314 out_accessor->type = cgltf_type_mat4;
3318 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"min") == 0)
3321 out_accessor->has_min = 1;
3323 int min_size = tokens[i].size > 16 ? 16 : tokens[i].size;
3324 i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->min, min_size);
3326 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"max") == 0)
3329 out_accessor->has_max = 1;
3331 int max_size = tokens[i].size > 16 ? 16 : tokens[i].size;
3332 i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->max, max_size);
3334 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"sparse") == 0)
3336 out_accessor->is_sparse = 1;
3337 i = cgltf_parse_json_accessor_sparse(options, tokens, i + 1, json_chunk, &out_accessor->sparse);
3339 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3341 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_accessor->extras);
3343 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3345 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_accessor->extensions_count, &out_accessor->extensions);
3349 i = cgltf_skip_json(tokens, i+1);
3361static int cgltf_parse_json_texture_transform(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_texture_transform* out_texture_transform)
3363 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3365 int size = tokens[i].size;
3368 for (
int j = 0; j < size; ++j)
3370 CGLTF_CHECK_KEY(tokens[i]);
3372 if (cgltf_json_strcmp(tokens + i, json_chunk,
"offset") == 0)
3374 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->offset, 2);
3376 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"rotation") == 0)
3379 out_texture_transform->rotation = cgltf_json_to_float(tokens + i, json_chunk);
3382 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scale") == 0)
3384 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->scale, 2);
3386 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"texCoord") == 0)
3389 out_texture_transform->has_texcoord = 1;
3390 out_texture_transform->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
3395 i = cgltf_skip_json(tokens, i + 1);
3407static 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)
3409 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3411 out_texture_view->scale = 1.0f;
3412 cgltf_fill_float_array(out_texture_view->transform.scale, 2, 1.0f);
3414 int size = tokens[i].size;
3417 for (
int j = 0; j < size; ++j)
3419 CGLTF_CHECK_KEY(tokens[i]);
3421 if (cgltf_json_strcmp(tokens + i, json_chunk,
"index") == 0)
3424 out_texture_view->texture = CGLTF_PTRINDEX(
cgltf_texture, cgltf_json_to_int(tokens + i, json_chunk));
3427 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"texCoord") == 0)
3430 out_texture_view->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
3433 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scale") == 0)
3436 out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
3439 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"strength") == 0)
3442 out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
3445 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3447 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_texture_view->extras);
3449 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3453 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3454 if(out_texture_view->extensions)
3456 return CGLTF_ERROR_JSON;
3459 int extensions_size = tokens[i].size;
3460 out_texture_view->extensions_count = 0;
3463 if (!out_texture_view->extensions)
3465 return CGLTF_ERROR_NOMEM;
3470 for (
int k = 0; k < extensions_size; ++k)
3472 CGLTF_CHECK_KEY(tokens[i]);
3474 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_texture_transform") == 0)
3476 out_texture_view->has_transform = 1;
3477 i = cgltf_parse_json_texture_transform(tokens, i + 1, json_chunk, &out_texture_view->transform);
3481 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture_view->extensions[out_texture_view->extensions_count++]));
3492 i = cgltf_skip_json(tokens, i + 1);
3506 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3508 int size = tokens[i].size;
3511 for (
int j = 0; j < size; ++j)
3513 CGLTF_CHECK_KEY(tokens[i]);
3515 if (cgltf_json_strcmp(tokens+i, json_chunk,
"metallicFactor") == 0)
3518 out_pbr->metallic_factor =
3519 cgltf_json_to_float(tokens + i, json_chunk);
3522 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"roughnessFactor") == 0)
3525 out_pbr->roughness_factor =
3526 cgltf_json_to_float(tokens+i, json_chunk);
3529 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"baseColorFactor") == 0)
3531 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->base_color_factor, 4);
3533 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"baseColorTexture") == 0)
3535 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
3536 &out_pbr->base_color_texture);
3538 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"metallicRoughnessTexture") == 0)
3540 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
3541 &out_pbr->metallic_roughness_texture);
3543 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3545 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_pbr->extras);
3549 i = cgltf_skip_json(tokens, i+1);
3563 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3564 int size = tokens[i].size;
3567 for (
int j = 0; j < size; ++j)
3569 CGLTF_CHECK_KEY(tokens[i]);
3571 if (cgltf_json_strcmp(tokens+i, json_chunk,
"diffuseFactor") == 0)
3573 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->diffuse_factor, 4);
3575 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularFactor") == 0)
3577 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->specular_factor, 3);
3579 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"glossinessFactor") == 0)
3582 out_pbr->glossiness_factor = cgltf_json_to_float(tokens + i, json_chunk);
3585 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"diffuseTexture") == 0)
3587 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->diffuse_texture);
3589 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularGlossinessTexture") == 0)
3591 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->specular_glossiness_texture);
3595 i = cgltf_skip_json(tokens, i+1);
3607static int cgltf_parse_json_clearcoat(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_clearcoat* out_clearcoat)
3609 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3610 int size = tokens[i].size;
3613 for (
int j = 0; j < size; ++j)
3615 CGLTF_CHECK_KEY(tokens[i]);
3617 if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatFactor") == 0)
3620 out_clearcoat->clearcoat_factor = cgltf_json_to_float(tokens + i, json_chunk);
3623 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatRoughnessFactor") == 0)
3626 out_clearcoat->clearcoat_roughness_factor = cgltf_json_to_float(tokens + i, json_chunk);
3629 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatTexture") == 0)
3631 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_texture);
3633 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatRoughnessTexture") == 0)
3635 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_roughness_texture);
3637 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"clearcoatNormalTexture") == 0)
3639 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_normal_texture);
3643 i = cgltf_skip_json(tokens, i+1);
3655static int cgltf_parse_json_ior(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_ior* out_ior)
3657 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3658 int size = tokens[i].size;
3662 out_ior->ior = 1.5f;
3664 for (
int j = 0; j < size; ++j)
3666 CGLTF_CHECK_KEY(tokens[i]);
3668 if (cgltf_json_strcmp(tokens+i, json_chunk,
"ior") == 0)
3671 out_ior->ior = cgltf_json_to_float(tokens + i, json_chunk);
3676 i = cgltf_skip_json(tokens, i+1);
3688static int cgltf_parse_json_specular(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_specular* out_specular)
3690 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3691 int size = tokens[i].size;
3695 out_specular->specular_factor = 1.0f;
3696 cgltf_fill_float_array(out_specular->specular_color_factor, 3, 1.0f);
3698 for (
int j = 0; j < size; ++j)
3700 CGLTF_CHECK_KEY(tokens[i]);
3702 if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularFactor") == 0)
3705 out_specular->specular_factor = cgltf_json_to_float(tokens + i, json_chunk);
3708 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularColorFactor") == 0)
3710 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_specular->specular_color_factor, 3);
3712 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"specularTexture") == 0)
3714 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_texture);
3716 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"specularColorTexture") == 0)
3718 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_color_texture);
3722 i = cgltf_skip_json(tokens, i+1);
3734static int cgltf_parse_json_transmission(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_transmission* out_transmission)
3736 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3737 int size = tokens[i].size;
3740 for (
int j = 0; j < size; ++j)
3742 CGLTF_CHECK_KEY(tokens[i]);
3744 if (cgltf_json_strcmp(tokens+i, json_chunk,
"transmissionFactor") == 0)
3747 out_transmission->transmission_factor = cgltf_json_to_float(tokens + i, json_chunk);
3750 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"transmissionTexture") == 0)
3752 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_transmission->transmission_texture);
3756 i = cgltf_skip_json(tokens, i+1);
3768static int cgltf_parse_json_volume(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_volume* out_volume)
3770 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3771 int size = tokens[i].size;
3774 for (
int j = 0; j < size; ++j)
3776 CGLTF_CHECK_KEY(tokens[i]);
3778 if (cgltf_json_strcmp(tokens + i, json_chunk,
"thicknessFactor") == 0)
3781 out_volume->thickness_factor = cgltf_json_to_float(tokens + i, json_chunk);
3784 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"thicknessTexture") == 0)
3786 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_volume->thickness_texture);
3788 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"attenuationColor") == 0)
3790 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_volume->attenuation_color, 3);
3792 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"attenuationDistance") == 0)
3795 out_volume->attenuation_distance = cgltf_json_to_float(tokens + i, json_chunk);
3800 i = cgltf_skip_json(tokens, i + 1);
3812static int cgltf_parse_json_sheen(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_sheen* out_sheen)
3814 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3815 int size = tokens[i].size;
3818 for (
int j = 0; j < size; ++j)
3820 CGLTF_CHECK_KEY(tokens[i]);
3822 if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenColorFactor") == 0)
3824 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_sheen->sheen_color_factor, 3);
3826 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenColorTexture") == 0)
3828 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_sheen->sheen_color_texture);
3830 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenRoughnessFactor") == 0)
3833 out_sheen->sheen_roughness_factor = cgltf_json_to_float(tokens + i, json_chunk);
3836 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"sheenRoughnessTexture") == 0)
3838 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_sheen->sheen_roughness_texture);
3842 i = cgltf_skip_json(tokens, i+1);
3854static int cgltf_parse_json_emissive_strength(jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_emissive_strength* out_emissive_strength)
3856 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3857 int size = tokens[i].size;
3861 out_emissive_strength->emissive_strength = 1.f;
3863 for (
int j = 0; j < size; ++j)
3865 CGLTF_CHECK_KEY(tokens[i]);
3867 if (cgltf_json_strcmp(tokens + i, json_chunk,
"emissiveStrength") == 0)
3870 out_emissive_strength->emissive_strength = cgltf_json_to_float(tokens + i, json_chunk);
3875 i = cgltf_skip_json(tokens, i + 1);
3887static int cgltf_parse_json_image(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_image* out_image)
3889 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3891 int size = tokens[i].size;
3894 for (
int j = 0; j < size; ++j)
3896 CGLTF_CHECK_KEY(tokens[i]);
3898 if (cgltf_json_strcmp(tokens + i, json_chunk,
"uri") == 0)
3900 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->uri);
3902 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"bufferView") == 0)
3905 out_image->buffer_view = CGLTF_PTRINDEX(
cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
3908 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"mimeType") == 0)
3910 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->mime_type);
3912 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
3914 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->name);
3916 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3918 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_image->extras);
3920 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3922 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_image->extensions_count, &out_image->extensions);
3926 i = cgltf_skip_json(tokens, i + 1);
3938static int cgltf_parse_json_sampler(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_sampler* out_sampler)
3941 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3943 out_sampler->wrap_s = 10497;
3944 out_sampler->wrap_t = 10497;
3946 int size = tokens[i].size;
3949 for (
int j = 0; j < size; ++j)
3951 CGLTF_CHECK_KEY(tokens[i]);
3953 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
3955 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_sampler->name);
3957 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"magFilter") == 0)
3960 out_sampler->mag_filter
3961 = cgltf_json_to_int(tokens + i, json_chunk);
3964 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"minFilter") == 0)
3967 out_sampler->min_filter
3968 = cgltf_json_to_int(tokens + i, json_chunk);
3971 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"wrapS") == 0)
3975 = cgltf_json_to_int(tokens + i, json_chunk);
3978 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"wrapT") == 0)
3982 = cgltf_json_to_int(tokens + i, json_chunk);
3985 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
3987 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sampler->extras);
3989 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
3991 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->extensions_count, &out_sampler->extensions);
3995 i = cgltf_skip_json(tokens, i + 1);
4007static int cgltf_parse_json_texture(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_texture* out_texture)
4009 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4011 int size = tokens[i].size;
4014 for (
int j = 0; j < size; ++j)
4016 CGLTF_CHECK_KEY(tokens[i]);
4018 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4020 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_texture->name);
4022 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"sampler") == 0)
4025 out_texture->sampler = CGLTF_PTRINDEX(
cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk));
4028 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"source") == 0)
4031 out_texture->image = CGLTF_PTRINDEX(
cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
4034 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4036 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_texture->extras);
4038 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4042 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4043 if (out_texture->extensions)
4045 return CGLTF_ERROR_JSON;
4048 int extensions_size = tokens[i].size;
4051 out_texture->extensions_count = 0;
4053 if (!out_texture->extensions)
4055 return CGLTF_ERROR_NOMEM;
4058 for (
int k = 0; k < extensions_size; ++k)
4060 CGLTF_CHECK_KEY(tokens[i]);
4062 if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_texture_basisu") == 0)
4064 out_texture->has_basisu = 1;
4066 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4067 int num_properties = tokens[i].size;
4070 for (
int t = 0; t < num_properties; ++t)
4072 CGLTF_CHECK_KEY(tokens[i]);
4074 if (cgltf_json_strcmp(tokens + i, json_chunk,
"source") == 0)
4077 out_texture->basisu_image = CGLTF_PTRINDEX(
cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
4082 i = cgltf_skip_json(tokens, i + 1);
4088 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture->extensions[out_texture->extensions_count++]));
4099 i = cgltf_skip_json(tokens, i + 1);
4111static int cgltf_parse_json_material(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_material* out_material)
4113 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4115 cgltf_fill_float_array(out_material->pbr_metallic_roughness.base_color_factor, 4, 1.0f);
4116 out_material->pbr_metallic_roughness.metallic_factor = 1.0f;
4117 out_material->pbr_metallic_roughness.roughness_factor = 1.0f;
4119 cgltf_fill_float_array(out_material->pbr_specular_glossiness.diffuse_factor, 4, 1.0f);
4120 cgltf_fill_float_array(out_material->pbr_specular_glossiness.specular_factor, 3, 1.0f);
4121 out_material->pbr_specular_glossiness.glossiness_factor = 1.0f;
4123 cgltf_fill_float_array(out_material->volume.attenuation_color, 3, 1.0f);
4124 out_material->volume.attenuation_distance = FLT_MAX;
4126 out_material->alpha_cutoff = 0.5f;
4128 int size = tokens[i].size;
4131 for (
int j = 0; j < size; ++j)
4133 CGLTF_CHECK_KEY(tokens[i]);
4135 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4137 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_material->name);
4139 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"pbrMetallicRoughness") == 0)
4141 out_material->has_pbr_metallic_roughness = 1;
4142 i = cgltf_parse_json_pbr_metallic_roughness(options, tokens, i + 1, json_chunk, &out_material->pbr_metallic_roughness);
4144 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"emissiveFactor") == 0)
4146 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_material->emissive_factor, 3);
4148 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"normalTexture") == 0)
4150 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4151 &out_material->normal_texture);
4153 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"occlusionTexture") == 0)
4155 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4156 &out_material->occlusion_texture);
4158 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"emissiveTexture") == 0)
4160 i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
4161 &out_material->emissive_texture);
4163 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"alphaMode") == 0)
4166 if (cgltf_json_strcmp(tokens + i, json_chunk,
"OPAQUE") == 0)
4168 out_material->alpha_mode = cgltf_alpha_mode_opaque;
4170 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"MASK") == 0)
4172 out_material->alpha_mode = cgltf_alpha_mode_mask;
4174 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"BLEND") == 0)
4176 out_material->alpha_mode = cgltf_alpha_mode_blend;
4180 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"alphaCutoff") == 0)
4183 out_material->alpha_cutoff = cgltf_json_to_float(tokens + i, json_chunk);
4186 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"doubleSided") == 0)
4189 out_material->double_sided =
4190 cgltf_json_to_bool(tokens + i, json_chunk);
4193 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4195 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_material->extras);
4197 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4201 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4202 if(out_material->extensions)
4204 return CGLTF_ERROR_JSON;
4207 int extensions_size = tokens[i].size;
4210 out_material->extensions_count= 0;
4212 if (!out_material->extensions)
4214 return CGLTF_ERROR_NOMEM;
4217 for (
int k = 0; k < extensions_size; ++k)
4219 CGLTF_CHECK_KEY(tokens[i]);
4221 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_pbrSpecularGlossiness") == 0)
4223 out_material->has_pbr_specular_glossiness = 1;
4224 i = cgltf_parse_json_pbr_specular_glossiness(options, tokens, i + 1, json_chunk, &out_material->pbr_specular_glossiness);
4226 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_unlit") == 0)
4228 out_material->unlit = 1;
4229 i = cgltf_skip_json(tokens, i+1);
4231 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_clearcoat") == 0)
4233 out_material->has_clearcoat = 1;
4234 i = cgltf_parse_json_clearcoat(options, tokens, i + 1, json_chunk, &out_material->clearcoat);
4236 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_ior") == 0)
4238 out_material->has_ior = 1;
4239 i = cgltf_parse_json_ior(tokens, i + 1, json_chunk, &out_material->ior);
4241 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_specular") == 0)
4243 out_material->has_specular = 1;
4244 i = cgltf_parse_json_specular(options, tokens, i + 1, json_chunk, &out_material->specular);
4246 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_transmission") == 0)
4248 out_material->has_transmission = 1;
4249 i = cgltf_parse_json_transmission(options, tokens, i + 1, json_chunk, &out_material->transmission);
4251 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_volume") == 0)
4253 out_material->has_volume = 1;
4254 i = cgltf_parse_json_volume(options, tokens, i + 1, json_chunk, &out_material->volume);
4256 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_sheen") == 0)
4258 out_material->has_sheen = 1;
4259 i = cgltf_parse_json_sheen(options, tokens, i + 1, json_chunk, &out_material->sheen);
4261 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"KHR_materials_emissive_strength") == 0)
4263 out_material->has_emissive_strength = 1;
4264 i = cgltf_parse_json_emissive_strength(tokens, i + 1, json_chunk, &out_material->emissive_strength);
4268 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++]));
4279 i = cgltf_skip_json(tokens, i+1);
4291static int cgltf_parse_json_accessors(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4293 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_accessor), (
void**)&out_data->accessors, &out_data->accessors_count);
4299 for (cgltf_size j = 0; j < out_data->accessors_count; ++j)
4301 i = cgltf_parse_json_accessor(options, tokens, i, json_chunk, &out_data->accessors[j]);
4310static int cgltf_parse_json_materials(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4312 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_material), (
void**)&out_data->materials, &out_data->materials_count);
4318 for (cgltf_size j = 0; j < out_data->materials_count; ++j)
4320 i = cgltf_parse_json_material(options, tokens, i, json_chunk, &out_data->materials[j]);
4329static int cgltf_parse_json_images(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4331 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_image), (
void**)&out_data->images, &out_data->images_count);
4337 for (cgltf_size j = 0; j < out_data->images_count; ++j)
4339 i = cgltf_parse_json_image(options, tokens, i, json_chunk, &out_data->images[j]);
4348static int cgltf_parse_json_textures(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4350 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_texture), (
void**)&out_data->textures, &out_data->textures_count);
4356 for (cgltf_size j = 0; j < out_data->textures_count; ++j)
4358 i = cgltf_parse_json_texture(options, tokens, i, json_chunk, &out_data->textures[j]);
4367static int cgltf_parse_json_samplers(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4369 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_sampler), (
void**)&out_data->samplers, &out_data->samplers_count);
4375 for (cgltf_size j = 0; j < out_data->samplers_count; ++j)
4377 i = cgltf_parse_json_sampler(options, tokens, i, json_chunk, &out_data->samplers[j]);
4389 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4391 int size = tokens[i].size;
4394 for (
int j = 0; j < size; ++j)
4396 CGLTF_CHECK_KEY(tokens[i]);
4398 if (cgltf_json_strcmp(tokens+i, json_chunk,
"buffer") == 0)
4401 out_meshopt_compression->buffer = CGLTF_PTRINDEX(
cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
4404 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
4407 out_meshopt_compression->offset = cgltf_json_to_size(tokens+i, json_chunk);
4410 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
4413 out_meshopt_compression->size = cgltf_json_to_size(tokens+i, json_chunk);
4416 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteStride") == 0)
4419 out_meshopt_compression->stride = cgltf_json_to_size(tokens+i, json_chunk);
4422 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"count") == 0)
4425 out_meshopt_compression->count = cgltf_json_to_int(tokens+i, json_chunk);
4428 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"mode") == 0)
4431 if (cgltf_json_strcmp(tokens+i, json_chunk,
"ATTRIBUTES") == 0)
4433 out_meshopt_compression->mode = cgltf_meshopt_compression_mode_attributes;
4435 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"TRIANGLES") == 0)
4437 out_meshopt_compression->mode = cgltf_meshopt_compression_mode_triangles;
4439 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"INDICES") == 0)
4441 out_meshopt_compression->mode = cgltf_meshopt_compression_mode_indices;
4445 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"filter") == 0)
4448 if (cgltf_json_strcmp(tokens+i, json_chunk,
"NONE") == 0)
4450 out_meshopt_compression->filter = cgltf_meshopt_compression_filter_none;
4452 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"OCTAHEDRAL") == 0)
4454 out_meshopt_compression->filter = cgltf_meshopt_compression_filter_octahedral;
4456 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"QUATERNION") == 0)
4458 out_meshopt_compression->filter = cgltf_meshopt_compression_filter_quaternion;
4460 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"EXPONENTIAL") == 0)
4462 out_meshopt_compression->filter = cgltf_meshopt_compression_filter_exponential;
4468 i = cgltf_skip_json(tokens, i+1);
4480static 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)
4482 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4484 int size = tokens[i].size;
4487 for (
int j = 0; j < size; ++j)
4489 CGLTF_CHECK_KEY(tokens[i]);
4491 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4493 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer_view->name);
4495 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"buffer") == 0)
4498 out_buffer_view->buffer = CGLTF_PTRINDEX(
cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
4501 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteOffset") == 0)
4504 out_buffer_view->offset =
4505 cgltf_json_to_size(tokens+i, json_chunk);
4508 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
4511 out_buffer_view->size =
4512 cgltf_json_to_size(tokens+i, json_chunk);
4515 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteStride") == 0)
4518 out_buffer_view->stride =
4519 cgltf_json_to_size(tokens+i, json_chunk);
4522 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"target") == 0)
4525 int type = cgltf_json_to_int(tokens+i, json_chunk);
4529 type = cgltf_buffer_view_type_vertices;
4532 type = cgltf_buffer_view_type_indices;
4535 type = cgltf_buffer_view_type_invalid;
4538 out_buffer_view->type = (cgltf_buffer_view_type)type;
4541 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4543 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_buffer_view->extras);
4545 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4549 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4550 if(out_buffer_view->extensions)
4552 return CGLTF_ERROR_JSON;
4555 int extensions_size = tokens[i].size;
4556 out_buffer_view->extensions_count = 0;
4559 if (!out_buffer_view->extensions)
4561 return CGLTF_ERROR_NOMEM;
4565 for (
int k = 0; k < extensions_size; ++k)
4567 CGLTF_CHECK_KEY(tokens[i]);
4569 if (cgltf_json_strcmp(tokens+i, json_chunk,
"EXT_meshopt_compression") == 0)
4571 out_buffer_view->has_meshopt_compression = 1;
4572 i = cgltf_parse_json_meshopt_compression(options, tokens, i + 1, json_chunk, &out_buffer_view->meshopt_compression);
4576 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_buffer_view->extensions[out_buffer_view->extensions_count++]));
4587 i = cgltf_skip_json(tokens, i+1);
4599static int cgltf_parse_json_buffer_views(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4601 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_buffer_view), (
void**)&out_data->buffer_views, &out_data->buffer_views_count);
4607 for (cgltf_size j = 0; j < out_data->buffer_views_count; ++j)
4609 i = cgltf_parse_json_buffer_view(options, tokens, i, json_chunk, &out_data->buffer_views[j]);
4618static int cgltf_parse_json_buffer(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_buffer* out_buffer)
4620 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4622 int size = tokens[i].size;
4625 for (
int j = 0; j < size; ++j)
4627 CGLTF_CHECK_KEY(tokens[i]);
4629 if (cgltf_json_strcmp(tokens + i, json_chunk,
"name") == 0)
4631 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->name);
4633 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"byteLength") == 0)
4637 cgltf_json_to_size(tokens+i, json_chunk);
4640 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"uri") == 0)
4642 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->uri);
4644 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4646 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_buffer->extras);
4648 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4650 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_buffer->extensions_count, &out_buffer->extensions);
4654 i = cgltf_skip_json(tokens, i+1);
4666static int cgltf_parse_json_buffers(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4668 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_buffer), (
void**)&out_data->buffers, &out_data->buffers_count);
4674 for (cgltf_size j = 0; j < out_data->buffers_count; ++j)
4676 i = cgltf_parse_json_buffer(options, tokens, i, json_chunk, &out_data->buffers[j]);
4685static int cgltf_parse_json_skin(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_skin* out_skin)
4687 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4689 int size = tokens[i].size;
4692 for (
int j = 0; j < size; ++j)
4694 CGLTF_CHECK_KEY(tokens[i]);
4696 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4698 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_skin->name);
4700 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"joints") == 0)
4702 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_node*), (
void**)&out_skin->joints, &out_skin->joints_count);
4708 for (cgltf_size k = 0; k < out_skin->joints_count; ++k)
4710 out_skin->joints[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
4714 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"skeleton") == 0)
4717 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
4718 out_skin->skeleton = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
4721 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"inverseBindMatrices") == 0)
4724 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
4725 out_skin->inverse_bind_matrices = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
4728 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4730 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_skin->extras);
4732 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4734 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_skin->extensions_count, &out_skin->extensions);
4738 i = cgltf_skip_json(tokens, i+1);
4750static int cgltf_parse_json_skins(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4752 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_skin), (
void**)&out_data->skins, &out_data->skins_count);
4758 for (cgltf_size j = 0; j < out_data->skins_count; ++j)
4760 i = cgltf_parse_json_skin(options, tokens, i, json_chunk, &out_data->skins[j]);
4769static int cgltf_parse_json_camera(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_camera* out_camera)
4771 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4773 int size = tokens[i].size;
4776 for (
int j = 0; j < size; ++j)
4778 CGLTF_CHECK_KEY(tokens[i]);
4780 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4782 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_camera->name);
4784 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
4787 if (cgltf_json_strcmp(tokens + i, json_chunk,
"perspective") == 0)
4789 out_camera->type = cgltf_camera_type_perspective;
4791 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"orthographic") == 0)
4793 out_camera->type = cgltf_camera_type_orthographic;
4797 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"perspective") == 0)
4801 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4803 int data_size = tokens[i].size;
4806 out_camera->type = cgltf_camera_type_perspective;
4808 for (
int k = 0; k < data_size; ++k)
4810 CGLTF_CHECK_KEY(tokens[i]);
4812 if (cgltf_json_strcmp(tokens+i, json_chunk,
"aspectRatio") == 0)
4815 out_camera->data.perspective.has_aspect_ratio = 1;
4816 out_camera->data.perspective.aspect_ratio = cgltf_json_to_float(tokens + i, json_chunk);
4819 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"yfov") == 0)
4822 out_camera->data.perspective.yfov = cgltf_json_to_float(tokens + i, json_chunk);
4825 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"zfar") == 0)
4828 out_camera->data.perspective.has_zfar = 1;
4829 out_camera->data.perspective.zfar = cgltf_json_to_float(tokens + i, json_chunk);
4832 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"znear") == 0)
4835 out_camera->data.perspective.znear = cgltf_json_to_float(tokens + i, json_chunk);
4838 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4840 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->data.perspective.extras);
4844 i = cgltf_skip_json(tokens, i+1);
4853 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"orthographic") == 0)
4857 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4859 int data_size = tokens[i].size;
4862 out_camera->type = cgltf_camera_type_orthographic;
4864 for (
int k = 0; k < data_size; ++k)
4866 CGLTF_CHECK_KEY(tokens[i]);
4868 if (cgltf_json_strcmp(tokens+i, json_chunk,
"xmag") == 0)
4871 out_camera->data.orthographic.xmag = cgltf_json_to_float(tokens + i, json_chunk);
4874 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"ymag") == 0)
4877 out_camera->data.orthographic.ymag = cgltf_json_to_float(tokens + i, json_chunk);
4880 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"zfar") == 0)
4883 out_camera->data.orthographic.zfar = cgltf_json_to_float(tokens + i, json_chunk);
4886 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"znear") == 0)
4889 out_camera->data.orthographic.znear = cgltf_json_to_float(tokens + i, json_chunk);
4892 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4894 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->data.orthographic.extras);
4898 i = cgltf_skip_json(tokens, i+1);
4907 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
4909 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->extras);
4911 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
4913 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_camera->extensions_count, &out_camera->extensions);
4917 i = cgltf_skip_json(tokens, i+1);
4929static int cgltf_parse_json_cameras(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
4931 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_camera), (
void**)&out_data->cameras, &out_data->cameras_count);
4937 for (cgltf_size j = 0; j < out_data->cameras_count; ++j)
4939 i = cgltf_parse_json_camera(options, tokens, i, json_chunk, &out_data->cameras[j]);
4948static int cgltf_parse_json_light(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_light* out_light)
4950 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
4952 out_light->color[0] = 1.f;
4953 out_light->color[1] = 1.f;
4954 out_light->color[2] = 1.f;
4955 out_light->intensity = 1.f;
4957 out_light->spot_inner_cone_angle = 0.f;
4958 out_light->spot_outer_cone_angle = 3.1415926535f / 4.0f;
4960 int size = tokens[i].size;
4963 for (
int j = 0; j < size; ++j)
4965 CGLTF_CHECK_KEY(tokens[i]);
4967 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
4969 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_light->name);
4971 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"color") == 0)
4973 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_light->color, 3);
4975 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"intensity") == 0)
4978 out_light->intensity = cgltf_json_to_float(tokens + i, json_chunk);
4981 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"type") == 0)
4984 if (cgltf_json_strcmp(tokens + i, json_chunk,
"directional") == 0)
4986 out_light->type = cgltf_light_type_directional;
4988 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"point") == 0)
4990 out_light->type = cgltf_light_type_point;
4992 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"spot") == 0)
4994 out_light->type = cgltf_light_type_spot;
4998 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"range") == 0)
5001 out_light->range = cgltf_json_to_float(tokens + i, json_chunk);
5004 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"spot") == 0)
5008 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5010 int data_size = tokens[i].size;
5013 for (
int k = 0; k < data_size; ++k)
5015 CGLTF_CHECK_KEY(tokens[i]);
5017 if (cgltf_json_strcmp(tokens+i, json_chunk,
"innerConeAngle") == 0)
5020 out_light->spot_inner_cone_angle = cgltf_json_to_float(tokens + i, json_chunk);
5023 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"outerConeAngle") == 0)
5026 out_light->spot_outer_cone_angle = cgltf_json_to_float(tokens + i, json_chunk);
5031 i = cgltf_skip_json(tokens, i+1);
5040 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5042 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_light->extras);
5046 i = cgltf_skip_json(tokens, i+1);
5058static int cgltf_parse_json_lights(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5060 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_light), (
void**)&out_data->lights, &out_data->lights_count);
5066 for (cgltf_size j = 0; j < out_data->lights_count; ++j)
5068 i = cgltf_parse_json_light(options, tokens, i, json_chunk, &out_data->lights[j]);
5077static int cgltf_parse_json_node(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_node* out_node)
5079 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5081 out_node->rotation[3] = 1.0f;
5082 out_node->scale[0] = 1.0f;
5083 out_node->scale[1] = 1.0f;
5084 out_node->scale[2] = 1.0f;
5085 out_node->matrix[0] = 1.0f;
5086 out_node->matrix[5] = 1.0f;
5087 out_node->matrix[10] = 1.0f;
5088 out_node->matrix[15] = 1.0f;
5090 int size = tokens[i].size;
5093 for (
int j = 0; j < size; ++j)
5095 CGLTF_CHECK_KEY(tokens[i]);
5097 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5099 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_node->name);
5101 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"children") == 0)
5103 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_node*), (
void**)&out_node->children, &out_node->children_count);
5109 for (cgltf_size k = 0; k < out_node->children_count; ++k)
5111 out_node->children[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5115 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"mesh") == 0)
5118 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5119 out_node->mesh = CGLTF_PTRINDEX(
cgltf_mesh, cgltf_json_to_int(tokens + i, json_chunk));
5122 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"skin") == 0)
5125 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5126 out_node->skin = CGLTF_PTRINDEX(
cgltf_skin, cgltf_json_to_int(tokens + i, json_chunk));
5129 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"camera") == 0)
5132 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5133 out_node->camera = CGLTF_PTRINDEX(
cgltf_camera, cgltf_json_to_int(tokens + i, json_chunk));
5136 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"translation") == 0)
5138 out_node->has_translation = 1;
5139 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->translation, 3);
5141 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"rotation") == 0)
5143 out_node->has_rotation = 1;
5144 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->rotation, 4);
5146 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"scale") == 0)
5148 out_node->has_scale = 1;
5149 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->scale, 3);
5151 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"matrix") == 0)
5153 out_node->has_matrix = 1;
5154 i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->matrix, 16);
5156 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"weights") == 0)
5158 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(cgltf_float), (
void**)&out_node->weights, &out_node->weights_count);
5164 i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_node->weights, (
int)out_node->weights_count);
5166 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5168 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_node->extras);
5170 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5174 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5175 if(out_node->extensions)
5177 return CGLTF_ERROR_JSON;
5180 int extensions_size = tokens[i].size;
5181 out_node->extensions_count= 0;
5184 if (!out_node->extensions)
5186 return CGLTF_ERROR_NOMEM;
5191 for (
int k = 0; k < extensions_size; ++k)
5193 CGLTF_CHECK_KEY(tokens[i]);
5195 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_lights_punctual") == 0)
5199 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5201 int data_size = tokens[i].size;
5204 for (
int m = 0; m < data_size; ++m)
5206 CGLTF_CHECK_KEY(tokens[i]);
5208 if (cgltf_json_strcmp(tokens + i, json_chunk,
"light") == 0)
5211 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
5212 out_node->light = CGLTF_PTRINDEX(
cgltf_light, cgltf_json_to_int(tokens + i, json_chunk));
5217 i = cgltf_skip_json(tokens, i + 1);
5228 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_node->extensions[out_node->extensions_count++]));
5239 i = cgltf_skip_json(tokens, i+1);
5251static int cgltf_parse_json_nodes(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5253 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_node), (
void**)&out_data->nodes, &out_data->nodes_count);
5259 for (cgltf_size j = 0; j < out_data->nodes_count; ++j)
5261 i = cgltf_parse_json_node(options, tokens, i, json_chunk, &out_data->nodes[j]);
5270static int cgltf_parse_json_scene(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_scene* out_scene)
5272 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5274 int size = tokens[i].size;
5277 for (
int j = 0; j < size; ++j)
5279 CGLTF_CHECK_KEY(tokens[i]);
5281 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5283 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_scene->name);
5285 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"nodes") == 0)
5287 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_node*), (
void**)&out_scene->nodes, &out_scene->nodes_count);
5293 for (cgltf_size k = 0; k < out_scene->nodes_count; ++k)
5295 out_scene->nodes[k] = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5299 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5301 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_scene->extras);
5303 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5305 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_scene->extensions_count, &out_scene->extensions);
5309 i = cgltf_skip_json(tokens, i+1);
5321static int cgltf_parse_json_scenes(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5323 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_scene), (
void**)&out_data->scenes, &out_data->scenes_count);
5329 for (cgltf_size j = 0; j < out_data->scenes_count; ++j)
5331 i = cgltf_parse_json_scene(options, tokens, i, json_chunk, &out_data->scenes[j]);
5343 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5345 int size = tokens[i].size;
5348 for (
int j = 0; j < size; ++j)
5350 CGLTF_CHECK_KEY(tokens[i]);
5352 if (cgltf_json_strcmp(tokens+i, json_chunk,
"input") == 0)
5355 out_sampler->input = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
5358 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"output") == 0)
5361 out_sampler->output = CGLTF_PTRINDEX(
cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
5364 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"interpolation") == 0)
5367 if (cgltf_json_strcmp(tokens + i, json_chunk,
"LINEAR") == 0)
5369 out_sampler->interpolation = cgltf_interpolation_type_linear;
5371 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"STEP") == 0)
5373 out_sampler->interpolation = cgltf_interpolation_type_step;
5375 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"CUBICSPLINE") == 0)
5377 out_sampler->interpolation = cgltf_interpolation_type_cubic_spline;
5381 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5383 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sampler->extras);
5385 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5387 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->extensions_count, &out_sampler->extensions);
5391 i = cgltf_skip_json(tokens, i+1);
5406 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5408 int size = tokens[i].size;
5411 for (
int j = 0; j < size; ++j)
5413 CGLTF_CHECK_KEY(tokens[i]);
5415 if (cgltf_json_strcmp(tokens+i, json_chunk,
"sampler") == 0)
5421 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"target") == 0)
5425 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5427 int target_size = tokens[i].size;
5430 for (
int k = 0; k < target_size; ++k)
5432 CGLTF_CHECK_KEY(tokens[i]);
5434 if (cgltf_json_strcmp(tokens+i, json_chunk,
"node") == 0)
5437 out_channel->target_node = CGLTF_PTRINDEX(
cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
5440 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"path") == 0)
5443 if (cgltf_json_strcmp(tokens+i, json_chunk,
"translation") == 0)
5445 out_channel->target_path = cgltf_animation_path_type_translation;
5447 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"rotation") == 0)
5449 out_channel->target_path = cgltf_animation_path_type_rotation;
5451 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"scale") == 0)
5453 out_channel->target_path = cgltf_animation_path_type_scale;
5455 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"weights") == 0)
5457 out_channel->target_path = cgltf_animation_path_type_weights;
5461 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5463 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_channel->extras);
5465 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5467 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_channel->extensions_count, &out_channel->extensions);
5471 i = cgltf_skip_json(tokens, i+1);
5482 i = cgltf_skip_json(tokens, i+1);
5494static int cgltf_parse_json_animation(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_animation* out_animation)
5496 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5498 int size = tokens[i].size;
5501 for (
int j = 0; j < size; ++j)
5503 CGLTF_CHECK_KEY(tokens[i]);
5505 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5507 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_animation->name);
5509 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"samplers") == 0)
5511 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_animation_sampler), (
void**)&out_animation->samplers, &out_animation->samplers_count);
5517 for (cgltf_size k = 0; k < out_animation->samplers_count; ++k)
5519 i = cgltf_parse_json_animation_sampler(options, tokens, i, json_chunk, &out_animation->samplers[k]);
5526 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"channels") == 0)
5528 i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk,
sizeof(
cgltf_animation_channel), (
void**)&out_animation->channels, &out_animation->channels_count);
5534 for (cgltf_size k = 0; k < out_animation->channels_count; ++k)
5536 i = cgltf_parse_json_animation_channel(options, tokens, i, json_chunk, &out_animation->channels[k]);
5543 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5545 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_animation->extras);
5547 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5549 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_animation->extensions_count, &out_animation->extensions);
5553 i = cgltf_skip_json(tokens, i+1);
5565static int cgltf_parse_json_animations(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5567 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_animation), (
void**)&out_data->animations, &out_data->animations_count);
5573 for (cgltf_size j = 0; j < out_data->animations_count; ++j)
5575 i = cgltf_parse_json_animation(options, tokens, i, json_chunk, &out_data->animations[j]);
5586 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5588 int size = tokens[i].size;
5591 for (
int j = 0; j < size; ++j)
5593 CGLTF_CHECK_KEY(tokens[i]);
5595 if (cgltf_json_strcmp(tokens+i, json_chunk,
"name") == 0)
5597 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_variant->name);
5599 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5601 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_variant->extras);
5605 i = cgltf_skip_json(tokens, i+1);
5617static int cgltf_parse_json_variants(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5619 i = cgltf_parse_json_array(options, tokens, i, json_chunk,
sizeof(
cgltf_material_variant), (
void**)&out_data->variants, &out_data->variants_count);
5625 for (cgltf_size j = 0; j < out_data->variants_count; ++j)
5627 i = cgltf_parse_json_variant(options, tokens, i, json_chunk, &out_data->variants[j]);
5636static int cgltf_parse_json_asset(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_asset* out_asset)
5638 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5640 int size = tokens[i].size;
5643 for (
int j = 0; j < size; ++j)
5645 CGLTF_CHECK_KEY(tokens[i]);
5647 if (cgltf_json_strcmp(tokens+i, json_chunk,
"copyright") == 0)
5649 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->copyright);
5651 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"generator") == 0)
5653 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->generator);
5655 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"version") == 0)
5657 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->version);
5659 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"minVersion") == 0)
5661 i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->min_version);
5663 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extras") == 0)
5665 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_asset->extras);
5667 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5669 i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_asset->extensions_count, &out_asset->extensions);
5673 i = cgltf_skip_json(tokens, i+1);
5682 if (out_asset->version && CGLTF_ATOF(out_asset->version) < 2)
5684 return CGLTF_ERROR_LEGACY;
5690cgltf_size cgltf_num_components(cgltf_type type) {
5693 case cgltf_type_vec2:
5695 case cgltf_type_vec3:
5697 case cgltf_type_vec4:
5699 case cgltf_type_mat2:
5701 case cgltf_type_mat3:
5703 case cgltf_type_mat4:
5705 case cgltf_type_invalid:
5706 case cgltf_type_scalar:
5712static cgltf_size cgltf_component_size(cgltf_component_type component_type) {
5713 switch (component_type)
5715 case cgltf_component_type_r_8:
5716 case cgltf_component_type_r_8u:
5718 case cgltf_component_type_r_16:
5719 case cgltf_component_type_r_16u:
5721 case cgltf_component_type_r_32u:
5722 case cgltf_component_type_r_32f:
5724 case cgltf_component_type_invalid:
5730static cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type)
5732 cgltf_size component_size = cgltf_component_size(component_type);
5733 if (type == cgltf_type_mat2 && component_size == 1)
5735 return 8 * component_size;
5737 else if (type == cgltf_type_mat3 && (component_size == 1 || component_size == 2))
5739 return 12 * component_size;
5741 return component_size * cgltf_num_components(type);
5744static int cgltf_fixup_pointers(
cgltf_data* out_data);
5746static int cgltf_parse_json_root(
cgltf_options* options, jsmntok_t
const* tokens,
int i,
const uint8_t* json_chunk,
cgltf_data* out_data)
5748 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5750 int size = tokens[i].size;
5753 for (
int j = 0; j < size; ++j)
5755 CGLTF_CHECK_KEY(tokens[i]);
5757 if (cgltf_json_strcmp(tokens + i, json_chunk,
"asset") == 0)
5759 i = cgltf_parse_json_asset(options, tokens, i + 1, json_chunk, &out_data->asset);
5761 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"meshes") == 0)
5763 i = cgltf_parse_json_meshes(options, tokens, i + 1, json_chunk, out_data);
5765 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"accessors") == 0)
5767 i = cgltf_parse_json_accessors(options, tokens, i + 1, json_chunk, out_data);
5769 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"bufferViews") == 0)
5771 i = cgltf_parse_json_buffer_views(options, tokens, i + 1, json_chunk, out_data);
5773 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"buffers") == 0)
5775 i = cgltf_parse_json_buffers(options, tokens, i + 1, json_chunk, out_data);
5777 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"materials") == 0)
5779 i = cgltf_parse_json_materials(options, tokens, i + 1, json_chunk, out_data);
5781 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"images") == 0)
5783 i = cgltf_parse_json_images(options, tokens, i + 1, json_chunk, out_data);
5785 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"textures") == 0)
5787 i = cgltf_parse_json_textures(options, tokens, i + 1, json_chunk, out_data);
5789 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"samplers") == 0)
5791 i = cgltf_parse_json_samplers(options, tokens, i + 1, json_chunk, out_data);
5793 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"skins") == 0)
5795 i = cgltf_parse_json_skins(options, tokens, i + 1, json_chunk, out_data);
5797 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"cameras") == 0)
5799 i = cgltf_parse_json_cameras(options, tokens, i + 1, json_chunk, out_data);
5801 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"nodes") == 0)
5803 i = cgltf_parse_json_nodes(options, tokens, i + 1, json_chunk, out_data);
5805 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scenes") == 0)
5807 i = cgltf_parse_json_scenes(options, tokens, i + 1, json_chunk, out_data);
5809 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"scene") == 0)
5812 out_data->scene = CGLTF_PTRINDEX(
cgltf_scene, cgltf_json_to_int(tokens + i, json_chunk));
5815 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"animations") == 0)
5817 i = cgltf_parse_json_animations(options, tokens, i + 1, json_chunk, out_data);
5819 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"extras") == 0)
5821 i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_data->extras);
5823 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensions") == 0)
5827 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5828 if(out_data->data_extensions)
5830 return CGLTF_ERROR_JSON;
5833 int extensions_size = tokens[i].size;
5834 out_data->data_extensions_count = 0;
5837 if (!out_data->data_extensions)
5839 return CGLTF_ERROR_NOMEM;
5844 for (
int k = 0; k < extensions_size; ++k)
5846 CGLTF_CHECK_KEY(tokens[i]);
5848 if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_lights_punctual") == 0)
5852 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5854 int data_size = tokens[i].size;
5857 for (
int m = 0; m < data_size; ++m)
5859 CGLTF_CHECK_KEY(tokens[i]);
5861 if (cgltf_json_strcmp(tokens + i, json_chunk,
"lights") == 0)
5863 i = cgltf_parse_json_lights(options, tokens, i + 1, json_chunk, out_data);
5867 i = cgltf_skip_json(tokens, i + 1);
5876 else if (cgltf_json_strcmp(tokens+i, json_chunk,
"KHR_materials_variants") == 0)
5880 CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
5882 int data_size = tokens[i].size;
5885 for (
int m = 0; m < data_size; ++m)
5887 CGLTF_CHECK_KEY(tokens[i]);
5889 if (cgltf_json_strcmp(tokens + i, json_chunk,
"variants") == 0)
5891 i = cgltf_parse_json_variants(options, tokens, i + 1, json_chunk, out_data);
5895 i = cgltf_skip_json(tokens, i + 1);
5906 i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_data->data_extensions[out_data->data_extensions_count++]));
5915 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensionsUsed") == 0)
5917 i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_data->extensions_used, &out_data->extensions_used_count);
5919 else if (cgltf_json_strcmp(tokens + i, json_chunk,
"extensionsRequired") == 0)
5921 i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_data->extensions_required, &out_data->extensions_required_count);
5925 i = cgltf_skip_json(tokens, i + 1);
5937cgltf_result cgltf_parse_json(
cgltf_options* options,
const uint8_t* json_chunk, cgltf_size size,
cgltf_data** out_data)
5939 jsmn_parser parser = { 0, 0, 0 };
5941 if (options->json_token_count == 0)
5943 int token_count = jsmn_parse(&parser, (
const char*)json_chunk, size, NULL, 0);
5945 if (token_count <= 0)
5947 return cgltf_result_invalid_json;
5950 options->json_token_count = token_count;
5953 jsmntok_t* tokens = (jsmntok_t*)options->memory.alloc(options->memory.user_data,
sizeof(jsmntok_t) * (options->json_token_count + 1));
5957 return cgltf_result_out_of_memory;
5962 int token_count = jsmn_parse(&parser, (
const char*)json_chunk, size, tokens, options->json_token_count);
5964 if (token_count <= 0)
5966 options->memory.free(options->memory.user_data, tokens);
5967 return cgltf_result_invalid_json;
5972 tokens[token_count].type = JSMN_UNDEFINED;
5978 options->memory.free(options->memory.user_data, tokens);
5979 return cgltf_result_out_of_memory;
5983 data->memory = options->memory;
5984 data->file = options->file;
5986 int i = cgltf_parse_json_root(options, tokens, 0, json_chunk, data);
5988 options->memory.free(options->memory.user_data, tokens);
5996 case CGLTF_ERROR_NOMEM:
return cgltf_result_out_of_memory;
5997 case CGLTF_ERROR_LEGACY:
return cgltf_result_legacy_gltf;
5998 default:
return cgltf_result_invalid_gltf;
6002 if (cgltf_fixup_pointers(data) < 0)
6005 return cgltf_result_invalid_gltf;
6008 data->json = (
const char*)json_chunk;
6009 data->json_size = size;
6013 return cgltf_result_success;
6016static int cgltf_fixup_pointers(
cgltf_data* data)
6018 for (cgltf_size i = 0; i < data->meshes_count; ++i)
6020 for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
6022 CGLTF_PTRFIXUP(data->meshes[i].primitives[j].indices, data->accessors, data->accessors_count);
6023 CGLTF_PTRFIXUP(data->meshes[i].primitives[j].material, data->materials, data->materials_count);
6025 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
6027 CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].attributes[k].data, data->accessors, data->accessors_count);
6030 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
6032 for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
6034 CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].targets[k].attributes[m].data, data->accessors, data->accessors_count);
6038 if (data->meshes[i].primitives[j].has_draco_mesh_compression)
6040 CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.buffer_view, data->buffer_views, data->buffer_views_count);
6041 for (cgltf_size m = 0; m < data->meshes[i].primitives[j].draco_mesh_compression.attributes_count; ++m)
6043 CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.attributes[m].data, data->accessors, data->accessors_count);
6047 for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
6049 CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].mappings[k].material, data->materials, data->materials_count);
6054 for (cgltf_size i = 0; i < data->accessors_count; ++i)
6056 CGLTF_PTRFIXUP(data->accessors[i].buffer_view, data->buffer_views, data->buffer_views_count);
6058 if (data->accessors[i].is_sparse)
6060 CGLTF_PTRFIXUP_REQ(data->accessors[i].sparse.indices_buffer_view, data->buffer_views, data->buffer_views_count);
6061 CGLTF_PTRFIXUP_REQ(data->accessors[i].sparse.values_buffer_view, data->buffer_views, data->buffer_views_count);
6064 if (data->accessors[i].buffer_view)
6066 data->accessors[i].stride = data->accessors[i].buffer_view->stride;
6069 if (data->accessors[i].stride == 0)
6071 data->accessors[i].stride = cgltf_calc_size(data->accessors[i].type, data->accessors[i].component_type);
6075 for (cgltf_size i = 0; i < data->textures_count; ++i)
6077 CGLTF_PTRFIXUP(data->textures[i].image, data->images, data->images_count);
6078 CGLTF_PTRFIXUP(data->textures[i].basisu_image, data->images, data->images_count);
6079 CGLTF_PTRFIXUP(data->textures[i].sampler, data->samplers, data->samplers_count);
6082 for (cgltf_size i = 0; i < data->images_count; ++i)
6084 CGLTF_PTRFIXUP(data->images[i].buffer_view, data->buffer_views, data->buffer_views_count);
6087 for (cgltf_size i = 0; i < data->materials_count; ++i)
6089 CGLTF_PTRFIXUP(data->materials[i].normal_texture.texture, data->textures, data->textures_count);
6090 CGLTF_PTRFIXUP(data->materials[i].emissive_texture.texture, data->textures, data->textures_count);
6091 CGLTF_PTRFIXUP(data->materials[i].occlusion_texture.texture, data->textures, data->textures_count);
6093 CGLTF_PTRFIXUP(data->materials[i].pbr_metallic_roughness.base_color_texture.texture, data->textures, data->textures_count);
6094 CGLTF_PTRFIXUP(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture, data->textures, data->textures_count);
6096 CGLTF_PTRFIXUP(data->materials[i].pbr_specular_glossiness.diffuse_texture.texture, data->textures, data->textures_count);
6097 CGLTF_PTRFIXUP(data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.texture, data->textures, data->textures_count);
6099 CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_texture.texture, data->textures, data->textures_count);
6100 CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_roughness_texture.texture, data->textures, data->textures_count);
6101 CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_normal_texture.texture, data->textures, data->textures_count);
6103 CGLTF_PTRFIXUP(data->materials[i].specular.specular_texture.texture, data->textures, data->textures_count);
6104 CGLTF_PTRFIXUP(data->materials[i].specular.specular_color_texture.texture, data->textures, data->textures_count);
6106 CGLTF_PTRFIXUP(data->materials[i].transmission.transmission_texture.texture, data->textures, data->textures_count);
6108 CGLTF_PTRFIXUP(data->materials[i].volume.thickness_texture.texture, data->textures, data->textures_count);
6110 CGLTF_PTRFIXUP(data->materials[i].sheen.sheen_color_texture.texture, data->textures, data->textures_count);
6111 CGLTF_PTRFIXUP(data->materials[i].sheen.sheen_roughness_texture.texture, data->textures, data->textures_count);
6114 for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
6116 CGLTF_PTRFIXUP_REQ(data->buffer_views[i].buffer, data->buffers, data->buffers_count);
6118 if (data->buffer_views[i].has_meshopt_compression)
6120 CGLTF_PTRFIXUP_REQ(data->buffer_views[i].meshopt_compression.buffer, data->buffers, data->buffers_count);
6124 for (cgltf_size i = 0; i < data->skins_count; ++i)
6126 for (cgltf_size j = 0; j < data->skins[i].joints_count; ++j)
6128 CGLTF_PTRFIXUP_REQ(data->skins[i].joints[j], data->nodes, data->nodes_count);
6131 CGLTF_PTRFIXUP(data->skins[i].skeleton, data->nodes, data->nodes_count);
6132 CGLTF_PTRFIXUP(data->skins[i].inverse_bind_matrices, data->accessors, data->accessors_count);
6135 for (cgltf_size i = 0; i < data->nodes_count; ++i)
6137 for (cgltf_size j = 0; j < data->nodes[i].children_count; ++j)
6139 CGLTF_PTRFIXUP_REQ(data->nodes[i].children[j], data->nodes, data->nodes_count);
6141 if (data->nodes[i].children[j]->parent)
6143 return CGLTF_ERROR_JSON;
6146 data->nodes[i].children[j]->parent = &data->nodes[i];
6149 CGLTF_PTRFIXUP(data->nodes[i].mesh, data->meshes, data->meshes_count);
6150 CGLTF_PTRFIXUP(data->nodes[i].skin, data->skins, data->skins_count);
6151 CGLTF_PTRFIXUP(data->nodes[i].camera, data->cameras, data->cameras_count);
6152 CGLTF_PTRFIXUP(data->nodes[i].light, data->lights, data->lights_count);
6155 for (cgltf_size i = 0; i < data->scenes_count; ++i)
6157 for (cgltf_size j = 0; j < data->scenes[i].nodes_count; ++j)
6159 CGLTF_PTRFIXUP_REQ(data->scenes[i].nodes[j], data->nodes, data->nodes_count);
6161 if (data->scenes[i].nodes[j]->parent)
6163 return CGLTF_ERROR_JSON;
6168 CGLTF_PTRFIXUP(data->scene, data->scenes, data->scenes_count);
6170 for (cgltf_size i = 0; i < data->animations_count; ++i)
6172 for (cgltf_size j = 0; j < data->animations[i].samplers_count; ++j)
6174 CGLTF_PTRFIXUP_REQ(data->animations[i].samplers[j].input, data->accessors, data->accessors_count);
6175 CGLTF_PTRFIXUP_REQ(data->animations[i].samplers[j].output, data->accessors, data->accessors_count);
6178 for (cgltf_size j = 0; j < data->animations[i].channels_count; ++j)
6180 CGLTF_PTRFIXUP_REQ(data->animations[i].channels[j].sampler, data->animations[i].samplers, data->animations[i].samplers_count);
6181 CGLTF_PTRFIXUP(data->animations[i].channels[j].target_node, data->nodes, data->nodes_count);
6217static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
6218 jsmntok_t *tokens,
size_t num_tokens) {
6220 if (parser->toknext >= num_tokens) {
6223 tok = &tokens[parser->toknext++];
6224 tok->start = tok->end = -1;
6226#ifdef JSMN_PARENT_LINKS
6235static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
6236 int start,
int end) {
6238 token->start = start;
6246static int jsmn_parse_primitive(jsmn_parser *parser,
const char *js,
6247 size_t len, jsmntok_t *tokens,
size_t num_tokens) {
6251 start = parser->pos;
6253 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
6254 switch (js[parser->pos]) {
6259 case '\t' :
case '\r' :
case '\n' :
case ' ' :
6260 case ',' :
case ']' :
case '}' :
6263 if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
6264 parser->pos = start;
6265 return JSMN_ERROR_INVAL;
6270 parser->pos = start;
6271 return JSMN_ERROR_PART;
6275 if (tokens == NULL) {
6279 token = jsmn_alloc_token(parser, tokens, num_tokens);
6280 if (token == NULL) {
6281 parser->pos = start;
6282 return JSMN_ERROR_NOMEM;
6284 jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
6285#ifdef JSMN_PARENT_LINKS
6286 token->parent = parser->toksuper;
6295static int jsmn_parse_string(jsmn_parser *parser,
const char *js,
6296 size_t len, jsmntok_t *tokens,
size_t num_tokens) {
6299 int start = parser->pos;
6304 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
6305 char c = js[parser->pos];
6309 if (tokens == NULL) {
6312 token = jsmn_alloc_token(parser, tokens, num_tokens);
6313 if (token == NULL) {
6314 parser->pos = start;
6315 return JSMN_ERROR_NOMEM;
6317 jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
6318#ifdef JSMN_PARENT_LINKS
6319 token->parent = parser->toksuper;
6325 if (
c ==
'\\' && parser->pos + 1 < len) {
6328 switch (js[parser->pos]) {
6330 case '\"':
case '/' :
case '\\' :
case 'b' :
6331 case 'f' :
case 'r' :
case 'n' :
case 't' :
6336 for(i = 0; i < 4 && parser->pos < len && js[parser->pos] !=
'\0'; i++) {
6338 if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) ||
6339 (js[parser->pos] >= 65 && js[parser->pos] <= 70) ||
6340 (js[parser->pos] >= 97 && js[parser->pos] <= 102))) {
6341 parser->pos = start;
6342 return JSMN_ERROR_INVAL;
6350 parser->pos = start;
6351 return JSMN_ERROR_INVAL;
6355 parser->pos = start;
6356 return JSMN_ERROR_PART;
6362static int jsmn_parse(jsmn_parser *parser,
const char *js,
size_t len,
6363 jsmntok_t *tokens,
size_t num_tokens) {
6367 int count = parser->toknext;
6369 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
6373 c = js[parser->pos];
6377 if (tokens == NULL) {
6380 token = jsmn_alloc_token(parser, tokens, num_tokens);
6382 return JSMN_ERROR_NOMEM;
6383 if (parser->toksuper != -1) {
6384 tokens[parser->toksuper].size++;
6385#ifdef JSMN_PARENT_LINKS
6386 token->parent = parser->toksuper;
6389 token->type = (
c ==
'{' ? JSMN_OBJECT : JSMN_ARRAY);
6390 token->start = parser->pos;
6391 parser->toksuper = parser->toknext - 1;
6396 type = (
c ==
'}' ? JSMN_OBJECT : JSMN_ARRAY);
6397#ifdef JSMN_PARENT_LINKS
6398 if (parser->toknext < 1) {
6399 return JSMN_ERROR_INVAL;
6401 token = &tokens[parser->toknext - 1];
6403 if (token->start != -1 && token->end == -1) {
6404 if (token->type != type) {
6405 return JSMN_ERROR_INVAL;
6407 token->end = parser->pos + 1;
6408 parser->toksuper = token->parent;
6411 if (token->parent == -1) {
6412 if(token->type != type || parser->toksuper == -1) {
6413 return JSMN_ERROR_INVAL;
6417 token = &tokens[token->parent];
6420 for (i = parser->toknext - 1; i >= 0; i--) {
6422 if (token->start != -1 && token->end == -1) {
6423 if (token->type != type) {
6424 return JSMN_ERROR_INVAL;
6426 parser->toksuper = -1;
6427 token->end = parser->pos + 1;
6432 if (i == -1)
return JSMN_ERROR_INVAL;
6433 for (; i >= 0; i--) {
6435 if (token->start != -1 && token->end == -1) {
6436 parser->toksuper = i;
6443 r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
6444 if (r < 0)
return r;
6446 if (parser->toksuper != -1 && tokens != NULL)
6447 tokens[parser->toksuper].size++;
6449 case '\t' :
case '\r' :
case '\n' :
case ' ':
6452 parser->toksuper = parser->toknext - 1;
6455 if (tokens != NULL && parser->toksuper != -1 &&
6456 tokens[parser->toksuper].type != JSMN_ARRAY &&
6457 tokens[parser->toksuper].type != JSMN_OBJECT) {
6458#ifdef JSMN_PARENT_LINKS
6459 parser->toksuper = tokens[parser->toksuper].parent;
6461 for (i = parser->toknext - 1; i >= 0; i--) {
6462 if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
6463 if (tokens[i].start != -1 && tokens[i].end == -1) {
6464 parser->toksuper = i;
6474 case '-':
case '0':
case '1' :
case '2':
case '3' :
case '4':
6475 case '5':
case '6':
case '7' :
case '8':
case '9':
6476 case 't':
case 'f':
case 'n' :
6478 if (tokens != NULL && parser->toksuper != -1) {
6479 jsmntok_t *t = &tokens[parser->toksuper];
6480 if (t->type == JSMN_OBJECT ||
6481 (t->type == JSMN_STRING && t->size != 0)) {
6482 return JSMN_ERROR_INVAL;
6489 r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
6490 if (r < 0)
return r;
6492 if (parser->toksuper != -1 && tokens != NULL)
6493 tokens[parser->toksuper].size++;
6499 return JSMN_ERROR_INVAL;
6504 if (tokens != NULL) {
6505 for (i = parser->toknext - 1; i >= 0; i--) {
6507 if (tokens[i].start != -1 && tokens[i].end == -1) {
6508 return JSMN_ERROR_PART;
6520static void jsmn_init(jsmn_parser *parser) {
6522 parser->toknext = 0;
6523 parser->toksuper = -1;