minesweeper

A minewseeper implementation to play around with Hare and Raylib
git clone https://git.tronto.net/minesweeper
Download | Log | Files | Refs | README | LICENSE

cgltf.h (199324B)


      1 /**
      2  * cgltf - a single-file glTF 2.0 parser written in C99.
      3  *
      4  * Version: 1.14
      5  *
      6  * Website: https://github.com/jkuhlmann/cgltf
      7  *
      8  * Distributed under the MIT License, see notice at the end of this file.
      9  *
     10  * Building:
     11  * Include this file where you need the struct and function
     12  * declarations. Have exactly one source file where you define
     13  * `CGLTF_IMPLEMENTATION` before including this file to get the
     14  * function definitions.
     15  *
     16  * Reference:
     17  * `cgltf_result cgltf_parse(const cgltf_options*, const void*,
     18  * cgltf_size, cgltf_data**)` parses both glTF and GLB data. If
     19  * this function returns `cgltf_result_success`, you have to call
     20  * `cgltf_free()` on the created `cgltf_data*` variable.
     21  * Note that contents of external files for buffers and images are not
     22  * automatically loaded. You'll need to read these files yourself using
     23  * URIs in the `cgltf_data` structure.
     24  *
     25  * `cgltf_options` is the struct passed to `cgltf_parse()` to control
     26  * parts of the parsing process. You can use it to force the file type
     27  * and provide memory allocation as well as file operation callbacks.
     28  * Should be zero-initialized to trigger default behavior.
     29  *
     30  * `cgltf_data` is the struct allocated and filled by `cgltf_parse()`.
     31  * It generally mirrors the glTF format as described by the spec (see
     32  * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0).
     33  *
     34  * `void cgltf_free(cgltf_data*)` frees the allocated `cgltf_data`
     35  * variable.
     36  *
     37  * `cgltf_result cgltf_load_buffers(const cgltf_options*, cgltf_data*,
     38  * const char* gltf_path)` can be optionally called to open and read buffer
     39  * files using the `FILE*` APIs. The `gltf_path` argument is the path to
     40  * the original glTF file, which allows the parser to resolve the path to
     41  * buffer files.
     42  *
     43  * `cgltf_result cgltf_load_buffer_base64(const cgltf_options* options,
     44  * cgltf_size size, const char* base64, void** out_data)` decodes
     45  * base64-encoded data content. Used internally by `cgltf_load_buffers()`.
     46  * This is useful when decoding data URIs in images.
     47  *
     48  * `cgltf_result cgltf_parse_file(const cgltf_options* options, const
     49  * char* path, cgltf_data** out_data)` can be used to open the given
     50  * file using `FILE*` APIs and parse the data using `cgltf_parse()`.
     51  *
     52  * `cgltf_result cgltf_validate(cgltf_data*)` can be used to do additional
     53  * checks to make sure the parsed glTF data is valid.
     54  *
     55  * `cgltf_node_transform_local` converts the translation / rotation / scale properties of a node
     56  * into a mat4.
     57  *
     58  * `cgltf_node_transform_world` calls `cgltf_node_transform_local` on every ancestor in order
     59  * to compute the root-to-node transformation.
     60  *
     61  * `cgltf_accessor_unpack_floats` reads in the data from an accessor, applies sparse data (if any),
     62  * and converts them to floating point. Assumes that `cgltf_load_buffers` has already been called.
     63  * By passing null for the output pointer, users can find out how many floats are required in the
     64  * output buffer.
     65  *
     66  * `cgltf_accessor_unpack_indices` reads in the index data from an accessor. Assumes that
     67  * `cgltf_load_buffers` has already been called. By passing null for the output pointer, users can
     68  * find out how many indices are required in the output buffer. Returns 0 if the accessor is
     69  * sparse or if the output component size is less than the accessor's component size.
     70  *
     71  * `cgltf_num_components` is a tiny utility that tells you the dimensionality of
     72  * a certain accessor type. This can be used before `cgltf_accessor_unpack_floats` to help allocate
     73  * the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for
     74  * similar purposes.
     75  *
     76  * `cgltf_accessor_read_float` reads a certain element from a non-sparse accessor and converts it to
     77  * floating point, assuming that `cgltf_load_buffers` has already been called. The passed-in element
     78  * size is the number of floats in the output buffer, which should be in the range [1, 16]. Returns
     79  * false if the passed-in element_size is too small, or if the accessor is sparse.
     80  *
     81  * `cgltf_accessor_read_uint` is similar to its floating-point counterpart, but limited to reading
     82  * vector types and does not support matrix types. The passed-in element size is the number of uints
     83  * in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in
     84  * element_size is too small, or if the accessor is sparse.
     85  *
     86  * `cgltf_accessor_read_index` is similar to its floating-point counterpart, but it returns size_t
     87  * and only works with single-component data types.
     88  *
     89  * `cgltf_copy_extras_json` allows users to retrieve the "extras" data that can be attached to many
     90  * glTF objects (which can be arbitrary JSON data). This is a legacy function, consider using
     91  * cgltf_extras::data directly instead. You can parse this data using your own JSON parser
     92  * or, if you've included the cgltf implementation using the integrated JSMN JSON parser.
     93  */
     94 #ifndef CGLTF_H_INCLUDED__
     95 #define CGLTF_H_INCLUDED__
     96 
     97 #include <stddef.h>
     98 #include <stdint.h> /* For uint8_t, uint32_t */
     99 
    100 #ifdef __cplusplus
    101 extern "C" {
    102 #endif
    103 
    104 typedef size_t cgltf_size;
    105 typedef long long int cgltf_ssize;
    106 typedef float cgltf_float;
    107 typedef int cgltf_int;
    108 typedef unsigned int cgltf_uint;
    109 typedef int cgltf_bool;
    110 
    111 typedef enum cgltf_file_type
    112 {
    113 	cgltf_file_type_invalid,
    114 	cgltf_file_type_gltf,
    115 	cgltf_file_type_glb,
    116 	cgltf_file_type_max_enum
    117 } cgltf_file_type;
    118 
    119 typedef enum cgltf_result
    120 {
    121 	cgltf_result_success,
    122 	cgltf_result_data_too_short,
    123 	cgltf_result_unknown_format,
    124 	cgltf_result_invalid_json,
    125 	cgltf_result_invalid_gltf,
    126 	cgltf_result_invalid_options,
    127 	cgltf_result_file_not_found,
    128 	cgltf_result_io_error,
    129 	cgltf_result_out_of_memory,
    130 	cgltf_result_legacy_gltf,
    131     cgltf_result_max_enum
    132 } cgltf_result;
    133 
    134 typedef struct cgltf_memory_options
    135 {
    136 	void* (*alloc_func)(void* user, cgltf_size size);
    137 	void (*free_func) (void* user, void* ptr);
    138 	void* user_data;
    139 } cgltf_memory_options;
    140 
    141 typedef struct cgltf_file_options
    142 {
    143 	cgltf_result(*read)(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, const char* path, cgltf_size* size, void** data);
    144 	void (*release)(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, void* data);
    145 	void* user_data;
    146 } cgltf_file_options;
    147 
    148 typedef struct cgltf_options
    149 {
    150 	cgltf_file_type type; /* invalid == auto detect */
    151 	cgltf_size json_token_count; /* 0 == auto */
    152 	cgltf_memory_options memory;
    153 	cgltf_file_options file;
    154 } cgltf_options;
    155 
    156 typedef enum cgltf_buffer_view_type
    157 {
    158 	cgltf_buffer_view_type_invalid,
    159 	cgltf_buffer_view_type_indices,
    160 	cgltf_buffer_view_type_vertices,
    161 	cgltf_buffer_view_type_max_enum
    162 } cgltf_buffer_view_type;
    163 
    164 typedef enum cgltf_attribute_type
    165 {
    166 	cgltf_attribute_type_invalid,
    167 	cgltf_attribute_type_position,
    168 	cgltf_attribute_type_normal,
    169 	cgltf_attribute_type_tangent,
    170 	cgltf_attribute_type_texcoord,
    171 	cgltf_attribute_type_color,
    172 	cgltf_attribute_type_joints,
    173 	cgltf_attribute_type_weights,
    174 	cgltf_attribute_type_custom,
    175 	cgltf_attribute_type_max_enum
    176 } cgltf_attribute_type;
    177 
    178 typedef enum cgltf_component_type
    179 {
    180 	cgltf_component_type_invalid,
    181 	cgltf_component_type_r_8, /* BYTE */
    182 	cgltf_component_type_r_8u, /* UNSIGNED_BYTE */
    183 	cgltf_component_type_r_16, /* SHORT */
    184 	cgltf_component_type_r_16u, /* UNSIGNED_SHORT */
    185 	cgltf_component_type_r_32u, /* UNSIGNED_INT */
    186 	cgltf_component_type_r_32f, /* FLOAT */
    187     cgltf_component_type_max_enum
    188 } cgltf_component_type;
    189 
    190 typedef enum cgltf_type
    191 {
    192 	cgltf_type_invalid,
    193 	cgltf_type_scalar,
    194 	cgltf_type_vec2,
    195 	cgltf_type_vec3,
    196 	cgltf_type_vec4,
    197 	cgltf_type_mat2,
    198 	cgltf_type_mat3,
    199 	cgltf_type_mat4,
    200 	cgltf_type_max_enum
    201 } cgltf_type;
    202 
    203 typedef enum cgltf_primitive_type
    204 {
    205 	cgltf_primitive_type_invalid,
    206 	cgltf_primitive_type_points,
    207 	cgltf_primitive_type_lines,
    208 	cgltf_primitive_type_line_loop,
    209 	cgltf_primitive_type_line_strip,
    210 	cgltf_primitive_type_triangles,
    211 	cgltf_primitive_type_triangle_strip,
    212 	cgltf_primitive_type_triangle_fan,
    213 	cgltf_primitive_type_max_enum
    214 } cgltf_primitive_type;
    215 
    216 typedef enum cgltf_alpha_mode
    217 {
    218 	cgltf_alpha_mode_opaque,
    219 	cgltf_alpha_mode_mask,
    220 	cgltf_alpha_mode_blend,
    221 	cgltf_alpha_mode_max_enum
    222 } cgltf_alpha_mode;
    223 
    224 typedef enum cgltf_animation_path_type {
    225 	cgltf_animation_path_type_invalid,
    226 	cgltf_animation_path_type_translation,
    227 	cgltf_animation_path_type_rotation,
    228 	cgltf_animation_path_type_scale,
    229 	cgltf_animation_path_type_weights,
    230 	cgltf_animation_path_type_max_enum
    231 } cgltf_animation_path_type;
    232 
    233 typedef enum cgltf_interpolation_type {
    234 	cgltf_interpolation_type_linear,
    235 	cgltf_interpolation_type_step,
    236 	cgltf_interpolation_type_cubic_spline,
    237 	cgltf_interpolation_type_max_enum
    238 } cgltf_interpolation_type;
    239 
    240 typedef enum cgltf_camera_type {
    241 	cgltf_camera_type_invalid,
    242 	cgltf_camera_type_perspective,
    243 	cgltf_camera_type_orthographic,
    244 	cgltf_camera_type_max_enum
    245 } cgltf_camera_type;
    246 
    247 typedef enum cgltf_light_type {
    248 	cgltf_light_type_invalid,
    249 	cgltf_light_type_directional,
    250 	cgltf_light_type_point,
    251 	cgltf_light_type_spot,
    252 	cgltf_light_type_max_enum
    253 } cgltf_light_type;
    254 
    255 typedef enum cgltf_data_free_method {
    256 	cgltf_data_free_method_none,
    257 	cgltf_data_free_method_file_release,
    258 	cgltf_data_free_method_memory_free,
    259 	cgltf_data_free_method_max_enum
    260 } cgltf_data_free_method;
    261 
    262 typedef struct cgltf_extras {
    263 	cgltf_size start_offset; /* this field is deprecated and will be removed in the future; use data instead */
    264 	cgltf_size end_offset; /* this field is deprecated and will be removed in the future; use data instead */
    265 
    266 	char* data;
    267 } cgltf_extras;
    268 
    269 typedef struct cgltf_extension {
    270 	char* name;
    271 	char* data;
    272 } cgltf_extension;
    273 
    274 typedef struct cgltf_buffer
    275 {
    276 	char* name;
    277 	cgltf_size size;
    278 	char* uri;
    279 	void* data; /* loaded by cgltf_load_buffers */
    280 	cgltf_data_free_method data_free_method;
    281 	cgltf_extras extras;
    282 	cgltf_size extensions_count;
    283 	cgltf_extension* extensions;
    284 } cgltf_buffer;
    285 
    286 typedef enum cgltf_meshopt_compression_mode {
    287 	cgltf_meshopt_compression_mode_invalid,
    288 	cgltf_meshopt_compression_mode_attributes,
    289 	cgltf_meshopt_compression_mode_triangles,
    290 	cgltf_meshopt_compression_mode_indices,
    291 	cgltf_meshopt_compression_mode_max_enum
    292 } cgltf_meshopt_compression_mode;
    293 
    294 typedef enum cgltf_meshopt_compression_filter {
    295 	cgltf_meshopt_compression_filter_none,
    296 	cgltf_meshopt_compression_filter_octahedral,
    297 	cgltf_meshopt_compression_filter_quaternion,
    298 	cgltf_meshopt_compression_filter_exponential,
    299 	cgltf_meshopt_compression_filter_max_enum
    300 } cgltf_meshopt_compression_filter;
    301 
    302 typedef struct cgltf_meshopt_compression
    303 {
    304 	cgltf_buffer* buffer;
    305 	cgltf_size offset;
    306 	cgltf_size size;
    307 	cgltf_size stride;
    308 	cgltf_size count;
    309 	cgltf_meshopt_compression_mode mode;
    310 	cgltf_meshopt_compression_filter filter;
    311 } cgltf_meshopt_compression;
    312 
    313 typedef struct cgltf_buffer_view
    314 {
    315 	char *name;
    316 	cgltf_buffer* buffer;
    317 	cgltf_size offset;
    318 	cgltf_size size;
    319 	cgltf_size stride; /* 0 == automatically determined by accessor */
    320 	cgltf_buffer_view_type type;
    321 	void* data; /* overrides buffer->data if present, filled by extensions */
    322 	cgltf_bool has_meshopt_compression;
    323 	cgltf_meshopt_compression meshopt_compression;
    324 	cgltf_extras extras;
    325 	cgltf_size extensions_count;
    326 	cgltf_extension* extensions;
    327 } cgltf_buffer_view;
    328 
    329 typedef struct cgltf_accessor_sparse
    330 {
    331 	cgltf_size count;
    332 	cgltf_buffer_view* indices_buffer_view;
    333 	cgltf_size indices_byte_offset;
    334 	cgltf_component_type indices_component_type;
    335 	cgltf_buffer_view* values_buffer_view;
    336 	cgltf_size values_byte_offset;
    337 } cgltf_accessor_sparse;
    338 
    339 typedef struct cgltf_accessor
    340 {
    341 	char* name;
    342 	cgltf_component_type component_type;
    343 	cgltf_bool normalized;
    344 	cgltf_type type;
    345 	cgltf_size offset;
    346 	cgltf_size count;
    347 	cgltf_size stride;
    348 	cgltf_buffer_view* buffer_view;
    349 	cgltf_bool has_min;
    350 	cgltf_float min[16];
    351 	cgltf_bool has_max;
    352 	cgltf_float max[16];
    353 	cgltf_bool is_sparse;
    354 	cgltf_accessor_sparse sparse;
    355 	cgltf_extras extras;
    356 	cgltf_size extensions_count;
    357 	cgltf_extension* extensions;
    358 } cgltf_accessor;
    359 
    360 typedef struct cgltf_attribute
    361 {
    362 	char* name;
    363 	cgltf_attribute_type type;
    364 	cgltf_int index;
    365 	cgltf_accessor* data;
    366 } cgltf_attribute;
    367 
    368 typedef struct cgltf_image
    369 {
    370 	char* name;
    371 	char* uri;
    372 	cgltf_buffer_view* buffer_view;
    373 	char* mime_type;
    374 	cgltf_extras extras;
    375 	cgltf_size extensions_count;
    376 	cgltf_extension* extensions;
    377 } cgltf_image;
    378 
    379 typedef struct cgltf_sampler
    380 {
    381 	char* name;
    382 	cgltf_int mag_filter;
    383 	cgltf_int min_filter;
    384 	cgltf_int wrap_s;
    385 	cgltf_int wrap_t;
    386 	cgltf_extras extras;
    387 	cgltf_size extensions_count;
    388 	cgltf_extension* extensions;
    389 } cgltf_sampler;
    390 
    391 typedef struct cgltf_texture
    392 {
    393 	char* name;
    394 	cgltf_image* image;
    395 	cgltf_sampler* sampler;
    396 	cgltf_bool has_basisu;
    397 	cgltf_image* basisu_image;
    398 	cgltf_bool has_webp;
    399 	cgltf_image* webp_image;
    400 	cgltf_extras extras;
    401 	cgltf_size extensions_count;
    402 	cgltf_extension* extensions;
    403 } cgltf_texture;
    404 
    405 typedef struct cgltf_texture_transform
    406 {
    407 	cgltf_float offset[2];
    408 	cgltf_float rotation;
    409 	cgltf_float scale[2];
    410 	cgltf_bool has_texcoord;
    411 	cgltf_int texcoord;
    412 } cgltf_texture_transform;
    413 
    414 typedef struct cgltf_texture_view
    415 {
    416 	cgltf_texture* texture;
    417 	cgltf_int texcoord;
    418 	cgltf_float scale; /* equivalent to strength for occlusion_texture */
    419 	cgltf_bool has_transform;
    420 	cgltf_texture_transform transform;
    421 } cgltf_texture_view;
    422 
    423 typedef struct cgltf_pbr_metallic_roughness
    424 {
    425 	cgltf_texture_view base_color_texture;
    426 	cgltf_texture_view metallic_roughness_texture;
    427 
    428 	cgltf_float base_color_factor[4];
    429 	cgltf_float metallic_factor;
    430 	cgltf_float roughness_factor;
    431 } cgltf_pbr_metallic_roughness;
    432 
    433 typedef struct cgltf_pbr_specular_glossiness
    434 {
    435 	cgltf_texture_view diffuse_texture;
    436 	cgltf_texture_view specular_glossiness_texture;
    437 
    438 	cgltf_float diffuse_factor[4];
    439 	cgltf_float specular_factor[3];
    440 	cgltf_float glossiness_factor;
    441 } cgltf_pbr_specular_glossiness;
    442 
    443 typedef struct cgltf_clearcoat
    444 {
    445 	cgltf_texture_view clearcoat_texture;
    446 	cgltf_texture_view clearcoat_roughness_texture;
    447 	cgltf_texture_view clearcoat_normal_texture;
    448 
    449 	cgltf_float clearcoat_factor;
    450 	cgltf_float clearcoat_roughness_factor;
    451 } cgltf_clearcoat;
    452 
    453 typedef struct cgltf_transmission
    454 {
    455 	cgltf_texture_view transmission_texture;
    456 	cgltf_float transmission_factor;
    457 } cgltf_transmission;
    458 
    459 typedef struct cgltf_ior
    460 {
    461 	cgltf_float ior;
    462 } cgltf_ior;
    463 
    464 typedef struct cgltf_specular
    465 {
    466 	cgltf_texture_view specular_texture;
    467 	cgltf_texture_view specular_color_texture;
    468 	cgltf_float specular_color_factor[3];
    469 	cgltf_float specular_factor;
    470 } cgltf_specular;
    471 
    472 typedef struct cgltf_volume
    473 {
    474 	cgltf_texture_view thickness_texture;
    475 	cgltf_float thickness_factor;
    476 	cgltf_float attenuation_color[3];
    477 	cgltf_float attenuation_distance;
    478 } cgltf_volume;
    479 
    480 typedef struct cgltf_sheen
    481 {
    482 	cgltf_texture_view sheen_color_texture;
    483 	cgltf_float sheen_color_factor[3];
    484 	cgltf_texture_view sheen_roughness_texture;
    485 	cgltf_float sheen_roughness_factor;
    486 } cgltf_sheen;
    487 
    488 typedef struct cgltf_emissive_strength
    489 {
    490 	cgltf_float emissive_strength;
    491 } cgltf_emissive_strength;
    492 
    493 typedef struct cgltf_iridescence
    494 {
    495 	cgltf_float iridescence_factor;
    496 	cgltf_texture_view iridescence_texture;
    497 	cgltf_float iridescence_ior;
    498 	cgltf_float iridescence_thickness_min;
    499 	cgltf_float iridescence_thickness_max;
    500 	cgltf_texture_view iridescence_thickness_texture;
    501 } cgltf_iridescence;
    502 
    503 typedef struct cgltf_anisotropy
    504 {
    505 	cgltf_float anisotropy_strength;
    506 	cgltf_float anisotropy_rotation;
    507 	cgltf_texture_view anisotropy_texture;
    508 } cgltf_anisotropy;
    509 
    510 typedef struct cgltf_dispersion
    511 {
    512 	cgltf_float dispersion;
    513 } cgltf_dispersion;
    514 
    515 typedef struct cgltf_material
    516 {
    517 	char* name;
    518 	cgltf_bool has_pbr_metallic_roughness;
    519 	cgltf_bool has_pbr_specular_glossiness;
    520 	cgltf_bool has_clearcoat;
    521 	cgltf_bool has_transmission;
    522 	cgltf_bool has_volume;
    523 	cgltf_bool has_ior;
    524 	cgltf_bool has_specular;
    525 	cgltf_bool has_sheen;
    526 	cgltf_bool has_emissive_strength;
    527 	cgltf_bool has_iridescence;
    528 	cgltf_bool has_anisotropy;
    529 	cgltf_bool has_dispersion;
    530 	cgltf_pbr_metallic_roughness pbr_metallic_roughness;
    531 	cgltf_pbr_specular_glossiness pbr_specular_glossiness;
    532 	cgltf_clearcoat clearcoat;
    533 	cgltf_ior ior;
    534 	cgltf_specular specular;
    535 	cgltf_sheen sheen;
    536 	cgltf_transmission transmission;
    537 	cgltf_volume volume;
    538 	cgltf_emissive_strength emissive_strength;
    539 	cgltf_iridescence iridescence;
    540 	cgltf_anisotropy anisotropy;
    541 	cgltf_dispersion dispersion;
    542 	cgltf_texture_view normal_texture;
    543 	cgltf_texture_view occlusion_texture;
    544 	cgltf_texture_view emissive_texture;
    545 	cgltf_float emissive_factor[3];
    546 	cgltf_alpha_mode alpha_mode;
    547 	cgltf_float alpha_cutoff;
    548 	cgltf_bool double_sided;
    549 	cgltf_bool unlit;
    550 	cgltf_extras extras;
    551 	cgltf_size extensions_count;
    552 	cgltf_extension* extensions;
    553 } cgltf_material;
    554 
    555 typedef struct cgltf_material_mapping
    556 {
    557 	cgltf_size variant;
    558 	cgltf_material* material;
    559 	cgltf_extras extras;
    560 } cgltf_material_mapping;
    561 
    562 typedef struct cgltf_morph_target {
    563 	cgltf_attribute* attributes;
    564 	cgltf_size attributes_count;
    565 } cgltf_morph_target;
    566 
    567 typedef struct cgltf_draco_mesh_compression {
    568 	cgltf_buffer_view* buffer_view;
    569 	cgltf_attribute* attributes;
    570 	cgltf_size attributes_count;
    571 } cgltf_draco_mesh_compression;
    572 
    573 typedef struct cgltf_mesh_gpu_instancing {
    574 	cgltf_attribute* attributes;
    575 	cgltf_size attributes_count;
    576 } cgltf_mesh_gpu_instancing;
    577 
    578 typedef struct cgltf_primitive {
    579 	cgltf_primitive_type type;
    580 	cgltf_accessor* indices;
    581 	cgltf_material* material;
    582 	cgltf_attribute* attributes;
    583 	cgltf_size attributes_count;
    584 	cgltf_morph_target* targets;
    585 	cgltf_size targets_count;
    586 	cgltf_extras extras;
    587 	cgltf_bool has_draco_mesh_compression;
    588 	cgltf_draco_mesh_compression draco_mesh_compression;
    589 	cgltf_material_mapping* mappings;
    590 	cgltf_size mappings_count;
    591 	cgltf_size extensions_count;
    592 	cgltf_extension* extensions;
    593 } cgltf_primitive;
    594 
    595 typedef struct cgltf_mesh {
    596 	char* name;
    597 	cgltf_primitive* primitives;
    598 	cgltf_size primitives_count;
    599 	cgltf_float* weights;
    600 	cgltf_size weights_count;
    601 	char** target_names;
    602 	cgltf_size target_names_count;
    603 	cgltf_extras extras;
    604 	cgltf_size extensions_count;
    605 	cgltf_extension* extensions;
    606 } cgltf_mesh;
    607 
    608 typedef struct cgltf_node cgltf_node;
    609 
    610 typedef struct cgltf_skin {
    611 	char* name;
    612 	cgltf_node** joints;
    613 	cgltf_size joints_count;
    614 	cgltf_node* skeleton;
    615 	cgltf_accessor* inverse_bind_matrices;
    616 	cgltf_extras extras;
    617 	cgltf_size extensions_count;
    618 	cgltf_extension* extensions;
    619 } cgltf_skin;
    620 
    621 typedef struct cgltf_camera_perspective {
    622 	cgltf_bool has_aspect_ratio;
    623 	cgltf_float aspect_ratio;
    624 	cgltf_float yfov;
    625 	cgltf_bool has_zfar;
    626 	cgltf_float zfar;
    627 	cgltf_float znear;
    628 	cgltf_extras extras;
    629 } cgltf_camera_perspective;
    630 
    631 typedef struct cgltf_camera_orthographic {
    632 	cgltf_float xmag;
    633 	cgltf_float ymag;
    634 	cgltf_float zfar;
    635 	cgltf_float znear;
    636 	cgltf_extras extras;
    637 } cgltf_camera_orthographic;
    638 
    639 typedef struct cgltf_camera {
    640 	char* name;
    641 	cgltf_camera_type type;
    642 	union {
    643 		cgltf_camera_perspective perspective;
    644 		cgltf_camera_orthographic orthographic;
    645 	} data;
    646 	cgltf_extras extras;
    647 	cgltf_size extensions_count;
    648 	cgltf_extension* extensions;
    649 } cgltf_camera;
    650 
    651 typedef struct cgltf_light {
    652 	char* name;
    653 	cgltf_float color[3];
    654 	cgltf_float intensity;
    655 	cgltf_light_type type;
    656 	cgltf_float range;
    657 	cgltf_float spot_inner_cone_angle;
    658 	cgltf_float spot_outer_cone_angle;
    659 	cgltf_extras extras;
    660 } cgltf_light;
    661 
    662 struct cgltf_node {
    663 	char* name;
    664 	cgltf_node* parent;
    665 	cgltf_node** children;
    666 	cgltf_size children_count;
    667 	cgltf_skin* skin;
    668 	cgltf_mesh* mesh;
    669 	cgltf_camera* camera;
    670 	cgltf_light* light;
    671 	cgltf_float* weights;
    672 	cgltf_size weights_count;
    673 	cgltf_bool has_translation;
    674 	cgltf_bool has_rotation;
    675 	cgltf_bool has_scale;
    676 	cgltf_bool has_matrix;
    677 	cgltf_float translation[3];
    678 	cgltf_float rotation[4];
    679 	cgltf_float scale[3];
    680 	cgltf_float matrix[16];
    681 	cgltf_extras extras;
    682 	cgltf_bool has_mesh_gpu_instancing;
    683 	cgltf_mesh_gpu_instancing mesh_gpu_instancing;
    684 	cgltf_size extensions_count;
    685 	cgltf_extension* extensions;
    686 };
    687 
    688 typedef struct cgltf_scene {
    689 	char* name;
    690 	cgltf_node** nodes;
    691 	cgltf_size nodes_count;
    692 	cgltf_extras extras;
    693 	cgltf_size extensions_count;
    694 	cgltf_extension* extensions;
    695 } cgltf_scene;
    696 
    697 typedef struct cgltf_animation_sampler {
    698 	cgltf_accessor* input;
    699 	cgltf_accessor* output;
    700 	cgltf_interpolation_type interpolation;
    701 	cgltf_extras extras;
    702 	cgltf_size extensions_count;
    703 	cgltf_extension* extensions;
    704 } cgltf_animation_sampler;
    705 
    706 typedef struct cgltf_animation_channel {
    707 	cgltf_animation_sampler* sampler;
    708 	cgltf_node* target_node;
    709 	cgltf_animation_path_type target_path;
    710 	cgltf_extras extras;
    711 	cgltf_size extensions_count;
    712 	cgltf_extension* extensions;
    713 } cgltf_animation_channel;
    714 
    715 typedef struct cgltf_animation {
    716 	char* name;
    717 	cgltf_animation_sampler* samplers;
    718 	cgltf_size samplers_count;
    719 	cgltf_animation_channel* channels;
    720 	cgltf_size channels_count;
    721 	cgltf_extras extras;
    722 	cgltf_size extensions_count;
    723 	cgltf_extension* extensions;
    724 } cgltf_animation;
    725 
    726 typedef struct cgltf_material_variant
    727 {
    728 	char* name;
    729 	cgltf_extras extras;
    730 } cgltf_material_variant;
    731 
    732 typedef struct cgltf_asset {
    733 	char* copyright;
    734 	char* generator;
    735 	char* version;
    736 	char* min_version;
    737 	cgltf_extras extras;
    738 	cgltf_size extensions_count;
    739 	cgltf_extension* extensions;
    740 } cgltf_asset;
    741 
    742 typedef struct cgltf_data
    743 {
    744 	cgltf_file_type file_type;
    745 	void* file_data;
    746 
    747 	cgltf_asset asset;
    748 
    749 	cgltf_mesh* meshes;
    750 	cgltf_size meshes_count;
    751 
    752 	cgltf_material* materials;
    753 	cgltf_size materials_count;
    754 
    755 	cgltf_accessor* accessors;
    756 	cgltf_size accessors_count;
    757 
    758 	cgltf_buffer_view* buffer_views;
    759 	cgltf_size buffer_views_count;
    760 
    761 	cgltf_buffer* buffers;
    762 	cgltf_size buffers_count;
    763 
    764 	cgltf_image* images;
    765 	cgltf_size images_count;
    766 
    767 	cgltf_texture* textures;
    768 	cgltf_size textures_count;
    769 
    770 	cgltf_sampler* samplers;
    771 	cgltf_size samplers_count;
    772 
    773 	cgltf_skin* skins;
    774 	cgltf_size skins_count;
    775 
    776 	cgltf_camera* cameras;
    777 	cgltf_size cameras_count;
    778 
    779 	cgltf_light* lights;
    780 	cgltf_size lights_count;
    781 
    782 	cgltf_node* nodes;
    783 	cgltf_size nodes_count;
    784 
    785 	cgltf_scene* scenes;
    786 	cgltf_size scenes_count;
    787 
    788 	cgltf_scene* scene;
    789 
    790 	cgltf_animation* animations;
    791 	cgltf_size animations_count;
    792 
    793 	cgltf_material_variant* variants;
    794 	cgltf_size variants_count;
    795 
    796 	cgltf_extras extras;
    797 
    798 	cgltf_size data_extensions_count;
    799 	cgltf_extension* data_extensions;
    800 
    801 	char** extensions_used;
    802 	cgltf_size extensions_used_count;
    803 
    804 	char** extensions_required;
    805 	cgltf_size extensions_required_count;
    806 
    807 	const char* json;
    808 	cgltf_size json_size;
    809 
    810 	const void* bin;
    811 	cgltf_size bin_size;
    812 
    813 	cgltf_memory_options memory;
    814 	cgltf_file_options file;
    815 } cgltf_data;
    816 
    817 cgltf_result cgltf_parse(
    818 		const cgltf_options* options,
    819 		const void* data,
    820 		cgltf_size size,
    821 		cgltf_data** out_data);
    822 
    823 cgltf_result cgltf_parse_file(
    824 		const cgltf_options* options,
    825 		const char* path,
    826 		cgltf_data** out_data);
    827 
    828 cgltf_result cgltf_load_buffers(
    829 		const cgltf_options* options,
    830 		cgltf_data* data,
    831 		const char* gltf_path);
    832 
    833 cgltf_result cgltf_load_buffer_base64(const cgltf_options* options, cgltf_size size, const char* base64, void** out_data);
    834 
    835 cgltf_size cgltf_decode_string(char* string);
    836 cgltf_size cgltf_decode_uri(char* uri);
    837 
    838 cgltf_result cgltf_validate(cgltf_data* data);
    839 
    840 void cgltf_free(cgltf_data* data);
    841 
    842 void cgltf_node_transform_local(const cgltf_node* node, cgltf_float* out_matrix);
    843 void cgltf_node_transform_world(const cgltf_node* node, cgltf_float* out_matrix);
    844 
    845 const uint8_t* cgltf_buffer_view_data(const cgltf_buffer_view* view);
    846 
    847 cgltf_bool cgltf_accessor_read_float(const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size);
    848 cgltf_bool cgltf_accessor_read_uint(const cgltf_accessor* accessor, cgltf_size index, cgltf_uint* out, cgltf_size element_size);
    849 cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size index);
    850 
    851 cgltf_size cgltf_num_components(cgltf_type type);
    852 cgltf_size cgltf_component_size(cgltf_component_type component_type);
    853 cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type);
    854 
    855 cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count);
    856 cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count);
    857 
    858 /* this function is deprecated and will be removed in the future; use cgltf_extras::data instead */
    859 cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* extras, char* dest, cgltf_size* dest_size);
    860 
    861 cgltf_size cgltf_mesh_index(const cgltf_data* data, const cgltf_mesh* object);
    862 cgltf_size cgltf_material_index(const cgltf_data* data, const cgltf_material* object);
    863 cgltf_size cgltf_accessor_index(const cgltf_data* data, const cgltf_accessor* object);
    864 cgltf_size cgltf_buffer_view_index(const cgltf_data* data, const cgltf_buffer_view* object);
    865 cgltf_size cgltf_buffer_index(const cgltf_data* data, const cgltf_buffer* object);
    866 cgltf_size cgltf_image_index(const cgltf_data* data, const cgltf_image* object);
    867 cgltf_size cgltf_texture_index(const cgltf_data* data, const cgltf_texture* object);
    868 cgltf_size cgltf_sampler_index(const cgltf_data* data, const cgltf_sampler* object);
    869 cgltf_size cgltf_skin_index(const cgltf_data* data, const cgltf_skin* object);
    870 cgltf_size cgltf_camera_index(const cgltf_data* data, const cgltf_camera* object);
    871 cgltf_size cgltf_light_index(const cgltf_data* data, const cgltf_light* object);
    872 cgltf_size cgltf_node_index(const cgltf_data* data, const cgltf_node* object);
    873 cgltf_size cgltf_scene_index(const cgltf_data* data, const cgltf_scene* object);
    874 cgltf_size cgltf_animation_index(const cgltf_data* data, const cgltf_animation* object);
    875 cgltf_size cgltf_animation_sampler_index(const cgltf_animation* animation, const cgltf_animation_sampler* object);
    876 cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const cgltf_animation_channel* object);
    877 
    878 #ifdef __cplusplus
    879 }
    880 #endif
    881 
    882 #endif /* #ifndef CGLTF_H_INCLUDED__ */
    883 
    884 /*
    885  *
    886  * Stop now, if you are only interested in the API.
    887  * Below, you find the implementation.
    888  *
    889  */
    890 
    891 #if defined(__INTELLISENSE__) || defined(__JETBRAINS_IDE__)
    892 /* This makes MSVC/CLion intellisense work. */
    893 #define CGLTF_IMPLEMENTATION
    894 #endif
    895 
    896 #ifdef CGLTF_IMPLEMENTATION
    897 
    898 #include <assert.h> /* For assert */
    899 #include <string.h> /* For strncpy */
    900 #include <stdio.h>  /* For fopen */
    901 #include <limits.h> /* For UINT_MAX etc */
    902 #include <float.h>  /* For FLT_MAX */
    903 
    904 #if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF) || !defined(CGLTF_ATOLL)
    905 #include <stdlib.h> /* For malloc, free, atoi, atof */
    906 #endif
    907 
    908 /* JSMN_PARENT_LINKS is necessary to make parsing large structures linear in input size */
    909 #define JSMN_PARENT_LINKS
    910 
    911 /* JSMN_STRICT is necessary to reject invalid JSON documents */
    912 #define JSMN_STRICT
    913 
    914 /*
    915  * -- jsmn.h start --
    916  * Source: https://github.com/zserge/jsmn
    917  * License: MIT
    918  */
    919 typedef enum {
    920 	JSMN_UNDEFINED = 0,
    921 	JSMN_OBJECT = 1,
    922 	JSMN_ARRAY = 2,
    923 	JSMN_STRING = 3,
    924 	JSMN_PRIMITIVE = 4
    925 } jsmntype_t;
    926 enum jsmnerr {
    927 	/* Not enough tokens were provided */
    928 	JSMN_ERROR_NOMEM = -1,
    929 	/* Invalid character inside JSON string */
    930 	JSMN_ERROR_INVAL = -2,
    931 	/* The string is not a full JSON packet, more bytes expected */
    932 	JSMN_ERROR_PART = -3
    933 };
    934 typedef struct {
    935 	jsmntype_t type;
    936 	ptrdiff_t start;
    937 	ptrdiff_t end;
    938 	int size;
    939 #ifdef JSMN_PARENT_LINKS
    940 	int parent;
    941 #endif
    942 } jsmntok_t;
    943 typedef struct {
    944 	size_t pos; /* offset in the JSON string */
    945 	unsigned int toknext; /* next token to allocate */
    946 	int toksuper; /* superior token node, e.g parent object or array */
    947 } jsmn_parser;
    948 static void jsmn_init(jsmn_parser *parser);
    949 static int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, jsmntok_t *tokens, size_t num_tokens);
    950 /*
    951  * -- jsmn.h end --
    952  */
    953 
    954 
    955 #ifndef CGLTF_CONSTS
    956 #define GlbHeaderSize 12
    957 #define GlbChunkHeaderSize 8
    958 static const uint32_t GlbVersion = 2;
    959 static const uint32_t GlbMagic = 0x46546C67;
    960 static const uint32_t GlbMagicJsonChunk = 0x4E4F534A;
    961 static const uint32_t GlbMagicBinChunk = 0x004E4942;
    962 #define CGLTF_CONSTS
    963 #endif
    964 
    965 #ifndef CGLTF_MALLOC
    966 #define CGLTF_MALLOC(size) malloc(size)
    967 #endif
    968 #ifndef CGLTF_FREE
    969 #define CGLTF_FREE(ptr) free(ptr)
    970 #endif
    971 #ifndef CGLTF_ATOI
    972 #define CGLTF_ATOI(str) atoi(str)
    973 #endif
    974 #ifndef CGLTF_ATOF
    975 #define CGLTF_ATOF(str) atof(str)
    976 #endif
    977 #ifndef CGLTF_ATOLL
    978 #define CGLTF_ATOLL(str) atoll(str)
    979 #endif
    980 #ifndef CGLTF_VALIDATE_ENABLE_ASSERTS
    981 #define CGLTF_VALIDATE_ENABLE_ASSERTS 0
    982 #endif
    983 
    984 static void* cgltf_default_alloc(void* user, cgltf_size size)
    985 {
    986 	(void)user;
    987 	return CGLTF_MALLOC(size);
    988 }
    989 
    990 static void cgltf_default_free(void* user, void* ptr)
    991 {
    992 	(void)user;
    993 	CGLTF_FREE(ptr);
    994 }
    995 
    996 static void* cgltf_calloc(cgltf_options* options, size_t element_size, cgltf_size count)
    997 {
    998 	if (SIZE_MAX / element_size < count)
    999 	{
   1000 		return NULL;
   1001 	}
   1002 	void* result = options->memory.alloc_func(options->memory.user_data, element_size * count);
   1003 	if (!result)
   1004 	{
   1005 		return NULL;
   1006 	}
   1007 	memset(result, 0, element_size * count);
   1008 	return result;
   1009 }
   1010 
   1011 static 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)
   1012 {
   1013 	(void)file_options;
   1014 	void* (*memory_alloc)(void*, cgltf_size) = memory_options->alloc_func ? memory_options->alloc_func : &cgltf_default_alloc;
   1015 	void (*memory_free)(void*, void*) = memory_options->free_func ? memory_options->free_func : &cgltf_default_free;
   1016 
   1017 	FILE* file = fopen(path, "rb");
   1018 	if (!file)
   1019 	{
   1020 		return cgltf_result_file_not_found;
   1021 	}
   1022 
   1023 	cgltf_size file_size = size ? *size : 0;
   1024 
   1025 	if (file_size == 0)
   1026 	{
   1027 		fseek(file, 0, SEEK_END);
   1028 
   1029 #ifdef _MSC_VER
   1030 		__int64 length = _ftelli64(file);
   1031 #else
   1032 		long length = ftell(file);
   1033 #endif
   1034 
   1035 		if (length < 0)
   1036 		{
   1037 			fclose(file);
   1038 			return cgltf_result_io_error;
   1039 		}
   1040 
   1041 		fseek(file, 0, SEEK_SET);
   1042 		file_size = (cgltf_size)length;
   1043 	}
   1044 
   1045 	char* file_data = (char*)memory_alloc(memory_options->user_data, file_size);
   1046 	if (!file_data)
   1047 	{
   1048 		fclose(file);
   1049 		return cgltf_result_out_of_memory;
   1050 	}
   1051 
   1052 	cgltf_size read_size = fread(file_data, 1, file_size, file);
   1053 
   1054 	fclose(file);
   1055 
   1056 	if (read_size != file_size)
   1057 	{
   1058 		memory_free(memory_options->user_data, file_data);
   1059 		return cgltf_result_io_error;
   1060 	}
   1061 
   1062 	if (size)
   1063 	{
   1064 		*size = file_size;
   1065 	}
   1066 	if (data)
   1067 	{
   1068 		*data = file_data;
   1069 	}
   1070 
   1071 	return cgltf_result_success;
   1072 }
   1073 
   1074 static void cgltf_default_file_release(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, void* data)
   1075 {
   1076 	(void)file_options;
   1077 	void (*memfree)(void*, void*) = memory_options->free_func ? memory_options->free_func : &cgltf_default_free;
   1078 	memfree(memory_options->user_data, data);
   1079 }
   1080 
   1081 static cgltf_result cgltf_parse_json(cgltf_options* options, const uint8_t* json_chunk, cgltf_size size, cgltf_data** out_data);
   1082 
   1083 cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_size size, cgltf_data** out_data)
   1084 {
   1085 	if (size < GlbHeaderSize)
   1086 	{
   1087 		return cgltf_result_data_too_short;
   1088 	}
   1089 
   1090 	if (options == NULL)
   1091 	{
   1092 		return cgltf_result_invalid_options;
   1093 	}
   1094 
   1095 	cgltf_options fixed_options = *options;
   1096 	if (fixed_options.memory.alloc_func == NULL)
   1097 	{
   1098 		fixed_options.memory.alloc_func = &cgltf_default_alloc;
   1099 	}
   1100 	if (fixed_options.memory.free_func == NULL)
   1101 	{
   1102 		fixed_options.memory.free_func = &cgltf_default_free;
   1103 	}
   1104 
   1105 	uint32_t tmp;
   1106 	// Magic
   1107 	memcpy(&tmp, data, 4);
   1108 	if (tmp != GlbMagic)
   1109 	{
   1110 		if (fixed_options.type == cgltf_file_type_invalid)
   1111 		{
   1112 			fixed_options.type = cgltf_file_type_gltf;
   1113 		}
   1114 		else if (fixed_options.type == cgltf_file_type_glb)
   1115 		{
   1116 			return cgltf_result_unknown_format;
   1117 		}
   1118 	}
   1119 
   1120 	if (fixed_options.type == cgltf_file_type_gltf)
   1121 	{
   1122 		cgltf_result json_result = cgltf_parse_json(&fixed_options, (const uint8_t*)data, size, out_data);
   1123 		if (json_result != cgltf_result_success)
   1124 		{
   1125 			return json_result;
   1126 		}
   1127 
   1128 		(*out_data)->file_type = cgltf_file_type_gltf;
   1129 
   1130 		return cgltf_result_success;
   1131 	}
   1132 
   1133 	const uint8_t* ptr = (const uint8_t*)data;
   1134 	// Version
   1135 	memcpy(&tmp, ptr + 4, 4);
   1136 	uint32_t version = tmp;
   1137 	if (version != GlbVersion)
   1138 	{
   1139 		return version < GlbVersion ? cgltf_result_legacy_gltf : cgltf_result_unknown_format;
   1140 	}
   1141 
   1142 	// Total length
   1143 	memcpy(&tmp, ptr + 8, 4);
   1144 	if (tmp > size)
   1145 	{
   1146 		return cgltf_result_data_too_short;
   1147 	}
   1148 
   1149 	const uint8_t* json_chunk = ptr + GlbHeaderSize;
   1150 
   1151 	if (GlbHeaderSize + GlbChunkHeaderSize > size)
   1152 	{
   1153 		return cgltf_result_data_too_short;
   1154 	}
   1155 
   1156 	// JSON chunk: length
   1157 	uint32_t json_length;
   1158 	memcpy(&json_length, json_chunk, 4);
   1159 	if (json_length > size - GlbHeaderSize - GlbChunkHeaderSize)
   1160 	{
   1161 		return cgltf_result_data_too_short;
   1162 	}
   1163 
   1164 	// JSON chunk: magic
   1165 	memcpy(&tmp, json_chunk + 4, 4);
   1166 	if (tmp != GlbMagicJsonChunk)
   1167 	{
   1168 		return cgltf_result_unknown_format;
   1169 	}
   1170 
   1171 	json_chunk += GlbChunkHeaderSize;
   1172 
   1173 	const void* bin = NULL;
   1174 	cgltf_size bin_size = 0;
   1175 
   1176 	if (GlbChunkHeaderSize <= size - GlbHeaderSize - GlbChunkHeaderSize - json_length)
   1177 	{
   1178 		// We can read another chunk
   1179 		const uint8_t* bin_chunk = json_chunk + json_length;
   1180 
   1181 		// Bin chunk: length
   1182 		uint32_t bin_length;
   1183 		memcpy(&bin_length, bin_chunk, 4);
   1184 		if (bin_length > size - GlbHeaderSize - GlbChunkHeaderSize - json_length - GlbChunkHeaderSize)
   1185 		{
   1186 			return cgltf_result_data_too_short;
   1187 		}
   1188 
   1189 		// Bin chunk: magic
   1190 		memcpy(&tmp, bin_chunk + 4, 4);
   1191 		if (tmp != GlbMagicBinChunk)
   1192 		{
   1193 			return cgltf_result_unknown_format;
   1194 		}
   1195 
   1196 		bin_chunk += GlbChunkHeaderSize;
   1197 
   1198 		bin = bin_chunk;
   1199 		bin_size = bin_length;
   1200 	}
   1201 
   1202 	cgltf_result json_result = cgltf_parse_json(&fixed_options, json_chunk, json_length, out_data);
   1203 	if (json_result != cgltf_result_success)
   1204 	{
   1205 		return json_result;
   1206 	}
   1207 
   1208 	(*out_data)->file_type = cgltf_file_type_glb;
   1209 	(*out_data)->bin = bin;
   1210 	(*out_data)->bin_size = bin_size;
   1211 
   1212 	return cgltf_result_success;
   1213 }
   1214 
   1215 cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cgltf_data** out_data)
   1216 {
   1217 	if (options == NULL)
   1218 	{
   1219 		return cgltf_result_invalid_options;
   1220 	}
   1221 
   1222 	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;
   1223 	void (*file_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data) = options->file.release ? options->file.release : cgltf_default_file_release;
   1224 
   1225 	void* file_data = NULL;
   1226 	cgltf_size file_size = 0;
   1227 	cgltf_result result = file_read(&options->memory, &options->file, path, &file_size, &file_data);
   1228 	if (result != cgltf_result_success)
   1229 	{
   1230 		return result;
   1231 	}
   1232 
   1233 	result = cgltf_parse(options, file_data, file_size, out_data);
   1234 
   1235 	if (result != cgltf_result_success)
   1236 	{
   1237 		file_release(&options->memory, &options->file, file_data);
   1238 		return result;
   1239 	}
   1240 
   1241 	(*out_data)->file_data = file_data;
   1242 
   1243 	return cgltf_result_success;
   1244 }
   1245 
   1246 static void cgltf_combine_paths(char* path, const char* base, const char* uri)
   1247 {
   1248 	const char* s0 = strrchr(base, '/');
   1249 	const char* s1 = strrchr(base, '\\');
   1250 	const char* slash = s0 ? (s1 && s1 > s0 ? s1 : s0) : s1;
   1251 
   1252 	if (slash)
   1253 	{
   1254 		size_t prefix = slash - base + 1;
   1255 
   1256 		strncpy(path, base, prefix);
   1257 		strcpy(path + prefix, uri);
   1258 	}
   1259 	else
   1260 	{
   1261 		strcpy(path, uri);
   1262 	}
   1263 }
   1264 
   1265 static cgltf_result cgltf_load_buffer_file(const cgltf_options* options, cgltf_size size, const char* uri, const char* gltf_path, void** out_data)
   1266 {
   1267 	void* (*memory_alloc)(void*, cgltf_size) = options->memory.alloc_func ? options->memory.alloc_func : &cgltf_default_alloc;
   1268 	void (*memory_free)(void*, void*) = options->memory.free_func ? options->memory.free_func : &cgltf_default_free;
   1269 	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;
   1270 
   1271 	char* path = (char*)memory_alloc(options->memory.user_data, strlen(uri) + strlen(gltf_path) + 1);
   1272 	if (!path)
   1273 	{
   1274 		return cgltf_result_out_of_memory;
   1275 	}
   1276 
   1277 	cgltf_combine_paths(path, gltf_path, uri);
   1278 
   1279 	// after combining, the tail of the resulting path is a uri; decode_uri converts it into path
   1280 	cgltf_decode_uri(path + strlen(path) - strlen(uri));
   1281 
   1282 	void* file_data = NULL;
   1283 	cgltf_result result = file_read(&options->memory, &options->file, path, &size, &file_data);
   1284 
   1285 	memory_free(options->memory.user_data, path);
   1286 
   1287 	*out_data = (result == cgltf_result_success) ? file_data : NULL;
   1288 
   1289 	return result;
   1290 }
   1291 
   1292 cgltf_result cgltf_load_buffer_base64(const cgltf_options* options, cgltf_size size, const char* base64, void** out_data)
   1293 {
   1294 	void* (*memory_alloc)(void*, cgltf_size) = options->memory.alloc_func ? options->memory.alloc_func : &cgltf_default_alloc;
   1295 	void (*memory_free)(void*, void*) = options->memory.free_func ? options->memory.free_func : &cgltf_default_free;
   1296 
   1297 	unsigned char* data = (unsigned char*)memory_alloc(options->memory.user_data, size);
   1298 	if (!data)
   1299 	{
   1300 		return cgltf_result_out_of_memory;
   1301 	}
   1302 
   1303 	unsigned int buffer = 0;
   1304 	unsigned int buffer_bits = 0;
   1305 
   1306 	for (cgltf_size i = 0; i < size; ++i)
   1307 	{
   1308 		while (buffer_bits < 8)
   1309 		{
   1310 			char ch = *base64++;
   1311 
   1312 			int index =
   1313 				(unsigned)(ch - 'A') < 26 ? (ch - 'A') :
   1314 				(unsigned)(ch - 'a') < 26 ? (ch - 'a') + 26 :
   1315 				(unsigned)(ch - '0') < 10 ? (ch - '0') + 52 :
   1316 				ch == '+' ? 62 :
   1317 				ch == '/' ? 63 :
   1318 				-1;
   1319 
   1320 			if (index < 0)
   1321 			{
   1322 				memory_free(options->memory.user_data, data);
   1323 				return cgltf_result_io_error;
   1324 			}
   1325 
   1326 			buffer = (buffer << 6) | index;
   1327 			buffer_bits += 6;
   1328 		}
   1329 
   1330 		data[i] = (unsigned char)(buffer >> (buffer_bits - 8));
   1331 		buffer_bits -= 8;
   1332 	}
   1333 
   1334 	*out_data = data;
   1335 
   1336 	return cgltf_result_success;
   1337 }
   1338 
   1339 static int cgltf_unhex(char ch)
   1340 {
   1341 	return
   1342 		(unsigned)(ch - '0') < 10 ? (ch - '0') :
   1343 		(unsigned)(ch - 'A') < 6 ? (ch - 'A') + 10 :
   1344 		(unsigned)(ch - 'a') < 6 ? (ch - 'a') + 10 :
   1345 		-1;
   1346 }
   1347 
   1348 cgltf_size cgltf_decode_string(char* string)
   1349 {
   1350 	char* read = string + strcspn(string, "\\");
   1351 	if (*read == 0)
   1352 	{
   1353 		return read - string;
   1354 	}
   1355 	char* write = string;
   1356 	char* last = string;
   1357 
   1358 	for (;;)
   1359 	{
   1360 		// Copy characters since last escaped sequence
   1361 		cgltf_size written = read - last;
   1362 		memmove(write, last, written);
   1363 		write += written;
   1364 
   1365 		if (*read++ == 0)
   1366 		{
   1367 			break;
   1368 		}
   1369 
   1370 		// jsmn already checked that all escape sequences are valid
   1371 		switch (*read++)
   1372 		{
   1373 		case '\"': *write++ = '\"'; break;
   1374 		case '/':  *write++ = '/';  break;
   1375 		case '\\': *write++ = '\\'; break;
   1376 		case 'b':  *write++ = '\b'; break;
   1377 		case 'f':  *write++ = '\f'; break;
   1378 		case 'r':  *write++ = '\r'; break;
   1379 		case 'n':  *write++ = '\n'; break;
   1380 		case 't':  *write++ = '\t'; break;
   1381 		case 'u':
   1382 		{
   1383 			// UCS-2 codepoint \uXXXX to UTF-8
   1384 			int character = 0;
   1385 			for (cgltf_size i = 0; i < 4; ++i)
   1386 			{
   1387 				character = (character << 4) + cgltf_unhex(*read++);
   1388 			}
   1389 
   1390 			if (character <= 0x7F)
   1391 			{
   1392 				*write++ = character & 0xFF;
   1393 			}
   1394 			else if (character <= 0x7FF)
   1395 			{
   1396 				*write++ = 0xC0 | ((character >> 6) & 0xFF);
   1397 				*write++ = 0x80 | (character & 0x3F);
   1398 			}
   1399 			else
   1400 			{
   1401 				*write++ = 0xE0 | ((character >> 12) & 0xFF);
   1402 				*write++ = 0x80 | ((character >> 6) & 0x3F);
   1403 				*write++ = 0x80 | (character & 0x3F);
   1404 			}
   1405 			break;
   1406 		}
   1407 		default:
   1408 			break;
   1409 		}
   1410 
   1411 		last = read;
   1412 		read += strcspn(read, "\\");
   1413 	}
   1414 
   1415 	*write = 0;
   1416 	return write - string;
   1417 }
   1418 
   1419 cgltf_size cgltf_decode_uri(char* uri)
   1420 {
   1421 	char* write = uri;
   1422 	char* i = uri;
   1423 
   1424 	while (*i)
   1425 	{
   1426 		if (*i == '%')
   1427 		{
   1428 			int ch1 = cgltf_unhex(i[1]);
   1429 
   1430 			if (ch1 >= 0)
   1431 			{
   1432 				int ch2 = cgltf_unhex(i[2]);
   1433 
   1434 				if (ch2 >= 0)
   1435 				{
   1436 					*write++ = (char)(ch1 * 16 + ch2);
   1437 					i += 3;
   1438 					continue;
   1439 				}
   1440 			}
   1441 		}
   1442 
   1443 		*write++ = *i++;
   1444 	}
   1445 
   1446 	*write = 0;
   1447 	return write - uri;
   1448 }
   1449 
   1450 cgltf_result cgltf_load_buffers(const cgltf_options* options, cgltf_data* data, const char* gltf_path)
   1451 {
   1452 	if (options == NULL)
   1453 	{
   1454 		return cgltf_result_invalid_options;
   1455 	}
   1456 
   1457 	if (data->buffers_count && data->buffers[0].data == NULL && data->buffers[0].uri == NULL && data->bin)
   1458 	{
   1459 		if (data->bin_size < data->buffers[0].size)
   1460 		{
   1461 			return cgltf_result_data_too_short;
   1462 		}
   1463 
   1464 		data->buffers[0].data = (void*)data->bin;
   1465 		data->buffers[0].data_free_method = cgltf_data_free_method_none;
   1466 	}
   1467 
   1468 	for (cgltf_size i = 0; i < data->buffers_count; ++i)
   1469 	{
   1470 		if (data->buffers[i].data)
   1471 		{
   1472 			continue;
   1473 		}
   1474 
   1475 		const char* uri = data->buffers[i].uri;
   1476 
   1477 		if (uri == NULL)
   1478 		{
   1479 			continue;
   1480 		}
   1481 
   1482 		if (strncmp(uri, "data:", 5) == 0)
   1483 		{
   1484 			const char* comma = strchr(uri, ',');
   1485 
   1486 			if (comma && comma - uri >= 7 && strncmp(comma - 7, ";base64", 7) == 0)
   1487 			{
   1488 				cgltf_result res = cgltf_load_buffer_base64(options, data->buffers[i].size, comma + 1, &data->buffers[i].data);
   1489 				data->buffers[i].data_free_method = cgltf_data_free_method_memory_free;
   1490 
   1491 				if (res != cgltf_result_success)
   1492 				{
   1493 					return res;
   1494 				}
   1495 			}
   1496 			else
   1497 			{
   1498 				return cgltf_result_unknown_format;
   1499 			}
   1500 		}
   1501 		else if (strstr(uri, "://") == NULL && gltf_path)
   1502 		{
   1503 			cgltf_result res = cgltf_load_buffer_file(options, data->buffers[i].size, uri, gltf_path, &data->buffers[i].data);
   1504 			data->buffers[i].data_free_method = cgltf_data_free_method_file_release;
   1505 
   1506 			if (res != cgltf_result_success)
   1507 			{
   1508 				return res;
   1509 			}
   1510 		}
   1511 		else
   1512 		{
   1513 			return cgltf_result_unknown_format;
   1514 		}
   1515 	}
   1516 
   1517 	return cgltf_result_success;
   1518 }
   1519 
   1520 static cgltf_size cgltf_calc_index_bound(cgltf_buffer_view* buffer_view, cgltf_size offset, cgltf_component_type component_type, cgltf_size count)
   1521 {
   1522 	char* data = (char*)buffer_view->buffer->data + offset + buffer_view->offset;
   1523 	cgltf_size bound = 0;
   1524 
   1525 	switch (component_type)
   1526 	{
   1527 	case cgltf_component_type_r_8u:
   1528 		for (size_t i = 0; i < count; ++i)
   1529 		{
   1530 			cgltf_size v = ((unsigned char*)data)[i];
   1531 			bound = bound > v ? bound : v;
   1532 		}
   1533 		break;
   1534 
   1535 	case cgltf_component_type_r_16u:
   1536 		for (size_t i = 0; i < count; ++i)
   1537 		{
   1538 			cgltf_size v = ((unsigned short*)data)[i];
   1539 			bound = bound > v ? bound : v;
   1540 		}
   1541 		break;
   1542 
   1543 	case cgltf_component_type_r_32u:
   1544 		for (size_t i = 0; i < count; ++i)
   1545 		{
   1546 			cgltf_size v = ((unsigned int*)data)[i];
   1547 			bound = bound > v ? bound : v;
   1548 		}
   1549 		break;
   1550 
   1551 	default:
   1552 		;
   1553 	}
   1554 
   1555 	return bound;
   1556 }
   1557 
   1558 #if CGLTF_VALIDATE_ENABLE_ASSERTS
   1559 #define CGLTF_ASSERT_IF(cond, result) assert(!(cond)); if (cond) return result;
   1560 #else
   1561 #define CGLTF_ASSERT_IF(cond, result) if (cond) return result;
   1562 #endif
   1563 
   1564 cgltf_result cgltf_validate(cgltf_data* data)
   1565 {
   1566 	for (cgltf_size i = 0; i < data->accessors_count; ++i)
   1567 	{
   1568 		cgltf_accessor* accessor = &data->accessors[i];
   1569 
   1570 		CGLTF_ASSERT_IF(data->accessors[i].component_type == cgltf_component_type_invalid, cgltf_result_invalid_gltf);
   1571 		CGLTF_ASSERT_IF(data->accessors[i].type == cgltf_type_invalid, cgltf_result_invalid_gltf);
   1572 
   1573 		cgltf_size element_size = cgltf_calc_size(accessor->type, accessor->component_type);
   1574 
   1575 		if (accessor->buffer_view)
   1576 		{
   1577 			cgltf_size req_size = accessor->offset + accessor->stride * (accessor->count - 1) + element_size;
   1578 
   1579 			CGLTF_ASSERT_IF(accessor->buffer_view->size < req_size, cgltf_result_data_too_short);
   1580 		}
   1581 
   1582 		if (accessor->is_sparse)
   1583 		{
   1584 			cgltf_accessor_sparse* sparse = &accessor->sparse;
   1585 
   1586 			cgltf_size indices_component_size = cgltf_component_size(sparse->indices_component_type);
   1587 			cgltf_size indices_req_size = sparse->indices_byte_offset + indices_component_size * sparse->count;
   1588 			cgltf_size values_req_size = sparse->values_byte_offset + element_size * sparse->count;
   1589 
   1590 			CGLTF_ASSERT_IF(sparse->indices_buffer_view->size < indices_req_size ||
   1591 							sparse->values_buffer_view->size < values_req_size, cgltf_result_data_too_short);
   1592 
   1593 			CGLTF_ASSERT_IF(sparse->indices_component_type != cgltf_component_type_r_8u &&
   1594 							sparse->indices_component_type != cgltf_component_type_r_16u &&
   1595 							sparse->indices_component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
   1596 
   1597 			if (sparse->indices_buffer_view->buffer->data)
   1598 			{
   1599 				cgltf_size index_bound = cgltf_calc_index_bound(sparse->indices_buffer_view, sparse->indices_byte_offset, sparse->indices_component_type, sparse->count);
   1600 
   1601 				CGLTF_ASSERT_IF(index_bound >= accessor->count, cgltf_result_data_too_short);
   1602 			}
   1603 		}
   1604 	}
   1605 
   1606 	for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
   1607 	{
   1608 		cgltf_size req_size = data->buffer_views[i].offset + data->buffer_views[i].size;
   1609 
   1610 		CGLTF_ASSERT_IF(data->buffer_views[i].buffer && data->buffer_views[i].buffer->size < req_size, cgltf_result_data_too_short);
   1611 
   1612 		if (data->buffer_views[i].has_meshopt_compression)
   1613 		{
   1614 			cgltf_meshopt_compression* mc = &data->buffer_views[i].meshopt_compression;
   1615 
   1616 			CGLTF_ASSERT_IF(mc->buffer == NULL || mc->buffer->size < mc->offset + mc->size, cgltf_result_data_too_short);
   1617 
   1618 			CGLTF_ASSERT_IF(data->buffer_views[i].stride && mc->stride != data->buffer_views[i].stride, cgltf_result_invalid_gltf);
   1619 
   1620 			CGLTF_ASSERT_IF(data->buffer_views[i].size != mc->stride * mc->count, cgltf_result_invalid_gltf);
   1621 
   1622 			CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_invalid, cgltf_result_invalid_gltf);
   1623 
   1624 			CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_attributes && !(mc->stride % 4 == 0 && mc->stride <= 256), cgltf_result_invalid_gltf);
   1625 
   1626 			CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_triangles && mc->count % 3 != 0, cgltf_result_invalid_gltf);
   1627 
   1628 			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);
   1629 
   1630 			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);
   1631 
   1632 			CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8, cgltf_result_invalid_gltf);
   1633 
   1634 			CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8, cgltf_result_invalid_gltf);
   1635 		}
   1636 	}
   1637 
   1638 	for (cgltf_size i = 0; i < data->meshes_count; ++i)
   1639 	{
   1640 		if (data->meshes[i].weights)
   1641 		{
   1642 			CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].weights_count, cgltf_result_invalid_gltf);
   1643 		}
   1644 
   1645 		if (data->meshes[i].target_names)
   1646 		{
   1647 			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);
   1648 		}
   1649 
   1650 		for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
   1651 		{
   1652 			CGLTF_ASSERT_IF(data->meshes[i].primitives[j].type == cgltf_primitive_type_invalid, cgltf_result_invalid_gltf);
   1653 			CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count, cgltf_result_invalid_gltf);
   1654 
   1655 			CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes_count == 0, cgltf_result_invalid_gltf);
   1656 
   1657 			cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data;
   1658 
   1659 			CGLTF_ASSERT_IF(first->count == 0, cgltf_result_invalid_gltf);
   1660 
   1661 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
   1662 			{
   1663 				CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
   1664 			}
   1665 
   1666 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
   1667 			{
   1668 				for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
   1669 				{
   1670 					CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf);
   1671 				}
   1672 			}
   1673 
   1674 			cgltf_accessor* indices = data->meshes[i].primitives[j].indices;
   1675 
   1676 			CGLTF_ASSERT_IF(indices &&
   1677 				indices->component_type != cgltf_component_type_r_8u &&
   1678 				indices->component_type != cgltf_component_type_r_16u &&
   1679 				indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
   1680 
   1681 			CGLTF_ASSERT_IF(indices && indices->type != cgltf_type_scalar, cgltf_result_invalid_gltf);
   1682 			CGLTF_ASSERT_IF(indices && indices->stride != cgltf_component_size(indices->component_type), cgltf_result_invalid_gltf);
   1683 
   1684 			if (indices && indices->buffer_view && indices->buffer_view->buffer->data)
   1685 			{
   1686 				cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count);
   1687 
   1688 				CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short);
   1689 			}
   1690 
   1691 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
   1692 			{
   1693 				CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf);
   1694 			}
   1695 		}
   1696 	}
   1697 
   1698 	for (cgltf_size i = 0; i < data->nodes_count; ++i)
   1699 	{
   1700 		if (data->nodes[i].weights && data->nodes[i].mesh)
   1701 		{
   1702 			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);
   1703 		}
   1704 
   1705 		if (data->nodes[i].has_mesh_gpu_instancing)
   1706 		{
   1707 			CGLTF_ASSERT_IF(data->nodes[i].mesh == NULL, cgltf_result_invalid_gltf);
   1708 			CGLTF_ASSERT_IF(data->nodes[i].mesh_gpu_instancing.attributes_count == 0, cgltf_result_invalid_gltf);
   1709 
   1710 			cgltf_accessor* first = data->nodes[i].mesh_gpu_instancing.attributes[0].data;
   1711 
   1712 			for (cgltf_size k = 0; k < data->nodes[i].mesh_gpu_instancing.attributes_count; ++k)
   1713 			{
   1714 				CGLTF_ASSERT_IF(data->nodes[i].mesh_gpu_instancing.attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
   1715 			}
   1716 		}
   1717 	}
   1718 
   1719 	for (cgltf_size i = 0; i < data->nodes_count; ++i)
   1720 	{
   1721 		cgltf_node* p1 = data->nodes[i].parent;
   1722 		cgltf_node* p2 = p1 ? p1->parent : NULL;
   1723 
   1724 		while (p1 && p2)
   1725 		{
   1726 			CGLTF_ASSERT_IF(p1 == p2, cgltf_result_invalid_gltf);
   1727 
   1728 			p1 = p1->parent;
   1729 			p2 = p2->parent ? p2->parent->parent : NULL;
   1730 		}
   1731 	}
   1732 
   1733 	for (cgltf_size i = 0; i < data->scenes_count; ++i)
   1734 	{
   1735 		for (cgltf_size j = 0; j < data->scenes[i].nodes_count; ++j)
   1736 		{
   1737 			CGLTF_ASSERT_IF(data->scenes[i].nodes[j]->parent, cgltf_result_invalid_gltf);
   1738 		}
   1739 	}
   1740 
   1741 	for (cgltf_size i = 0; i < data->animations_count; ++i)
   1742 	{
   1743 		for (cgltf_size j = 0; j < data->animations[i].channels_count; ++j)
   1744 		{
   1745 			cgltf_animation_channel* channel = &data->animations[i].channels[j];
   1746 
   1747 			if (!channel->target_node)
   1748 			{
   1749 				continue;
   1750 			}
   1751 
   1752 			cgltf_size components = 1;
   1753 
   1754 			if (channel->target_path == cgltf_animation_path_type_weights)
   1755 			{
   1756 				CGLTF_ASSERT_IF(!channel->target_node->mesh || !channel->target_node->mesh->primitives_count, cgltf_result_invalid_gltf);
   1757 
   1758 				components = channel->target_node->mesh->primitives[0].targets_count;
   1759 			}
   1760 
   1761 			cgltf_size values = channel->sampler->interpolation == cgltf_interpolation_type_cubic_spline ? 3 : 1;
   1762 
   1763 			CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_invalid_gltf);
   1764 		}
   1765 	}
   1766 
   1767 	for (cgltf_size i = 0; i < data->variants_count; ++i)
   1768 	{
   1769 		CGLTF_ASSERT_IF(!data->variants[i].name, cgltf_result_invalid_gltf);
   1770 	}
   1771 
   1772 	return cgltf_result_success;
   1773 }
   1774 
   1775 cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* extras, char* dest, cgltf_size* dest_size)
   1776 {
   1777 	cgltf_size json_size = extras->end_offset - extras->start_offset;
   1778 
   1779 	if (!dest)
   1780 	{
   1781 		if (dest_size)
   1782 		{
   1783 			*dest_size = json_size + 1;
   1784 			return cgltf_result_success;
   1785 		}
   1786 		return cgltf_result_invalid_options;
   1787 	}
   1788 
   1789 	if (*dest_size + 1 < json_size)
   1790 	{
   1791 		strncpy(dest, data->json + extras->start_offset, *dest_size - 1);
   1792 		dest[*dest_size - 1] = 0;
   1793 	}
   1794 	else
   1795 	{
   1796 		strncpy(dest, data->json + extras->start_offset, json_size);
   1797 		dest[json_size] = 0;
   1798 	}
   1799 
   1800 	return cgltf_result_success;
   1801 }
   1802 
   1803 static void cgltf_free_extras(cgltf_data* data, cgltf_extras* extras)
   1804 {
   1805 	data->memory.free_func(data->memory.user_data, extras->data);
   1806 }
   1807 
   1808 static void cgltf_free_extensions(cgltf_data* data, cgltf_extension* extensions, cgltf_size extensions_count)
   1809 {
   1810 	for (cgltf_size i = 0; i < extensions_count; ++i)
   1811 	{
   1812 		data->memory.free_func(data->memory.user_data, extensions[i].name);
   1813 		data->memory.free_func(data->memory.user_data, extensions[i].data);
   1814 	}
   1815 	data->memory.free_func(data->memory.user_data, extensions);
   1816 }
   1817 
   1818 void cgltf_free(cgltf_data* data)
   1819 {
   1820 	if (!data)
   1821 	{
   1822 		return;
   1823 	}
   1824 
   1825 	void (*file_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data) = data->file.release ? data->file.release : cgltf_default_file_release;
   1826 
   1827 	data->memory.free_func(data->memory.user_data, data->asset.copyright);
   1828 	data->memory.free_func(data->memory.user_data, data->asset.generator);
   1829 	data->memory.free_func(data->memory.user_data, data->asset.version);
   1830 	data->memory.free_func(data->memory.user_data, data->asset.min_version);
   1831 
   1832 	cgltf_free_extensions(data, data->asset.extensions, data->asset.extensions_count);
   1833 	cgltf_free_extras(data, &data->asset.extras);
   1834 
   1835 	for (cgltf_size i = 0; i < data->accessors_count; ++i)
   1836 	{
   1837 		data->memory.free_func(data->memory.user_data, data->accessors[i].name);
   1838 
   1839 		cgltf_free_extensions(data, data->accessors[i].extensions, data->accessors[i].extensions_count);
   1840 		cgltf_free_extras(data, &data->accessors[i].extras);
   1841 	}
   1842 	data->memory.free_func(data->memory.user_data, data->accessors);
   1843 
   1844 	for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
   1845 	{
   1846 		data->memory.free_func(data->memory.user_data, data->buffer_views[i].name);
   1847 		data->memory.free_func(data->memory.user_data, data->buffer_views[i].data);
   1848 
   1849 		cgltf_free_extensions(data, data->buffer_views[i].extensions, data->buffer_views[i].extensions_count);
   1850 		cgltf_free_extras(data, &data->buffer_views[i].extras);
   1851 	}
   1852 	data->memory.free_func(data->memory.user_data, data->buffer_views);
   1853 
   1854 	for (cgltf_size i = 0; i < data->buffers_count; ++i)
   1855 	{
   1856 		data->memory.free_func(data->memory.user_data, data->buffers[i].name);
   1857 
   1858 		if (data->buffers[i].data_free_method == cgltf_data_free_method_file_release)
   1859 		{
   1860 			file_release(&data->memory, &data->file, data->buffers[i].data);
   1861 		}
   1862 		else if (data->buffers[i].data_free_method == cgltf_data_free_method_memory_free)
   1863 		{
   1864 			data->memory.free_func(data->memory.user_data, data->buffers[i].data);
   1865 		}
   1866 
   1867 		data->memory.free_func(data->memory.user_data, data->buffers[i].uri);
   1868 
   1869 		cgltf_free_extensions(data, data->buffers[i].extensions, data->buffers[i].extensions_count);
   1870 		cgltf_free_extras(data, &data->buffers[i].extras);
   1871 	}
   1872 	data->memory.free_func(data->memory.user_data, data->buffers);
   1873 
   1874 	for (cgltf_size i = 0; i < data->meshes_count; ++i)
   1875 	{
   1876 		data->memory.free_func(data->memory.user_data, data->meshes[i].name);
   1877 
   1878 		for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
   1879 		{
   1880 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
   1881 			{
   1882 				data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].attributes[k].name);
   1883 			}
   1884 
   1885 			data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].attributes);
   1886 
   1887 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
   1888 			{
   1889 				for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
   1890 				{
   1891 					data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].targets[k].attributes[m].name);
   1892 				}
   1893 
   1894 				data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].targets[k].attributes);
   1895 			}
   1896 
   1897 			data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].targets);
   1898 
   1899 			if (data->meshes[i].primitives[j].has_draco_mesh_compression)
   1900 			{
   1901 				for (cgltf_size k = 0; k < data->meshes[i].primitives[j].draco_mesh_compression.attributes_count; ++k)
   1902 				{
   1903 					data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes[k].name);
   1904 				}
   1905 
   1906 				data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes);
   1907 			}
   1908 
   1909 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
   1910 			{
   1911 				cgltf_free_extras(data, &data->meshes[i].primitives[j].mappings[k].extras);
   1912 			}
   1913 
   1914 			data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].mappings);
   1915 
   1916 			cgltf_free_extensions(data, data->meshes[i].primitives[j].extensions, data->meshes[i].primitives[j].extensions_count);
   1917 			cgltf_free_extras(data, &data->meshes[i].primitives[j].extras);
   1918 		}
   1919 
   1920 		data->memory.free_func(data->memory.user_data, data->meshes[i].primitives);
   1921 		data->memory.free_func(data->memory.user_data, data->meshes[i].weights);
   1922 
   1923 		for (cgltf_size j = 0; j < data->meshes[i].target_names_count; ++j)
   1924 		{
   1925 			data->memory.free_func(data->memory.user_data, data->meshes[i].target_names[j]);
   1926 		}
   1927 
   1928 		cgltf_free_extensions(data, data->meshes[i].extensions, data->meshes[i].extensions_count);
   1929 		cgltf_free_extras(data, &data->meshes[i].extras);
   1930 
   1931 		data->memory.free_func(data->memory.user_data, data->meshes[i].target_names);
   1932 	}
   1933 
   1934 	data->memory.free_func(data->memory.user_data, data->meshes);
   1935 
   1936 	for (cgltf_size i = 0; i < data->materials_count; ++i)
   1937 	{
   1938 		data->memory.free_func(data->memory.user_data, data->materials[i].name);
   1939 
   1940 		cgltf_free_extensions(data, data->materials[i].extensions, data->materials[i].extensions_count);
   1941 		cgltf_free_extras(data, &data->materials[i].extras);
   1942 	}
   1943 
   1944 	data->memory.free_func(data->memory.user_data, data->materials);
   1945 
   1946 	for (cgltf_size i = 0; i < data->images_count; ++i)
   1947 	{
   1948 		data->memory.free_func(data->memory.user_data, data->images[i].name);
   1949 		data->memory.free_func(data->memory.user_data, data->images[i].uri);
   1950 		data->memory.free_func(data->memory.user_data, data->images[i].mime_type);
   1951 
   1952 		cgltf_free_extensions(data, data->images[i].extensions, data->images[i].extensions_count);
   1953 		cgltf_free_extras(data, &data->images[i].extras);
   1954 	}
   1955 
   1956 	data->memory.free_func(data->memory.user_data, data->images);
   1957 
   1958 	for (cgltf_size i = 0; i < data->textures_count; ++i)
   1959 	{
   1960 		data->memory.free_func(data->memory.user_data, data->textures[i].name);
   1961 
   1962 		cgltf_free_extensions(data, data->textures[i].extensions, data->textures[i].extensions_count);
   1963 		cgltf_free_extras(data, &data->textures[i].extras);
   1964 	}
   1965 
   1966 	data->memory.free_func(data->memory.user_data, data->textures);
   1967 
   1968 	for (cgltf_size i = 0; i < data->samplers_count; ++i)
   1969 	{
   1970 		data->memory.free_func(data->memory.user_data, data->samplers[i].name);
   1971 
   1972 		cgltf_free_extensions(data, data->samplers[i].extensions, data->samplers[i].extensions_count);
   1973 		cgltf_free_extras(data, &data->samplers[i].extras);
   1974 	}
   1975 
   1976 	data->memory.free_func(data->memory.user_data, data->samplers);
   1977 
   1978 	for (cgltf_size i = 0; i < data->skins_count; ++i)
   1979 	{
   1980 		data->memory.free_func(data->memory.user_data, data->skins[i].name);
   1981 		data->memory.free_func(data->memory.user_data, data->skins[i].joints);
   1982 
   1983 		cgltf_free_extensions(data, data->skins[i].extensions, data->skins[i].extensions_count);
   1984 		cgltf_free_extras(data, &data->skins[i].extras);
   1985 	}
   1986 
   1987 	data->memory.free_func(data->memory.user_data, data->skins);
   1988 
   1989 	for (cgltf_size i = 0; i < data->cameras_count; ++i)
   1990 	{
   1991 		data->memory.free_func(data->memory.user_data, data->cameras[i].name);
   1992 
   1993 		if (data->cameras[i].type == cgltf_camera_type_perspective)
   1994 		{
   1995 			cgltf_free_extras(data, &data->cameras[i].data.perspective.extras);
   1996 		}
   1997 		else if (data->cameras[i].type == cgltf_camera_type_orthographic)
   1998 		{
   1999 			cgltf_free_extras(data, &data->cameras[i].data.orthographic.extras);
   2000 		}
   2001 
   2002 		cgltf_free_extensions(data, data->cameras[i].extensions, data->cameras[i].extensions_count);
   2003 		cgltf_free_extras(data, &data->cameras[i].extras);
   2004 	}
   2005 
   2006 	data->memory.free_func(data->memory.user_data, data->cameras);
   2007 
   2008 	for (cgltf_size i = 0; i < data->lights_count; ++i)
   2009 	{
   2010 		data->memory.free_func(data->memory.user_data, data->lights[i].name);
   2011 
   2012 		cgltf_free_extras(data, &data->lights[i].extras);
   2013 	}
   2014 
   2015 	data->memory.free_func(data->memory.user_data, data->lights);
   2016 
   2017 	for (cgltf_size i = 0; i < data->nodes_count; ++i)
   2018 	{
   2019 		data->memory.free_func(data->memory.user_data, data->nodes[i].name);
   2020 		data->memory.free_func(data->memory.user_data, data->nodes[i].children);
   2021 		data->memory.free_func(data->memory.user_data, data->nodes[i].weights);
   2022 
   2023 		if (data->nodes[i].has_mesh_gpu_instancing)
   2024 		{
   2025 			for (cgltf_size j = 0; j < data->nodes[i].mesh_gpu_instancing.attributes_count; ++j)
   2026 			{
   2027 				data->memory.free_func(data->memory.user_data, data->nodes[i].mesh_gpu_instancing.attributes[j].name);
   2028 			}
   2029 
   2030 			data->memory.free_func(data->memory.user_data, data->nodes[i].mesh_gpu_instancing.attributes);
   2031 		}
   2032 
   2033 		cgltf_free_extensions(data, data->nodes[i].extensions, data->nodes[i].extensions_count);
   2034 		cgltf_free_extras(data, &data->nodes[i].extras);
   2035 	}
   2036 
   2037 	data->memory.free_func(data->memory.user_data, data->nodes);
   2038 
   2039 	for (cgltf_size i = 0; i < data->scenes_count; ++i)
   2040 	{
   2041 		data->memory.free_func(data->memory.user_data, data->scenes[i].name);
   2042 		data->memory.free_func(data->memory.user_data, data->scenes[i].nodes);
   2043 
   2044 		cgltf_free_extensions(data, data->scenes[i].extensions, data->scenes[i].extensions_count);
   2045 		cgltf_free_extras(data, &data->scenes[i].extras);
   2046 	}
   2047 
   2048 	data->memory.free_func(data->memory.user_data, data->scenes);
   2049 
   2050 	for (cgltf_size i = 0; i < data->animations_count; ++i)
   2051 	{
   2052 		data->memory.free_func(data->memory.user_data, data->animations[i].name);
   2053 		for (cgltf_size j = 0; j <  data->animations[i].samplers_count; ++j)
   2054 		{
   2055 			cgltf_free_extensions(data, data->animations[i].samplers[j].extensions, data->animations[i].samplers[j].extensions_count);
   2056 			cgltf_free_extras(data, &data->animations[i].samplers[j].extras);
   2057 		}
   2058 		data->memory.free_func(data->memory.user_data, data->animations[i].samplers);
   2059 
   2060 		for (cgltf_size j = 0; j <  data->animations[i].channels_count; ++j)
   2061 		{
   2062 			cgltf_free_extensions(data, data->animations[i].channels[j].extensions, data->animations[i].channels[j].extensions_count);
   2063 			cgltf_free_extras(data, &data->animations[i].channels[j].extras);
   2064 		}
   2065 		data->memory.free_func(data->memory.user_data, data->animations[i].channels);
   2066 
   2067 		cgltf_free_extensions(data, data->animations[i].extensions, data->animations[i].extensions_count);
   2068 		cgltf_free_extras(data, &data->animations[i].extras);
   2069 	}
   2070 
   2071 	data->memory.free_func(data->memory.user_data, data->animations);
   2072 
   2073 	for (cgltf_size i = 0; i < data->variants_count; ++i)
   2074 	{
   2075 		data->memory.free_func(data->memory.user_data, data->variants[i].name);
   2076 
   2077 		cgltf_free_extras(data, &data->variants[i].extras);
   2078 	}
   2079 
   2080 	data->memory.free_func(data->memory.user_data, data->variants);
   2081 
   2082 	cgltf_free_extensions(data, data->data_extensions, data->data_extensions_count);
   2083 	cgltf_free_extras(data, &data->extras);
   2084 
   2085 	for (cgltf_size i = 0; i < data->extensions_used_count; ++i)
   2086 	{
   2087 		data->memory.free_func(data->memory.user_data, data->extensions_used[i]);
   2088 	}
   2089 
   2090 	data->memory.free_func(data->memory.user_data, data->extensions_used);
   2091 
   2092 	for (cgltf_size i = 0; i < data->extensions_required_count; ++i)
   2093 	{
   2094 		data->memory.free_func(data->memory.user_data, data->extensions_required[i]);
   2095 	}
   2096 
   2097 	data->memory.free_func(data->memory.user_data, data->extensions_required);
   2098 
   2099 	file_release(&data->memory, &data->file, data->file_data);
   2100 
   2101 	data->memory.free_func(data->memory.user_data, data);
   2102 }
   2103 
   2104 void cgltf_node_transform_local(const cgltf_node* node, cgltf_float* out_matrix)
   2105 {
   2106 	cgltf_float* lm = out_matrix;
   2107 
   2108 	if (node->has_matrix)
   2109 	{
   2110 		memcpy(lm, node->matrix, sizeof(float) * 16);
   2111 	}
   2112 	else
   2113 	{
   2114 		float tx = node->translation[0];
   2115 		float ty = node->translation[1];
   2116 		float tz = node->translation[2];
   2117 
   2118 		float qx = node->rotation[0];
   2119 		float qy = node->rotation[1];
   2120 		float qz = node->rotation[2];
   2121 		float qw = node->rotation[3];
   2122 
   2123 		float sx = node->scale[0];
   2124 		float sy = node->scale[1];
   2125 		float sz = node->scale[2];
   2126 
   2127 		lm[0] = (1 - 2 * qy*qy - 2 * qz*qz) * sx;
   2128 		lm[1] = (2 * qx*qy + 2 * qz*qw) * sx;
   2129 		lm[2] = (2 * qx*qz - 2 * qy*qw) * sx;
   2130 		lm[3] = 0.f;
   2131 
   2132 		lm[4] = (2 * qx*qy - 2 * qz*qw) * sy;
   2133 		lm[5] = (1 - 2 * qx*qx - 2 * qz*qz) * sy;
   2134 		lm[6] = (2 * qy*qz + 2 * qx*qw) * sy;
   2135 		lm[7] = 0.f;
   2136 
   2137 		lm[8] = (2 * qx*qz + 2 * qy*qw) * sz;
   2138 		lm[9] = (2 * qy*qz - 2 * qx*qw) * sz;
   2139 		lm[10] = (1 - 2 * qx*qx - 2 * qy*qy) * sz;
   2140 		lm[11] = 0.f;
   2141 
   2142 		lm[12] = tx;
   2143 		lm[13] = ty;
   2144 		lm[14] = tz;
   2145 		lm[15] = 1.f;
   2146 	}
   2147 }
   2148 
   2149 void cgltf_node_transform_world(const cgltf_node* node, cgltf_float* out_matrix)
   2150 {
   2151 	cgltf_float* lm = out_matrix;
   2152 	cgltf_node_transform_local(node, lm);
   2153 
   2154 	const cgltf_node* parent = node->parent;
   2155 
   2156 	while (parent)
   2157 	{
   2158 		float pm[16];
   2159 		cgltf_node_transform_local(parent, pm);
   2160 
   2161 		for (int i = 0; i < 4; ++i)
   2162 		{
   2163 			float l0 = lm[i * 4 + 0];
   2164 			float l1 = lm[i * 4 + 1];
   2165 			float l2 = lm[i * 4 + 2];
   2166 
   2167 			float r0 = l0 * pm[0] + l1 * pm[4] + l2 * pm[8];
   2168 			float r1 = l0 * pm[1] + l1 * pm[5] + l2 * pm[9];
   2169 			float r2 = l0 * pm[2] + l1 * pm[6] + l2 * pm[10];
   2170 
   2171 			lm[i * 4 + 0] = r0;
   2172 			lm[i * 4 + 1] = r1;
   2173 			lm[i * 4 + 2] = r2;
   2174 		}
   2175 
   2176 		lm[12] += pm[12];
   2177 		lm[13] += pm[13];
   2178 		lm[14] += pm[14];
   2179 
   2180 		parent = parent->parent;
   2181 	}
   2182 }
   2183 
   2184 static cgltf_ssize cgltf_component_read_integer(const void* in, cgltf_component_type component_type)
   2185 {
   2186 	switch (component_type)
   2187 	{
   2188 		case cgltf_component_type_r_16:
   2189 			return *((const int16_t*) in);
   2190 		case cgltf_component_type_r_16u:
   2191 			return *((const uint16_t*) in);
   2192 		case cgltf_component_type_r_32u:
   2193 			return *((const uint32_t*) in);
   2194 		case cgltf_component_type_r_8:
   2195 			return *((const int8_t*) in);
   2196 		case cgltf_component_type_r_8u:
   2197 			return *((const uint8_t*) in);
   2198 		default:
   2199 			return 0;
   2200 	}
   2201 }
   2202 
   2203 static cgltf_size cgltf_component_read_index(const void* in, cgltf_component_type component_type)
   2204 {
   2205 	switch (component_type)
   2206 	{
   2207 		case cgltf_component_type_r_16u:
   2208 			return *((const uint16_t*) in);
   2209 		case cgltf_component_type_r_32u:
   2210 			return *((const uint32_t*) in);
   2211 		case cgltf_component_type_r_8u:
   2212 			return *((const uint8_t*) in);
   2213 		default:
   2214 			return 0;
   2215 	}
   2216 }
   2217 
   2218 static cgltf_float cgltf_component_read_float(const void* in, cgltf_component_type component_type, cgltf_bool normalized)
   2219 {
   2220 	if (component_type == cgltf_component_type_r_32f)
   2221 	{
   2222 		return *((const float*) in);
   2223 	}
   2224 
   2225 	if (normalized)
   2226 	{
   2227 		switch (component_type)
   2228 		{
   2229 			// note: glTF spec doesn't currently define normalized conversions for 32-bit integers
   2230 			case cgltf_component_type_r_16:
   2231 				return *((const int16_t*) in) / (cgltf_float)32767;
   2232 			case cgltf_component_type_r_16u:
   2233 				return *((const uint16_t*) in) / (cgltf_float)65535;
   2234 			case cgltf_component_type_r_8:
   2235 				return *((const int8_t*) in) / (cgltf_float)127;
   2236 			case cgltf_component_type_r_8u:
   2237 				return *((const uint8_t*) in) / (cgltf_float)255;
   2238 			default:
   2239 				return 0;
   2240 		}
   2241 	}
   2242 
   2243 	return (cgltf_float)cgltf_component_read_integer(in, component_type);
   2244 }
   2245 
   2246 static 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)
   2247 {
   2248 	cgltf_size num_components = cgltf_num_components(type);
   2249 
   2250 	if (element_size < num_components) {
   2251 		return 0;
   2252 	}
   2253 
   2254 	// There are three special cases for component extraction, see #data-alignment in the 2.0 spec.
   2255 
   2256 	cgltf_size component_size = cgltf_component_size(component_type);
   2257 
   2258 	if (type == cgltf_type_mat2 && component_size == 1)
   2259 	{
   2260 		out[0] = cgltf_component_read_float(element, component_type, normalized);
   2261 		out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
   2262 		out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
   2263 		out[3] = cgltf_component_read_float(element + 5, component_type, normalized);
   2264 		return 1;
   2265 	}
   2266 
   2267 	if (type == cgltf_type_mat3 && component_size == 1)
   2268 	{
   2269 		out[0] = cgltf_component_read_float(element, component_type, normalized);
   2270 		out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
   2271 		out[2] = cgltf_component_read_float(element + 2, component_type, normalized);
   2272 		out[3] = cgltf_component_read_float(element + 4, component_type, normalized);
   2273 		out[4] = cgltf_component_read_float(element + 5, component_type, normalized);
   2274 		out[5] = cgltf_component_read_float(element + 6, component_type, normalized);
   2275 		out[6] = cgltf_component_read_float(element + 8, component_type, normalized);
   2276 		out[7] = cgltf_component_read_float(element + 9, component_type, normalized);
   2277 		out[8] = cgltf_component_read_float(element + 10, component_type, normalized);
   2278 		return 1;
   2279 	}
   2280 
   2281 	if (type == cgltf_type_mat3 && component_size == 2)
   2282 	{
   2283 		out[0] = cgltf_component_read_float(element, component_type, normalized);
   2284 		out[1] = cgltf_component_read_float(element + 2, component_type, normalized);
   2285 		out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
   2286 		out[3] = cgltf_component_read_float(element + 8, component_type, normalized);
   2287 		out[4] = cgltf_component_read_float(element + 10, component_type, normalized);
   2288 		out[5] = cgltf_component_read_float(element + 12, component_type, normalized);
   2289 		out[6] = cgltf_component_read_float(element + 16, component_type, normalized);
   2290 		out[7] = cgltf_component_read_float(element + 18, component_type, normalized);
   2291 		out[8] = cgltf_component_read_float(element + 20, component_type, normalized);
   2292 		return 1;
   2293 	}
   2294 
   2295 	for (cgltf_size i = 0; i < num_components; ++i)
   2296 	{
   2297 		out[i] = cgltf_component_read_float(element + component_size * i, component_type, normalized);
   2298 	}
   2299 	return 1;
   2300 }
   2301 
   2302 const uint8_t* cgltf_buffer_view_data(const cgltf_buffer_view* view)
   2303 {
   2304 	if (view->data)
   2305 		return (const uint8_t*)view->data;
   2306 
   2307 	if (!view->buffer->data)
   2308 		return NULL;
   2309 
   2310 	const uint8_t* result = (const uint8_t*)view->buffer->data;
   2311 	result += view->offset;
   2312 	return result;
   2313 }
   2314 
   2315 cgltf_bool cgltf_accessor_read_float(const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size)
   2316 {
   2317 	if (accessor->is_sparse)
   2318 	{
   2319 		return 0;
   2320 	}
   2321 	if (accessor->buffer_view == NULL)
   2322 	{
   2323 		memset(out, 0, element_size * sizeof(cgltf_float));
   2324 		return 1;
   2325 	}
   2326 	const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
   2327 	if (element == NULL)
   2328 	{
   2329 		return 0;
   2330 	}
   2331 	element += accessor->offset + accessor->stride * index;
   2332 	return cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, out, element_size);
   2333 }
   2334 
   2335 cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count)
   2336 {
   2337 	cgltf_size floats_per_element = cgltf_num_components(accessor->type);
   2338 	cgltf_size available_floats = accessor->count * floats_per_element;
   2339 	if (out == NULL)
   2340 	{
   2341 		return available_floats;
   2342 	}
   2343 
   2344 	float_count = available_floats < float_count ? available_floats : float_count;
   2345 	cgltf_size element_count = float_count / floats_per_element;
   2346 
   2347 	// First pass: convert each element in the base accessor.
   2348 	if (accessor->buffer_view == NULL)
   2349 	{
   2350 		memset(out, 0, element_count * floats_per_element * sizeof(cgltf_float));
   2351 	}
   2352 	else
   2353 	{
   2354 		const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
   2355 		if (element == NULL)
   2356 		{
   2357 			return 0;
   2358 		}
   2359 		element += accessor->offset;
   2360 
   2361 		if (accessor->component_type == cgltf_component_type_r_32f && accessor->stride == floats_per_element * sizeof(cgltf_float))
   2362 		{
   2363 			memcpy(out, element, element_count * floats_per_element * sizeof(cgltf_float));
   2364 		}
   2365 		else
   2366 		{
   2367 			cgltf_float* dest = out;
   2368 
   2369 			for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element, element += accessor->stride)
   2370 			{
   2371 				if (!cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, dest, floats_per_element))
   2372 				{
   2373 					return 0;
   2374 				}
   2375 			}
   2376 		}
   2377 	}
   2378 
   2379 	// Second pass: write out each element in the sparse accessor.
   2380 	if (accessor->is_sparse)
   2381 	{
   2382 		const cgltf_accessor_sparse* sparse = &accessor->sparse;
   2383 
   2384 		const uint8_t* index_data = cgltf_buffer_view_data(sparse->indices_buffer_view);
   2385 		const uint8_t* reader_head = cgltf_buffer_view_data(sparse->values_buffer_view);
   2386 
   2387 		if (index_data == NULL || reader_head == NULL)
   2388 		{
   2389 			return 0;
   2390 		}
   2391 
   2392 		index_data += sparse->indices_byte_offset;
   2393 		reader_head += sparse->values_byte_offset;
   2394 
   2395 		cgltf_size index_stride = cgltf_component_size(sparse->indices_component_type);
   2396 		for (cgltf_size reader_index = 0; reader_index < sparse->count; reader_index++, index_data += index_stride, reader_head += accessor->stride)
   2397 		{
   2398 			size_t writer_index = cgltf_component_read_index(index_data, sparse->indices_component_type);
   2399 			float* writer_head = out + writer_index * floats_per_element;
   2400 
   2401 			if (!cgltf_element_read_float(reader_head, accessor->type, accessor->component_type, accessor->normalized, writer_head, floats_per_element))
   2402 			{
   2403 				return 0;
   2404 			}
   2405 		}
   2406 	}
   2407 
   2408 	return element_count * floats_per_element;
   2409 }
   2410 
   2411 static cgltf_uint cgltf_component_read_uint(const void* in, cgltf_component_type component_type)
   2412 {
   2413 	switch (component_type)
   2414 	{
   2415 		case cgltf_component_type_r_8:
   2416 			return *((const int8_t*) in);
   2417 
   2418 		case cgltf_component_type_r_8u:
   2419 			return *((const uint8_t*) in);
   2420 
   2421 		case cgltf_component_type_r_16:
   2422 			return *((const int16_t*) in);
   2423 
   2424 		case cgltf_component_type_r_16u:
   2425 			return *((const uint16_t*) in);
   2426 
   2427 		case cgltf_component_type_r_32u:
   2428 			return *((const uint32_t*) in);
   2429 
   2430 		default:
   2431 			return 0;
   2432 	}
   2433 }
   2434 
   2435 static 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)
   2436 {
   2437 	cgltf_size num_components = cgltf_num_components(type);
   2438 
   2439 	if (element_size < num_components)
   2440 	{
   2441 		return 0;
   2442 	}
   2443 
   2444 	// Reading integer matrices is not a valid use case
   2445 	if (type == cgltf_type_mat2 || type == cgltf_type_mat3 || type == cgltf_type_mat4)
   2446 	{
   2447 		return 0;
   2448 	}
   2449 
   2450 	cgltf_size component_size = cgltf_component_size(component_type);
   2451 
   2452 	for (cgltf_size i = 0; i < num_components; ++i)
   2453 	{
   2454 		out[i] = cgltf_component_read_uint(element + component_size * i, component_type);
   2455 	}
   2456 	return 1;
   2457 }
   2458 
   2459 cgltf_bool cgltf_accessor_read_uint(const cgltf_accessor* accessor, cgltf_size index, cgltf_uint* out, cgltf_size element_size)
   2460 {
   2461 	if (accessor->is_sparse)
   2462 	{
   2463 		return 0;
   2464 	}
   2465 	if (accessor->buffer_view == NULL)
   2466 	{
   2467 		memset(out, 0, element_size * sizeof( cgltf_uint ));
   2468 		return 1;
   2469 	}
   2470 	const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
   2471 	if (element == NULL)
   2472 	{
   2473 		return 0;
   2474 	}
   2475 	element += accessor->offset + accessor->stride * index;
   2476 	return cgltf_element_read_uint(element, accessor->type, accessor->component_type, out, element_size);
   2477 }
   2478 
   2479 cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size index)
   2480 {
   2481 	if (accessor->is_sparse)
   2482 	{
   2483 		return 0; // This is an error case, but we can't communicate the error with existing interface.
   2484 	}
   2485 	if (accessor->buffer_view == NULL)
   2486 	{
   2487 		return 0;
   2488 	}
   2489 	const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
   2490 	if (element == NULL)
   2491 	{
   2492 		return 0; // This is an error case, but we can't communicate the error with existing interface.
   2493 	}
   2494 	element += accessor->offset + accessor->stride * index;
   2495 	return cgltf_component_read_index(element, accessor->component_type);
   2496 }
   2497 
   2498 cgltf_size cgltf_mesh_index(const cgltf_data* data, const cgltf_mesh* object)
   2499 {
   2500 	assert(object && (cgltf_size)(object - data->meshes) < data->meshes_count);
   2501 	return (cgltf_size)(object - data->meshes);
   2502 }
   2503 
   2504 cgltf_size cgltf_material_index(const cgltf_data* data, const cgltf_material* object)
   2505 {
   2506 	assert(object && (cgltf_size)(object - data->materials) < data->materials_count);
   2507 	return (cgltf_size)(object - data->materials);
   2508 }
   2509 
   2510 cgltf_size cgltf_accessor_index(const cgltf_data* data, const cgltf_accessor* object)
   2511 {
   2512 	assert(object && (cgltf_size)(object - data->accessors) < data->accessors_count);
   2513 	return (cgltf_size)(object - data->accessors);
   2514 }
   2515 
   2516 cgltf_size cgltf_buffer_view_index(const cgltf_data* data, const cgltf_buffer_view* object)
   2517 {
   2518 	assert(object && (cgltf_size)(object - data->buffer_views) < data->buffer_views_count);
   2519 	return (cgltf_size)(object - data->buffer_views);
   2520 }
   2521 
   2522 cgltf_size cgltf_buffer_index(const cgltf_data* data, const cgltf_buffer* object)
   2523 {
   2524 	assert(object && (cgltf_size)(object - data->buffers) < data->buffers_count);
   2525 	return (cgltf_size)(object - data->buffers);
   2526 }
   2527 
   2528 cgltf_size cgltf_image_index(const cgltf_data* data, const cgltf_image* object)
   2529 {
   2530 	assert(object && (cgltf_size)(object - data->images) < data->images_count);
   2531 	return (cgltf_size)(object - data->images);
   2532 }
   2533 
   2534 cgltf_size cgltf_texture_index(const cgltf_data* data, const cgltf_texture* object)
   2535 {
   2536 	assert(object && (cgltf_size)(object - data->textures) < data->textures_count);
   2537 	return (cgltf_size)(object - data->textures);
   2538 }
   2539 
   2540 cgltf_size cgltf_sampler_index(const cgltf_data* data, const cgltf_sampler* object)
   2541 {
   2542 	assert(object && (cgltf_size)(object - data->samplers) < data->samplers_count);
   2543 	return (cgltf_size)(object - data->samplers);
   2544 }
   2545 
   2546 cgltf_size cgltf_skin_index(const cgltf_data* data, const cgltf_skin* object)
   2547 {
   2548 	assert(object && (cgltf_size)(object - data->skins) < data->skins_count);
   2549 	return (cgltf_size)(object - data->skins);
   2550 }
   2551 
   2552 cgltf_size cgltf_camera_index(const cgltf_data* data, const cgltf_camera* object)
   2553 {
   2554 	assert(object && (cgltf_size)(object - data->cameras) < data->cameras_count);
   2555 	return (cgltf_size)(object - data->cameras);
   2556 }
   2557 
   2558 cgltf_size cgltf_light_index(const cgltf_data* data, const cgltf_light* object)
   2559 {
   2560 	assert(object && (cgltf_size)(object - data->lights) < data->lights_count);
   2561 	return (cgltf_size)(object - data->lights);
   2562 }
   2563 
   2564 cgltf_size cgltf_node_index(const cgltf_data* data, const cgltf_node* object)
   2565 {
   2566 	assert(object && (cgltf_size)(object - data->nodes) < data->nodes_count);
   2567 	return (cgltf_size)(object - data->nodes);
   2568 }
   2569 
   2570 cgltf_size cgltf_scene_index(const cgltf_data* data, const cgltf_scene* object)
   2571 {
   2572 	assert(object && (cgltf_size)(object - data->scenes) < data->scenes_count);
   2573 	return (cgltf_size)(object - data->scenes);
   2574 }
   2575 
   2576 cgltf_size cgltf_animation_index(const cgltf_data* data, const cgltf_animation* object)
   2577 {
   2578 	assert(object && (cgltf_size)(object - data->animations) < data->animations_count);
   2579 	return (cgltf_size)(object - data->animations);
   2580 }
   2581 
   2582 cgltf_size cgltf_animation_sampler_index(const cgltf_animation* animation, const cgltf_animation_sampler* object)
   2583 {
   2584 	assert(object && (cgltf_size)(object - animation->samplers) < animation->samplers_count);
   2585 	return (cgltf_size)(object - animation->samplers);
   2586 }
   2587 
   2588 cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const cgltf_animation_channel* object)
   2589 {
   2590 	assert(object && (cgltf_size)(object - animation->channels) < animation->channels_count);
   2591 	return (cgltf_size)(object - animation->channels);
   2592 }
   2593 
   2594 cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count)
   2595 {
   2596 	if (out == NULL)
   2597 	{
   2598 		return accessor->count;
   2599 	}
   2600 
   2601 	index_count = accessor->count < index_count ? accessor->count : index_count;
   2602 	cgltf_size index_component_size = cgltf_component_size(accessor->component_type);
   2603 
   2604 	if (accessor->is_sparse)
   2605 	{
   2606 		return 0;
   2607 	}
   2608 	if (accessor->buffer_view == NULL)
   2609 	{
   2610 		return 0;
   2611 	}
   2612 	if (index_component_size > out_component_size)
   2613 	{
   2614 		return 0;
   2615 	}
   2616 	const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
   2617 	if (element == NULL)
   2618 	{
   2619 		return 0;
   2620 	}
   2621 	element += accessor->offset;
   2622 
   2623 	if (index_component_size == out_component_size && accessor->stride == out_component_size)
   2624 	{
   2625 		memcpy(out, element, index_count * index_component_size);
   2626 		return index_count;
   2627 	}
   2628 
   2629 	// The component size of the output array is larger than the component size of the index data, so index data will be padded.
   2630 	switch (out_component_size)
   2631 	{
   2632 	case 2:
   2633 		for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)
   2634 		{
   2635 			((uint16_t*)out)[index] = (uint16_t)cgltf_component_read_index(element, accessor->component_type);
   2636 		}
   2637 		break;
   2638 	case 4:
   2639 		for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)
   2640 		{
   2641 			((uint32_t*)out)[index] = (uint32_t)cgltf_component_read_index(element, accessor->component_type);
   2642 		}
   2643 		break;
   2644 	default:
   2645 		break;
   2646 	}
   2647 
   2648 	return index_count;
   2649 }
   2650 
   2651 #define CGLTF_ERROR_JSON -1
   2652 #define CGLTF_ERROR_NOMEM -2
   2653 #define CGLTF_ERROR_LEGACY -3
   2654 
   2655 #define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; }
   2656 #define CGLTF_CHECK_TOKTYPE_RET(tok_, type_, ret_) if ((tok_).type != (type_)) { return ret_; }
   2657 #define CGLTF_CHECK_KEY(tok_) if ((tok_).type != JSMN_STRING || (tok_).size == 0) { return CGLTF_ERROR_JSON; } /* checking size for 0 verifies that a value follows the key */
   2658 
   2659 #define CGLTF_PTRINDEX(type, idx) (type*)((cgltf_size)idx + 1)
   2660 #define CGLTF_PTRFIXUP(var, data, size) if (var) { if ((cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1]; }
   2661 #define CGLTF_PTRFIXUP_REQ(var, data, size) if (!var || (cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1];
   2662 
   2663 static int cgltf_json_strcmp(jsmntok_t const* tok, const uint8_t* json_chunk, const char* str)
   2664 {
   2665 	CGLTF_CHECK_TOKTYPE(*tok, JSMN_STRING);
   2666 	size_t const str_len = strlen(str);
   2667 	size_t const name_length = (size_t)(tok->end - tok->start);
   2668 	return (str_len == name_length) ? strncmp((const char*)json_chunk + tok->start, str, str_len) : 128;
   2669 }
   2670 
   2671 static int cgltf_json_to_int(jsmntok_t const* tok, const uint8_t* json_chunk)
   2672 {
   2673 	CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
   2674 	char tmp[128];
   2675 	int size = (size_t)(tok->end - tok->start) < sizeof(tmp) ? (int)(tok->end - tok->start) : (int)(sizeof(tmp) - 1);
   2676 	strncpy(tmp, (const char*)json_chunk + tok->start, size);
   2677 	tmp[size] = 0;
   2678 	return CGLTF_ATOI(tmp);
   2679 }
   2680 
   2681 static cgltf_size cgltf_json_to_size(jsmntok_t const* tok, const uint8_t* json_chunk)
   2682 {
   2683 	CGLTF_CHECK_TOKTYPE_RET(*tok, JSMN_PRIMITIVE, 0);
   2684 	char tmp[128];
   2685 	int size = (size_t)(tok->end - tok->start) < sizeof(tmp) ? (int)(tok->end - tok->start) : (int)(sizeof(tmp) - 1);
   2686 	strncpy(tmp, (const char*)json_chunk + tok->start, size);
   2687 	tmp[size] = 0;
   2688 	long long res = CGLTF_ATOLL(tmp);
   2689 	return res < 0 ? 0 : (cgltf_size)res;
   2690 }
   2691 
   2692 static cgltf_float cgltf_json_to_float(jsmntok_t const* tok, const uint8_t* json_chunk)
   2693 {
   2694 	CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
   2695 	char tmp[128];
   2696 	int size = (size_t)(tok->end - tok->start) < sizeof(tmp) ? (int)(tok->end - tok->start) : (int)(sizeof(tmp) - 1);
   2697 	strncpy(tmp, (const char*)json_chunk + tok->start, size);
   2698 	tmp[size] = 0;
   2699 	return (cgltf_float)CGLTF_ATOF(tmp);
   2700 }
   2701 
   2702 static cgltf_bool cgltf_json_to_bool(jsmntok_t const* tok, const uint8_t* json_chunk)
   2703 {
   2704 	int size = (int)(tok->end - tok->start);
   2705 	return size == 4 && memcmp(json_chunk + tok->start, "true", 4) == 0;
   2706 }
   2707 
   2708 static int cgltf_skip_json(jsmntok_t const* tokens, int i)
   2709 {
   2710 	int end = i + 1;
   2711 
   2712 	while (i < end)
   2713 	{
   2714 		switch (tokens[i].type)
   2715 		{
   2716 		case JSMN_OBJECT:
   2717 			end += tokens[i].size * 2;
   2718 			break;
   2719 
   2720 		case JSMN_ARRAY:
   2721 			end += tokens[i].size;
   2722 			break;
   2723 
   2724 		case JSMN_PRIMITIVE:
   2725 		case JSMN_STRING:
   2726 			break;
   2727 
   2728 		default:
   2729 			return -1;
   2730 		}
   2731 
   2732 		i++;
   2733 	}
   2734 
   2735 	return i;
   2736 }
   2737 
   2738 static void cgltf_fill_float_array(float* out_array, int size, float value)
   2739 {
   2740 	for (int j = 0; j < size; ++j)
   2741 	{
   2742 		out_array[j] = value;
   2743 	}
   2744 }
   2745 
   2746 static int cgltf_parse_json_float_array(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, float* out_array, int size)
   2747 {
   2748 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
   2749 	if (tokens[i].size != size)
   2750 	{
   2751 		return CGLTF_ERROR_JSON;
   2752 	}
   2753 	++i;
   2754 	for (int j = 0; j < size; ++j)
   2755 	{
   2756 		CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   2757 		out_array[j] = cgltf_json_to_float(tokens + i, json_chunk);
   2758 		++i;
   2759 	}
   2760 	return i;
   2761 }
   2762 
   2763 static int cgltf_parse_json_string(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, char** out_string)
   2764 {
   2765 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
   2766 	if (*out_string)
   2767 	{
   2768 		return CGLTF_ERROR_JSON;
   2769 	}
   2770 	int size = (int)(tokens[i].end - tokens[i].start);
   2771 	char* result = (char*)options->memory.alloc_func(options->memory.user_data, size + 1);
   2772 	if (!result)
   2773 	{
   2774 		return CGLTF_ERROR_NOMEM;
   2775 	}
   2776 	strncpy(result, (const char*)json_chunk + tokens[i].start, size);
   2777 	result[size] = 0;
   2778 	*out_string = result;
   2779 	return i + 1;
   2780 }
   2781 
   2782 static int cgltf_parse_json_array(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, size_t element_size, void** out_array, cgltf_size* out_size)
   2783 {
   2784 	(void)json_chunk;
   2785 	if (tokens[i].type != JSMN_ARRAY)
   2786 	{
   2787 		return tokens[i].type == JSMN_OBJECT ? CGLTF_ERROR_LEGACY : CGLTF_ERROR_JSON;
   2788 	}
   2789 	if (*out_array)
   2790 	{
   2791 		return CGLTF_ERROR_JSON;
   2792 	}
   2793 	int size = tokens[i].size;
   2794 	void* result = cgltf_calloc(options, element_size, size);
   2795 	if (!result)
   2796 	{
   2797 		return CGLTF_ERROR_NOMEM;
   2798 	}
   2799 	*out_array = result;
   2800 	*out_size = size;
   2801 	return i + 1;
   2802 }
   2803 
   2804 static int cgltf_parse_json_string_array(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, char*** out_array, cgltf_size* out_size)
   2805 {
   2806 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
   2807 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(char*), (void**)out_array, out_size);
   2808 	if (i < 0)
   2809 	{
   2810 		return i;
   2811 	}
   2812 
   2813 	for (cgltf_size j = 0; j < *out_size; ++j)
   2814 	{
   2815 		i = cgltf_parse_json_string(options, tokens, i, json_chunk, j + (*out_array));
   2816 		if (i < 0)
   2817 		{
   2818 			return i;
   2819 		}
   2820 	}
   2821 	return i;
   2822 }
   2823 
   2824 static void cgltf_parse_attribute_type(const char* name, cgltf_attribute_type* out_type, int* out_index)
   2825 {
   2826 	if (*name == '_')
   2827 	{
   2828 		*out_type = cgltf_attribute_type_custom;
   2829 		return;
   2830 	}
   2831 
   2832 	const char* us = strchr(name, '_');
   2833 	size_t len = us ? (size_t)(us - name) : strlen(name);
   2834 
   2835 	if (len == 8 && strncmp(name, "POSITION", 8) == 0)
   2836 	{
   2837 		*out_type = cgltf_attribute_type_position;
   2838 	}
   2839 	else if (len == 6 && strncmp(name, "NORMAL", 6) == 0)
   2840 	{
   2841 		*out_type = cgltf_attribute_type_normal;
   2842 	}
   2843 	else if (len == 7 && strncmp(name, "TANGENT", 7) == 0)
   2844 	{
   2845 		*out_type = cgltf_attribute_type_tangent;
   2846 	}
   2847 	else if (len == 8 && strncmp(name, "TEXCOORD", 8) == 0)
   2848 	{
   2849 		*out_type = cgltf_attribute_type_texcoord;
   2850 	}
   2851 	else if (len == 5 && strncmp(name, "COLOR", 5) == 0)
   2852 	{
   2853 		*out_type = cgltf_attribute_type_color;
   2854 	}
   2855 	else if (len == 6 && strncmp(name, "JOINTS", 6) == 0)
   2856 	{
   2857 		*out_type = cgltf_attribute_type_joints;
   2858 	}
   2859 	else if (len == 7 && strncmp(name, "WEIGHTS", 7) == 0)
   2860 	{
   2861 		*out_type = cgltf_attribute_type_weights;
   2862 	}
   2863 	else
   2864 	{
   2865 		*out_type = cgltf_attribute_type_invalid;
   2866 	}
   2867 
   2868 	if (us && *out_type != cgltf_attribute_type_invalid)
   2869 	{
   2870 		*out_index = CGLTF_ATOI(us + 1);
   2871 		if (*out_index < 0)
   2872 		{
   2873 			*out_type = cgltf_attribute_type_invalid;
   2874 			*out_index = 0;
   2875 		}
   2876 	}
   2877 }
   2878 
   2879 static int cgltf_parse_json_attribute_list(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_attribute** out_attributes, cgltf_size* out_attributes_count)
   2880 {
   2881 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2882 
   2883 	if (*out_attributes)
   2884 	{
   2885 		return CGLTF_ERROR_JSON;
   2886 	}
   2887 
   2888 	*out_attributes_count = tokens[i].size;
   2889 	*out_attributes = (cgltf_attribute*)cgltf_calloc(options, sizeof(cgltf_attribute), *out_attributes_count);
   2890 	++i;
   2891 
   2892 	if (!*out_attributes)
   2893 	{
   2894 		return CGLTF_ERROR_NOMEM;
   2895 	}
   2896 
   2897 	for (cgltf_size j = 0; j < *out_attributes_count; ++j)
   2898 	{
   2899 		CGLTF_CHECK_KEY(tokens[i]);
   2900 
   2901 		i = cgltf_parse_json_string(options, tokens, i, json_chunk, &(*out_attributes)[j].name);
   2902 		if (i < 0)
   2903 		{
   2904 			return CGLTF_ERROR_JSON;
   2905 		}
   2906 
   2907 		cgltf_parse_attribute_type((*out_attributes)[j].name, &(*out_attributes)[j].type, &(*out_attributes)[j].index);
   2908 
   2909 		(*out_attributes)[j].data = CGLTF_PTRINDEX(cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
   2910 		++i;
   2911 	}
   2912 
   2913 	return i;
   2914 }
   2915 
   2916 static int cgltf_parse_json_extras(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_extras* out_extras)
   2917 {
   2918 	if (out_extras->data)
   2919 	{
   2920 		return CGLTF_ERROR_JSON;
   2921 	}
   2922 
   2923 	/* fill deprecated fields for now, this will be removed in the future */
   2924 	out_extras->start_offset = tokens[i].start;
   2925 	out_extras->end_offset = tokens[i].end;
   2926 
   2927 	size_t start = tokens[i].start;
   2928 	size_t size = tokens[i].end - start;
   2929 	out_extras->data = (char*)options->memory.alloc_func(options->memory.user_data, size + 1);
   2930 	if (!out_extras->data)
   2931 	{
   2932 		return CGLTF_ERROR_NOMEM;
   2933 	}
   2934 	strncpy(out_extras->data, (const char*)json_chunk + start, size);
   2935 	out_extras->data[size] = '\0';
   2936 
   2937 	i = cgltf_skip_json(tokens, i);
   2938 	return i;
   2939 }
   2940 
   2941 static int cgltf_parse_json_unprocessed_extension(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_extension* out_extension)
   2942 {
   2943 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
   2944 	CGLTF_CHECK_TOKTYPE(tokens[i+1], JSMN_OBJECT);
   2945 	if (out_extension->name)
   2946 	{
   2947 		return CGLTF_ERROR_JSON;
   2948 	}
   2949 
   2950 	cgltf_size name_length = tokens[i].end - tokens[i].start;
   2951 	out_extension->name = (char*)options->memory.alloc_func(options->memory.user_data, name_length + 1);
   2952 	if (!out_extension->name)
   2953 	{
   2954 		return CGLTF_ERROR_NOMEM;
   2955 	}
   2956 	strncpy(out_extension->name, (const char*)json_chunk + tokens[i].start, name_length);
   2957 	out_extension->name[name_length] = 0;
   2958 	i++;
   2959 
   2960 	size_t start = tokens[i].start;
   2961 	size_t size = tokens[i].end - start;
   2962 	out_extension->data = (char*)options->memory.alloc_func(options->memory.user_data, size + 1);
   2963 	if (!out_extension->data)
   2964 	{
   2965 		return CGLTF_ERROR_NOMEM;
   2966 	}
   2967 	strncpy(out_extension->data, (const char*)json_chunk + start, size);
   2968 	out_extension->data[size] = '\0';
   2969 
   2970 	i = cgltf_skip_json(tokens, i);
   2971 
   2972 	return i;
   2973 }
   2974 
   2975 static int cgltf_parse_json_unprocessed_extensions(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_size* out_extensions_count, cgltf_extension** out_extensions)
   2976 {
   2977 	++i;
   2978 
   2979 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2980 	if(*out_extensions)
   2981 	{
   2982 		return CGLTF_ERROR_JSON;
   2983 	}
   2984 
   2985 	int extensions_size = tokens[i].size;
   2986 	*out_extensions_count = 0;
   2987 	*out_extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size);
   2988 
   2989 	if (!*out_extensions)
   2990 	{
   2991 		return CGLTF_ERROR_NOMEM;
   2992 	}
   2993 
   2994 	++i;
   2995 
   2996 	for (int j = 0; j < extensions_size; ++j)
   2997 	{
   2998 		CGLTF_CHECK_KEY(tokens[i]);
   2999 
   3000 		cgltf_size extension_index = (*out_extensions_count)++;
   3001 		cgltf_extension* extension = &((*out_extensions)[extension_index]);
   3002 		i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, extension);
   3003 
   3004 		if (i < 0)
   3005 		{
   3006 			return i;
   3007 		}
   3008 	}
   3009 	return i;
   3010 }
   3011 
   3012 static int cgltf_parse_json_draco_mesh_compression(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_draco_mesh_compression* out_draco_mesh_compression)
   3013 {
   3014 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3015 
   3016 	int size = tokens[i].size;
   3017 	++i;
   3018 
   3019 	for (int j = 0; j < size; ++j)
   3020 	{
   3021 		CGLTF_CHECK_KEY(tokens[i]);
   3022 
   3023 		if (cgltf_json_strcmp(tokens + i, json_chunk, "attributes") == 0)
   3024 		{
   3025 			i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_draco_mesh_compression->attributes, &out_draco_mesh_compression->attributes_count);
   3026 		}
   3027 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "bufferView") == 0)
   3028 		{
   3029 			++i;
   3030 			out_draco_mesh_compression->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
   3031 			++i;
   3032 		}
   3033 		else
   3034 		{
   3035 			i = cgltf_skip_json(tokens, i+1);
   3036 		}
   3037 
   3038 		if (i < 0)
   3039 		{
   3040 			return i;
   3041 		}
   3042 	}
   3043 
   3044 	return i;
   3045 }
   3046 
   3047 static int cgltf_parse_json_mesh_gpu_instancing(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_mesh_gpu_instancing* out_mesh_gpu_instancing)
   3048 {
   3049 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3050 
   3051 	int size = tokens[i].size;
   3052 	++i;
   3053 
   3054 	for (int j = 0; j < size; ++j)
   3055 	{
   3056 		CGLTF_CHECK_KEY(tokens[i]);
   3057 
   3058 		if (cgltf_json_strcmp(tokens + i, json_chunk, "attributes") == 0)
   3059 		{
   3060 			i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_mesh_gpu_instancing->attributes, &out_mesh_gpu_instancing->attributes_count);
   3061 		}
   3062 		else
   3063 		{
   3064 			i = cgltf_skip_json(tokens, i+1);
   3065 		}
   3066 
   3067 		if (i < 0)
   3068 		{
   3069 			return i;
   3070 		}
   3071 	}
   3072 
   3073 	return i;
   3074 }
   3075 
   3076 static int cgltf_parse_json_material_mapping_data(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_material_mapping* out_mappings, cgltf_size* offset)
   3077 {
   3078 	(void)options;
   3079 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
   3080 
   3081 	int size = tokens[i].size;
   3082 	++i;
   3083 
   3084 	for (int j = 0; j < size; ++j)
   3085 	{
   3086 		CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3087 
   3088 		int obj_size = tokens[i].size;
   3089 		++i;
   3090 
   3091 		int material = -1;
   3092 		int variants_tok = -1;
   3093 		int extras_tok = -1;
   3094 
   3095 		for (int k = 0; k < obj_size; ++k)
   3096 		{
   3097 			CGLTF_CHECK_KEY(tokens[i]);
   3098 
   3099 			if (cgltf_json_strcmp(tokens + i, json_chunk, "material") == 0)
   3100 			{
   3101 				++i;
   3102 				material = cgltf_json_to_int(tokens + i, json_chunk);
   3103 				++i;
   3104 			}
   3105 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "variants") == 0)
   3106 			{
   3107 				variants_tok = i+1;
   3108 				CGLTF_CHECK_TOKTYPE(tokens[variants_tok], JSMN_ARRAY);
   3109 
   3110 				i = cgltf_skip_json(tokens, i+1);
   3111 			}
   3112 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   3113 			{
   3114 				extras_tok = i + 1;
   3115 				i = cgltf_skip_json(tokens, extras_tok);
   3116 			}
   3117 			else
   3118 			{
   3119 				i = cgltf_skip_json(tokens, i+1);
   3120 			}
   3121 
   3122 			if (i < 0)
   3123 			{
   3124 				return i;
   3125 			}
   3126 		}
   3127 
   3128 		if (material < 0 || variants_tok < 0)
   3129 		{
   3130 			return CGLTF_ERROR_JSON;
   3131 		}
   3132 
   3133 		if (out_mappings)
   3134 		{
   3135 			for (int k = 0; k < tokens[variants_tok].size; ++k)
   3136 			{
   3137 				int variant = cgltf_json_to_int(&tokens[variants_tok + 1 + k], json_chunk);
   3138 				if (variant < 0)
   3139 					return variant;
   3140 
   3141 				out_mappings[*offset].material = CGLTF_PTRINDEX(cgltf_material, material);
   3142 				out_mappings[*offset].variant = variant;
   3143 
   3144 				if (extras_tok >= 0)
   3145 				{
   3146 					int e = cgltf_parse_json_extras(options, tokens, extras_tok, json_chunk, &out_mappings[*offset].extras);
   3147 					if (e < 0)
   3148 						return e;
   3149 				}
   3150 
   3151 				(*offset)++;
   3152 			}
   3153 		}
   3154 		else
   3155 		{
   3156 			(*offset) += tokens[variants_tok].size;
   3157 		}
   3158 	}
   3159 
   3160 	return i;
   3161 }
   3162 
   3163 static int cgltf_parse_json_material_mappings(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_primitive* out_prim)
   3164 {
   3165 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3166 
   3167 	int size = tokens[i].size;
   3168 	++i;
   3169 
   3170 	for (int j = 0; j < size; ++j)
   3171 	{
   3172 		CGLTF_CHECK_KEY(tokens[i]);
   3173 
   3174 		if (cgltf_json_strcmp(tokens + i, json_chunk, "mappings") == 0)
   3175 		{
   3176 			if (out_prim->mappings)
   3177 			{
   3178 				return CGLTF_ERROR_JSON;
   3179 			}
   3180 
   3181 			cgltf_size mappings_offset = 0;
   3182 			int k = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, NULL, &mappings_offset);
   3183 			if (k < 0)
   3184 			{
   3185 				return k;
   3186 			}
   3187 
   3188 			out_prim->mappings_count = mappings_offset;
   3189 			out_prim->mappings = (cgltf_material_mapping*)cgltf_calloc(options, sizeof(cgltf_material_mapping), out_prim->mappings_count);
   3190 
   3191 			mappings_offset = 0;
   3192 			i = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, out_prim->mappings, &mappings_offset);
   3193 		}
   3194 		else
   3195 		{
   3196 			i = cgltf_skip_json(tokens, i+1);
   3197 		}
   3198 
   3199 		if (i < 0)
   3200 		{
   3201 			return i;
   3202 		}
   3203 	}
   3204 
   3205 	return i;
   3206 }
   3207 
   3208 static cgltf_primitive_type cgltf_json_to_primitive_type(jsmntok_t const* tok, const uint8_t* json_chunk)
   3209 {
   3210 	int type = cgltf_json_to_int(tok, json_chunk);
   3211 
   3212 	switch (type)
   3213 	{
   3214 	case 0:
   3215 		return cgltf_primitive_type_points;
   3216 	case 1:
   3217 		return cgltf_primitive_type_lines;
   3218 	case 2:
   3219 		return cgltf_primitive_type_line_loop;
   3220 	case 3:
   3221 		return cgltf_primitive_type_line_strip;
   3222 	case 4:
   3223 		return cgltf_primitive_type_triangles;
   3224 	case 5:
   3225 		return cgltf_primitive_type_triangle_strip;
   3226 	case 6:
   3227 		return cgltf_primitive_type_triangle_fan;
   3228 	default:
   3229 		return cgltf_primitive_type_invalid;
   3230 	}
   3231 }
   3232 
   3233 static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_primitive* out_prim)
   3234 {
   3235 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3236 
   3237 	out_prim->type = cgltf_primitive_type_triangles;
   3238 
   3239 	int size = tokens[i].size;
   3240 	++i;
   3241 
   3242 	for (int j = 0; j < size; ++j)
   3243 	{
   3244 		CGLTF_CHECK_KEY(tokens[i]);
   3245 
   3246 		if (cgltf_json_strcmp(tokens+i, json_chunk, "mode") == 0)
   3247 		{
   3248 			++i;
   3249 			out_prim->type = cgltf_json_to_primitive_type(tokens+i, json_chunk);
   3250 			++i;
   3251 		}
   3252 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0)
   3253 		{
   3254 			++i;
   3255 			out_prim->indices = CGLTF_PTRINDEX(cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
   3256 			++i;
   3257 		}
   3258 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "material") == 0)
   3259 		{
   3260 			++i;
   3261 			out_prim->material = CGLTF_PTRINDEX(cgltf_material, cgltf_json_to_int(tokens + i, json_chunk));
   3262 			++i;
   3263 		}
   3264 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "attributes") == 0)
   3265 		{
   3266 			i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_prim->attributes, &out_prim->attributes_count);
   3267 		}
   3268 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "targets") == 0)
   3269 		{
   3270 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_morph_target), (void**)&out_prim->targets, &out_prim->targets_count);
   3271 			if (i < 0)
   3272 			{
   3273 				return i;
   3274 			}
   3275 
   3276 			for (cgltf_size k = 0; k < out_prim->targets_count; ++k)
   3277 			{
   3278 				i = cgltf_parse_json_attribute_list(options, tokens, i, json_chunk, &out_prim->targets[k].attributes, &out_prim->targets[k].attributes_count);
   3279 				if (i < 0)
   3280 				{
   3281 					return i;
   3282 				}
   3283 			}
   3284 		}
   3285 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   3286 		{
   3287 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_prim->extras);
   3288 		}
   3289 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   3290 		{
   3291 			++i;
   3292 
   3293 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3294 			if(out_prim->extensions)
   3295 			{
   3296 				return CGLTF_ERROR_JSON;
   3297 			}
   3298 
   3299 			int extensions_size = tokens[i].size;
   3300 			out_prim->extensions_count = 0;
   3301 			out_prim->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size);
   3302 
   3303 			if (!out_prim->extensions)
   3304 			{
   3305 				return CGLTF_ERROR_NOMEM;
   3306 			}
   3307 
   3308 			++i;
   3309 			for (int k = 0; k < extensions_size; ++k)
   3310 			{
   3311 				CGLTF_CHECK_KEY(tokens[i]);
   3312 
   3313 				if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_draco_mesh_compression") == 0)
   3314 				{
   3315 					out_prim->has_draco_mesh_compression = 1;
   3316 					i = cgltf_parse_json_draco_mesh_compression(options, tokens, i + 1, json_chunk, &out_prim->draco_mesh_compression);
   3317 				}
   3318 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_variants") == 0)
   3319 				{
   3320 					i = cgltf_parse_json_material_mappings(options, tokens, i + 1, json_chunk, out_prim);
   3321 				}
   3322 				else
   3323 				{
   3324 					i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_prim->extensions[out_prim->extensions_count++]));
   3325 				}
   3326 
   3327 				if (i < 0)
   3328 				{
   3329 					return i;
   3330 				}
   3331 			}
   3332 		}
   3333 		else
   3334 		{
   3335 			i = cgltf_skip_json(tokens, i+1);
   3336 		}
   3337 
   3338 		if (i < 0)
   3339 		{
   3340 			return i;
   3341 		}
   3342 	}
   3343 
   3344 	return i;
   3345 }
   3346 
   3347 static int cgltf_parse_json_mesh(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_mesh* out_mesh)
   3348 {
   3349 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3350 
   3351 	int size = tokens[i].size;
   3352 	++i;
   3353 
   3354 	for (int j = 0; j < size; ++j)
   3355 	{
   3356 		CGLTF_CHECK_KEY(tokens[i]);
   3357 
   3358 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   3359 		{
   3360 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_mesh->name);
   3361 		}
   3362 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "primitives") == 0)
   3363 		{
   3364 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_primitive), (void**)&out_mesh->primitives, &out_mesh->primitives_count);
   3365 			if (i < 0)
   3366 			{
   3367 				return i;
   3368 			}
   3369 
   3370 			for (cgltf_size prim_index = 0; prim_index < out_mesh->primitives_count; ++prim_index)
   3371 			{
   3372 				i = cgltf_parse_json_primitive(options, tokens, i, json_chunk, &out_mesh->primitives[prim_index]);
   3373 				if (i < 0)
   3374 				{
   3375 					return i;
   3376 				}
   3377 			}
   3378 		}
   3379 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "weights") == 0)
   3380 		{
   3381 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_float), (void**)&out_mesh->weights, &out_mesh->weights_count);
   3382 			if (i < 0)
   3383 			{
   3384 				return i;
   3385 			}
   3386 
   3387 			i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_mesh->weights, (int)out_mesh->weights_count);
   3388 		}
   3389 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   3390 		{
   3391 			++i;
   3392 
   3393 			out_mesh->extras.start_offset = tokens[i].start;
   3394 			out_mesh->extras.end_offset = tokens[i].end;
   3395 
   3396 			if (tokens[i].type == JSMN_OBJECT)
   3397 			{
   3398 				int extras_size = tokens[i].size;
   3399 				++i;
   3400 
   3401 				for (int k = 0; k < extras_size; ++k)
   3402 				{
   3403 					CGLTF_CHECK_KEY(tokens[i]);
   3404 
   3405 					if (cgltf_json_strcmp(tokens+i, json_chunk, "targetNames") == 0 && tokens[i+1].type == JSMN_ARRAY)
   3406 					{
   3407 						i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_mesh->target_names, &out_mesh->target_names_count);
   3408 					}
   3409 					else
   3410 					{
   3411 						i = cgltf_skip_json(tokens, i+1);
   3412 					}
   3413 
   3414 					if (i < 0)
   3415 					{
   3416 						return i;
   3417 					}
   3418 				}
   3419 			}
   3420 			else
   3421 			{
   3422 				i = cgltf_skip_json(tokens, i);
   3423 			}
   3424 		}
   3425 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   3426 		{
   3427 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_mesh->extensions_count, &out_mesh->extensions);
   3428 		}
   3429 		else
   3430 		{
   3431 			i = cgltf_skip_json(tokens, i+1);
   3432 		}
   3433 
   3434 		if (i < 0)
   3435 		{
   3436 			return i;
   3437 		}
   3438 	}
   3439 
   3440 	return i;
   3441 }
   3442 
   3443 static int cgltf_parse_json_meshes(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   3444 {
   3445 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_mesh), (void**)&out_data->meshes, &out_data->meshes_count);
   3446 	if (i < 0)
   3447 	{
   3448 		return i;
   3449 	}
   3450 
   3451 	for (cgltf_size j = 0; j < out_data->meshes_count; ++j)
   3452 	{
   3453 		i = cgltf_parse_json_mesh(options, tokens, i, json_chunk, &out_data->meshes[j]);
   3454 		if (i < 0)
   3455 		{
   3456 			return i;
   3457 		}
   3458 	}
   3459 	return i;
   3460 }
   3461 
   3462 static cgltf_component_type cgltf_json_to_component_type(jsmntok_t const* tok, const uint8_t* json_chunk)
   3463 {
   3464 	int type = cgltf_json_to_int(tok, json_chunk);
   3465 
   3466 	switch (type)
   3467 	{
   3468 	case 5120:
   3469 		return cgltf_component_type_r_8;
   3470 	case 5121:
   3471 		return cgltf_component_type_r_8u;
   3472 	case 5122:
   3473 		return cgltf_component_type_r_16;
   3474 	case 5123:
   3475 		return cgltf_component_type_r_16u;
   3476 	case 5125:
   3477 		return cgltf_component_type_r_32u;
   3478 	case 5126:
   3479 		return cgltf_component_type_r_32f;
   3480 	default:
   3481 		return cgltf_component_type_invalid;
   3482 	}
   3483 }
   3484 
   3485 static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor_sparse* out_sparse)
   3486 {
   3487 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3488 
   3489 	int size = tokens[i].size;
   3490 	++i;
   3491 
   3492 	for (int j = 0; j < size; ++j)
   3493 	{
   3494 		CGLTF_CHECK_KEY(tokens[i]);
   3495 
   3496 		if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0)
   3497 		{
   3498 			++i;
   3499 			out_sparse->count = cgltf_json_to_size(tokens + i, json_chunk);
   3500 			++i;
   3501 		}
   3502 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0)
   3503 		{
   3504 			++i;
   3505 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3506 
   3507 			int indices_size = tokens[i].size;
   3508 			++i;
   3509 
   3510 			for (int k = 0; k < indices_size; ++k)
   3511 			{
   3512 				CGLTF_CHECK_KEY(tokens[i]);
   3513 
   3514 				if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
   3515 				{
   3516 					++i;
   3517 					out_sparse->indices_buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
   3518 					++i;
   3519 				}
   3520 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
   3521 				{
   3522 					++i;
   3523 					out_sparse->indices_byte_offset = cgltf_json_to_size(tokens + i, json_chunk);
   3524 					++i;
   3525 				}
   3526 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "componentType") == 0)
   3527 				{
   3528 					++i;
   3529 					out_sparse->indices_component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
   3530 					++i;
   3531 				}
   3532 				else
   3533 				{
   3534 					i = cgltf_skip_json(tokens, i+1);
   3535 				}
   3536 
   3537 				if (i < 0)
   3538 				{
   3539 					return i;
   3540 				}
   3541 			}
   3542 		}
   3543 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "values") == 0)
   3544 		{
   3545 			++i;
   3546 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3547 
   3548 			int values_size = tokens[i].size;
   3549 			++i;
   3550 
   3551 			for (int k = 0; k < values_size; ++k)
   3552 			{
   3553 				CGLTF_CHECK_KEY(tokens[i]);
   3554 
   3555 				if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
   3556 				{
   3557 					++i;
   3558 					out_sparse->values_buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
   3559 					++i;
   3560 				}
   3561 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
   3562 				{
   3563 					++i;
   3564 					out_sparse->values_byte_offset = cgltf_json_to_size(tokens + i, json_chunk);
   3565 					++i;
   3566 				}
   3567 				else
   3568 				{
   3569 					i = cgltf_skip_json(tokens, i+1);
   3570 				}
   3571 
   3572 				if (i < 0)
   3573 				{
   3574 					return i;
   3575 				}
   3576 			}
   3577 		}
   3578 		else
   3579 		{
   3580 			i = cgltf_skip_json(tokens, i+1);
   3581 		}
   3582 
   3583 		if (i < 0)
   3584 		{
   3585 			return i;
   3586 		}
   3587 	}
   3588 
   3589 	return i;
   3590 }
   3591 
   3592 static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor* out_accessor)
   3593 {
   3594 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3595 
   3596 	int size = tokens[i].size;
   3597 	++i;
   3598 
   3599 	for (int j = 0; j < size; ++j)
   3600 	{
   3601 		CGLTF_CHECK_KEY(tokens[i]);
   3602 
   3603 		if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
   3604 		{
   3605 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_accessor->name);
   3606 		}
   3607 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
   3608 		{
   3609 			++i;
   3610 			out_accessor->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
   3611 			++i;
   3612 		}
   3613 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
   3614 		{
   3615 			++i;
   3616 			out_accessor->offset =
   3617 					cgltf_json_to_size(tokens+i, json_chunk);
   3618 			++i;
   3619 		}
   3620 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "componentType") == 0)
   3621 		{
   3622 			++i;
   3623 			out_accessor->component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
   3624 			++i;
   3625 		}
   3626 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "normalized") == 0)
   3627 		{
   3628 			++i;
   3629 			out_accessor->normalized = cgltf_json_to_bool(tokens+i, json_chunk);
   3630 			++i;
   3631 		}
   3632 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0)
   3633 		{
   3634 			++i;
   3635 			out_accessor->count = cgltf_json_to_size(tokens+i, json_chunk);
   3636 			++i;
   3637 		}
   3638 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "type") == 0)
   3639 		{
   3640 			++i;
   3641 			if (cgltf_json_strcmp(tokens+i, json_chunk, "SCALAR") == 0)
   3642 			{
   3643 				out_accessor->type = cgltf_type_scalar;
   3644 			}
   3645 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "VEC2") == 0)
   3646 			{
   3647 				out_accessor->type = cgltf_type_vec2;
   3648 			}
   3649 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "VEC3") == 0)
   3650 			{
   3651 				out_accessor->type = cgltf_type_vec3;
   3652 			}
   3653 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "VEC4") == 0)
   3654 			{
   3655 				out_accessor->type = cgltf_type_vec4;
   3656 			}
   3657 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "MAT2") == 0)
   3658 			{
   3659 				out_accessor->type = cgltf_type_mat2;
   3660 			}
   3661 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "MAT3") == 0)
   3662 			{
   3663 				out_accessor->type = cgltf_type_mat3;
   3664 			}
   3665 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "MAT4") == 0)
   3666 			{
   3667 				out_accessor->type = cgltf_type_mat4;
   3668 			}
   3669 			++i;
   3670 		}
   3671 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "min") == 0)
   3672 		{
   3673 			++i;
   3674 			out_accessor->has_min = 1;
   3675 			// note: we can't parse the precise number of elements since type may not have been computed yet
   3676 			int min_size = tokens[i].size > 16 ? 16 : tokens[i].size;
   3677 			i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->min, min_size);
   3678 		}
   3679 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "max") == 0)
   3680 		{
   3681 			++i;
   3682 			out_accessor->has_max = 1;
   3683 			// note: we can't parse the precise number of elements since type may not have been computed yet
   3684 			int max_size = tokens[i].size > 16 ? 16 : tokens[i].size;
   3685 			i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->max, max_size);
   3686 		}
   3687 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "sparse") == 0)
   3688 		{
   3689 			out_accessor->is_sparse = 1;
   3690 			i = cgltf_parse_json_accessor_sparse(tokens, i + 1, json_chunk, &out_accessor->sparse);
   3691 		}
   3692 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   3693 		{
   3694 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_accessor->extras);
   3695 		}
   3696 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   3697 		{
   3698 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_accessor->extensions_count, &out_accessor->extensions);
   3699 		}
   3700 		else
   3701 		{
   3702 			i = cgltf_skip_json(tokens, i+1);
   3703 		}
   3704 
   3705 		if (i < 0)
   3706 		{
   3707 			return i;
   3708 		}
   3709 	}
   3710 
   3711 	return i;
   3712 }
   3713 
   3714 static int cgltf_parse_json_texture_transform(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture_transform* out_texture_transform)
   3715 {
   3716 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3717 
   3718 	int size = tokens[i].size;
   3719 	++i;
   3720 
   3721 	for (int j = 0; j < size; ++j)
   3722 	{
   3723 		CGLTF_CHECK_KEY(tokens[i]);
   3724 
   3725 		if (cgltf_json_strcmp(tokens + i, json_chunk, "offset") == 0)
   3726 		{
   3727 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->offset, 2);
   3728 		}
   3729 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "rotation") == 0)
   3730 		{
   3731 			++i;
   3732 			out_texture_transform->rotation = cgltf_json_to_float(tokens + i, json_chunk);
   3733 			++i;
   3734 		}
   3735 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0)
   3736 		{
   3737 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->scale, 2);
   3738 		}
   3739 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "texCoord") == 0)
   3740 		{
   3741 			++i;
   3742 			out_texture_transform->has_texcoord = 1;
   3743 			out_texture_transform->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
   3744 			++i;
   3745 		}
   3746 		else
   3747 		{
   3748 			i = cgltf_skip_json(tokens, i + 1);
   3749 		}
   3750 
   3751 		if (i < 0)
   3752 		{
   3753 			return i;
   3754 		}
   3755 	}
   3756 
   3757 	return i;
   3758 }
   3759 
   3760 static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture_view* out_texture_view)
   3761 {
   3762 	(void)options;
   3763 
   3764 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3765 
   3766 	out_texture_view->scale = 1.0f;
   3767 	cgltf_fill_float_array(out_texture_view->transform.scale, 2, 1.0f);
   3768 
   3769 	int size = tokens[i].size;
   3770 	++i;
   3771 
   3772 	for (int j = 0; j < size; ++j)
   3773 	{
   3774 		CGLTF_CHECK_KEY(tokens[i]);
   3775 
   3776 		if (cgltf_json_strcmp(tokens + i, json_chunk, "index") == 0)
   3777 		{
   3778 			++i;
   3779 			out_texture_view->texture = CGLTF_PTRINDEX(cgltf_texture, cgltf_json_to_int(tokens + i, json_chunk));
   3780 			++i;
   3781 		}
   3782 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "texCoord") == 0)
   3783 		{
   3784 			++i;
   3785 			out_texture_view->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
   3786 			++i;
   3787 		}
   3788 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0)
   3789 		{
   3790 			++i;
   3791 			out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
   3792 			++i;
   3793 		}
   3794 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "strength") == 0)
   3795 		{
   3796 			++i;
   3797 			out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
   3798 			++i;
   3799 		}
   3800 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   3801 		{
   3802 			++i;
   3803 
   3804 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3805 			int extensions_size = tokens[i].size;
   3806 
   3807 			++i;
   3808 
   3809 			for (int k = 0; k < extensions_size; ++k)
   3810 			{
   3811 				CGLTF_CHECK_KEY(tokens[i]);
   3812 
   3813 				if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_texture_transform") == 0)
   3814 				{
   3815 					out_texture_view->has_transform = 1;
   3816 					i = cgltf_parse_json_texture_transform(tokens, i + 1, json_chunk, &out_texture_view->transform);
   3817 				}
   3818 				else
   3819 				{
   3820 					i = cgltf_skip_json(tokens, i + 1);
   3821 				}
   3822 
   3823 				if (i < 0)
   3824 				{
   3825 					return i;
   3826 				}
   3827 			}
   3828 		}
   3829 		else
   3830 		{
   3831 			i = cgltf_skip_json(tokens, i + 1);
   3832 		}
   3833 
   3834 		if (i < 0)
   3835 		{
   3836 			return i;
   3837 		}
   3838 	}
   3839 
   3840 	return i;
   3841 }
   3842 
   3843 static int cgltf_parse_json_pbr_metallic_roughness(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_pbr_metallic_roughness* out_pbr)
   3844 {
   3845 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3846 
   3847 	int size = tokens[i].size;
   3848 	++i;
   3849 
   3850 	for (int j = 0; j < size; ++j)
   3851 	{
   3852 		CGLTF_CHECK_KEY(tokens[i]);
   3853 
   3854 		if (cgltf_json_strcmp(tokens+i, json_chunk, "metallicFactor") == 0)
   3855 		{
   3856 			++i;
   3857 			out_pbr->metallic_factor =
   3858 				cgltf_json_to_float(tokens + i, json_chunk);
   3859 			++i;
   3860 		}
   3861 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0)
   3862 		{
   3863 			++i;
   3864 			out_pbr->roughness_factor =
   3865 				cgltf_json_to_float(tokens+i, json_chunk);
   3866 			++i;
   3867 		}
   3868 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "baseColorFactor") == 0)
   3869 		{
   3870 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->base_color_factor, 4);
   3871 		}
   3872 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "baseColorTexture") == 0)
   3873 		{
   3874 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->base_color_texture);
   3875 		}
   3876 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "metallicRoughnessTexture") == 0)
   3877 		{
   3878 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->metallic_roughness_texture);
   3879 		}
   3880 		else
   3881 		{
   3882 			i = cgltf_skip_json(tokens, i+1);
   3883 		}
   3884 
   3885 		if (i < 0)
   3886 		{
   3887 			return i;
   3888 		}
   3889 	}
   3890 
   3891 	return i;
   3892 }
   3893 
   3894 static int cgltf_parse_json_pbr_specular_glossiness(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_pbr_specular_glossiness* out_pbr)
   3895 {
   3896 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3897 	int size = tokens[i].size;
   3898 	++i;
   3899 
   3900 	for (int j = 0; j < size; ++j)
   3901 	{
   3902 		CGLTF_CHECK_KEY(tokens[i]);
   3903 
   3904 		if (cgltf_json_strcmp(tokens+i, json_chunk, "diffuseFactor") == 0)
   3905 		{
   3906 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->diffuse_factor, 4);
   3907 		}
   3908 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "specularFactor") == 0)
   3909 		{
   3910 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->specular_factor, 3);
   3911 		}
   3912 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "glossinessFactor") == 0)
   3913 		{
   3914 			++i;
   3915 			out_pbr->glossiness_factor = cgltf_json_to_float(tokens + i, json_chunk);
   3916 			++i;
   3917 		}
   3918 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "diffuseTexture") == 0)
   3919 		{
   3920 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->diffuse_texture);
   3921 		}
   3922 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "specularGlossinessTexture") == 0)
   3923 		{
   3924 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->specular_glossiness_texture);
   3925 		}
   3926 		else
   3927 		{
   3928 			i = cgltf_skip_json(tokens, i+1);
   3929 		}
   3930 
   3931 		if (i < 0)
   3932 		{
   3933 			return i;
   3934 		}
   3935 	}
   3936 
   3937 	return i;
   3938 }
   3939 
   3940 static int cgltf_parse_json_clearcoat(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_clearcoat* out_clearcoat)
   3941 {
   3942 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3943 	int size = tokens[i].size;
   3944 	++i;
   3945 
   3946 	for (int j = 0; j < size; ++j)
   3947 	{
   3948 		CGLTF_CHECK_KEY(tokens[i]);
   3949 
   3950 		if (cgltf_json_strcmp(tokens+i, json_chunk, "clearcoatFactor") == 0)
   3951 		{
   3952 			++i;
   3953 			out_clearcoat->clearcoat_factor = cgltf_json_to_float(tokens + i, json_chunk);
   3954 			++i;
   3955 		}
   3956 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "clearcoatRoughnessFactor") == 0)
   3957 		{
   3958 			++i;
   3959 			out_clearcoat->clearcoat_roughness_factor = cgltf_json_to_float(tokens + i, json_chunk);
   3960 			++i;
   3961 		}
   3962 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "clearcoatTexture") == 0)
   3963 		{
   3964 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_texture);
   3965 		}
   3966 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "clearcoatRoughnessTexture") == 0)
   3967 		{
   3968 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_roughness_texture);
   3969 		}
   3970 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "clearcoatNormalTexture") == 0)
   3971 		{
   3972 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_normal_texture);
   3973 		}
   3974 		else
   3975 		{
   3976 			i = cgltf_skip_json(tokens, i+1);
   3977 		}
   3978 
   3979 		if (i < 0)
   3980 		{
   3981 			return i;
   3982 		}
   3983 	}
   3984 
   3985 	return i;
   3986 }
   3987 
   3988 static int cgltf_parse_json_ior(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_ior* out_ior)
   3989 {
   3990 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3991 	int size = tokens[i].size;
   3992 	++i;
   3993 
   3994 	// Default values
   3995 	out_ior->ior = 1.5f;
   3996 
   3997 	for (int j = 0; j < size; ++j)
   3998 	{
   3999 		CGLTF_CHECK_KEY(tokens[i]);
   4000 
   4001 		if (cgltf_json_strcmp(tokens+i, json_chunk, "ior") == 0)
   4002 		{
   4003 			++i;
   4004 			out_ior->ior = cgltf_json_to_float(tokens + i, json_chunk);
   4005 			++i;
   4006 		}
   4007 		else
   4008 		{
   4009 			i = cgltf_skip_json(tokens, i+1);
   4010 		}
   4011 
   4012 		if (i < 0)
   4013 		{
   4014 			return i;
   4015 		}
   4016 	}
   4017 
   4018 	return i;
   4019 }
   4020 
   4021 static int cgltf_parse_json_specular(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_specular* out_specular)
   4022 {
   4023 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4024 	int size = tokens[i].size;
   4025 	++i;
   4026 
   4027 	// Default values
   4028 	out_specular->specular_factor = 1.0f;
   4029 	cgltf_fill_float_array(out_specular->specular_color_factor, 3, 1.0f);
   4030 
   4031 	for (int j = 0; j < size; ++j)
   4032 	{
   4033 		CGLTF_CHECK_KEY(tokens[i]);
   4034 
   4035 		if (cgltf_json_strcmp(tokens+i, json_chunk, "specularFactor") == 0)
   4036 		{
   4037 			++i;
   4038 			out_specular->specular_factor = cgltf_json_to_float(tokens + i, json_chunk);
   4039 			++i;
   4040 		}
   4041 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "specularColorFactor") == 0)
   4042 		{
   4043 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_specular->specular_color_factor, 3);
   4044 		}
   4045 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "specularTexture") == 0)
   4046 		{
   4047 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_texture);
   4048 		}
   4049 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "specularColorTexture") == 0)
   4050 		{
   4051 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_color_texture);
   4052 		}
   4053 		else
   4054 		{
   4055 			i = cgltf_skip_json(tokens, i+1);
   4056 		}
   4057 
   4058 		if (i < 0)
   4059 		{
   4060 			return i;
   4061 		}
   4062 	}
   4063 
   4064 	return i;
   4065 }
   4066 
   4067 static int cgltf_parse_json_transmission(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_transmission* out_transmission)
   4068 {
   4069 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4070 	int size = tokens[i].size;
   4071 	++i;
   4072 
   4073 	for (int j = 0; j < size; ++j)
   4074 	{
   4075 		CGLTF_CHECK_KEY(tokens[i]);
   4076 
   4077 		if (cgltf_json_strcmp(tokens+i, json_chunk, "transmissionFactor") == 0)
   4078 		{
   4079 			++i;
   4080 			out_transmission->transmission_factor = cgltf_json_to_float(tokens + i, json_chunk);
   4081 			++i;
   4082 		}
   4083 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "transmissionTexture") == 0)
   4084 		{
   4085 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_transmission->transmission_texture);
   4086 		}
   4087 		else
   4088 		{
   4089 			i = cgltf_skip_json(tokens, i+1);
   4090 		}
   4091 
   4092 		if (i < 0)
   4093 		{
   4094 			return i;
   4095 		}
   4096 	}
   4097 
   4098 	return i;
   4099 }
   4100 
   4101 static int cgltf_parse_json_volume(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_volume* out_volume)
   4102 {
   4103 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4104 	int size = tokens[i].size;
   4105 	++i;
   4106 
   4107 	for (int j = 0; j < size; ++j)
   4108 	{
   4109 		CGLTF_CHECK_KEY(tokens[i]);
   4110 
   4111 		if (cgltf_json_strcmp(tokens + i, json_chunk, "thicknessFactor") == 0)
   4112 		{
   4113 			++i;
   4114 			out_volume->thickness_factor = cgltf_json_to_float(tokens + i, json_chunk);
   4115 			++i;
   4116 		}
   4117 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "thicknessTexture") == 0)
   4118 		{
   4119 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_volume->thickness_texture);
   4120 		}
   4121 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "attenuationColor") == 0)
   4122 		{
   4123 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_volume->attenuation_color, 3);
   4124 		}
   4125 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "attenuationDistance") == 0)
   4126 		{
   4127 			++i;
   4128 			out_volume->attenuation_distance = cgltf_json_to_float(tokens + i, json_chunk);
   4129 			++i;
   4130 		}
   4131 		else
   4132 		{
   4133 			i = cgltf_skip_json(tokens, i + 1);
   4134 		}
   4135 
   4136 		if (i < 0)
   4137 		{
   4138 			return i;
   4139 		}
   4140 	}
   4141 
   4142 	return i;
   4143 }
   4144 
   4145 static int cgltf_parse_json_sheen(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_sheen* out_sheen)
   4146 {
   4147 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4148 	int size = tokens[i].size;
   4149 	++i;
   4150 
   4151 	for (int j = 0; j < size; ++j)
   4152 	{
   4153 		CGLTF_CHECK_KEY(tokens[i]);
   4154 
   4155 		if (cgltf_json_strcmp(tokens+i, json_chunk, "sheenColorFactor") == 0)
   4156 		{
   4157 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_sheen->sheen_color_factor, 3);
   4158 		}
   4159 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "sheenColorTexture") == 0)
   4160 		{
   4161 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_sheen->sheen_color_texture);
   4162 		}
   4163 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "sheenRoughnessFactor") == 0)
   4164 		{
   4165 			++i;
   4166 			out_sheen->sheen_roughness_factor = cgltf_json_to_float(tokens + i, json_chunk);
   4167 			++i;
   4168 		}
   4169 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "sheenRoughnessTexture") == 0)
   4170 		{
   4171 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_sheen->sheen_roughness_texture);
   4172 		}
   4173 		else
   4174 		{
   4175 			i = cgltf_skip_json(tokens, i+1);
   4176 		}
   4177 
   4178 		if (i < 0)
   4179 		{
   4180 			return i;
   4181 		}
   4182 	}
   4183 
   4184 	return i;
   4185 }
   4186 
   4187 static int cgltf_parse_json_emissive_strength(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_emissive_strength* out_emissive_strength)
   4188 {
   4189 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4190 	int size = tokens[i].size;
   4191 	++i;
   4192 
   4193 	// Default
   4194 	out_emissive_strength->emissive_strength = 1.f;
   4195 
   4196 	for (int j = 0; j < size; ++j)
   4197 	{
   4198 		CGLTF_CHECK_KEY(tokens[i]);
   4199 
   4200 		if (cgltf_json_strcmp(tokens + i, json_chunk, "emissiveStrength") == 0)
   4201 		{
   4202 			++i;
   4203 			out_emissive_strength->emissive_strength = cgltf_json_to_float(tokens + i, json_chunk);
   4204 			++i;
   4205 		}
   4206 		else
   4207 		{
   4208 			i = cgltf_skip_json(tokens, i + 1);
   4209 		}
   4210 
   4211 		if (i < 0)
   4212 		{
   4213 			return i;
   4214 		}
   4215 	}
   4216 
   4217 	return i;
   4218 }
   4219 
   4220 static int cgltf_parse_json_iridescence(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_iridescence* out_iridescence)
   4221 {
   4222 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4223 	int size = tokens[i].size;
   4224 	++i;
   4225 
   4226 	// Default
   4227 	out_iridescence->iridescence_ior = 1.3f;
   4228 	out_iridescence->iridescence_thickness_min = 100.f;
   4229 	out_iridescence->iridescence_thickness_max = 400.f;
   4230 
   4231 	for (int j = 0; j < size; ++j)
   4232 	{
   4233 		CGLTF_CHECK_KEY(tokens[i]);
   4234 
   4235 		if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceFactor") == 0)
   4236 		{
   4237 			++i;
   4238 			out_iridescence->iridescence_factor = cgltf_json_to_float(tokens + i, json_chunk);
   4239 			++i;
   4240 		}
   4241 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceTexture") == 0)
   4242 		{
   4243 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_iridescence->iridescence_texture);
   4244 		}
   4245 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceIor") == 0)
   4246 		{
   4247 			++i;
   4248 			out_iridescence->iridescence_ior = cgltf_json_to_float(tokens + i, json_chunk);
   4249 			++i;
   4250 		}
   4251 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceThicknessMinimum") == 0)
   4252 		{
   4253 			++i;
   4254 			out_iridescence->iridescence_thickness_min = cgltf_json_to_float(tokens + i, json_chunk);
   4255 			++i;
   4256 		}
   4257 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceThicknessMaximum") == 0)
   4258 		{
   4259 			++i;
   4260 			out_iridescence->iridescence_thickness_max = cgltf_json_to_float(tokens + i, json_chunk);
   4261 			++i;
   4262 		}
   4263 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceThicknessTexture") == 0)
   4264 		{
   4265 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_iridescence->iridescence_thickness_texture);
   4266 		}
   4267 		else
   4268 		{
   4269 			i = cgltf_skip_json(tokens, i + 1);
   4270 		}
   4271 
   4272 		if (i < 0)
   4273 		{
   4274 			return i;
   4275 		}
   4276 	}
   4277 
   4278 	return i;
   4279 }
   4280 
   4281 static int cgltf_parse_json_anisotropy(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_anisotropy* out_anisotropy)
   4282 {
   4283 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4284 	int size = tokens[i].size;
   4285 	++i;
   4286 
   4287 
   4288 	for (int j = 0; j < size; ++j)
   4289 	{
   4290 		CGLTF_CHECK_KEY(tokens[i]);
   4291 
   4292 		if (cgltf_json_strcmp(tokens + i, json_chunk, "anisotropyStrength") == 0)
   4293 		{
   4294 			++i;
   4295 			out_anisotropy->anisotropy_strength = cgltf_json_to_float(tokens + i, json_chunk);
   4296 			++i;
   4297 		}
   4298 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "anisotropyRotation") == 0)
   4299 		{
   4300 			++i;
   4301 			out_anisotropy->anisotropy_rotation = cgltf_json_to_float(tokens + i, json_chunk);
   4302 			++i;
   4303 		}
   4304 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "anisotropyTexture") == 0)
   4305 		{
   4306 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_anisotropy->anisotropy_texture);
   4307 		}
   4308 		else
   4309 		{
   4310 			i = cgltf_skip_json(tokens, i + 1);
   4311 		}
   4312 
   4313 		if (i < 0)
   4314 		{
   4315 			return i;
   4316 		}
   4317 	}
   4318 
   4319 	return i;
   4320 }
   4321 
   4322 static int cgltf_parse_json_dispersion(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_dispersion* out_dispersion)
   4323 {
   4324 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4325 	int size = tokens[i].size;
   4326 	++i;
   4327 
   4328 
   4329 	for (int j = 0; j < size; ++j)
   4330 	{
   4331 		CGLTF_CHECK_KEY(tokens[i]);
   4332 
   4333 		if (cgltf_json_strcmp(tokens + i, json_chunk, "dispersion") == 0)
   4334 		{
   4335 			++i;
   4336 			out_dispersion->dispersion = cgltf_json_to_float(tokens + i, json_chunk);
   4337 			++i;
   4338 		}
   4339 		else
   4340 		{
   4341 			i = cgltf_skip_json(tokens, i + 1);
   4342 		}
   4343 
   4344 		if (i < 0)
   4345 		{
   4346 			return i;
   4347 		}
   4348 	}
   4349 
   4350 	return i;
   4351 }
   4352 
   4353 static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_image* out_image)
   4354 {
   4355 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4356 
   4357 	int size = tokens[i].size;
   4358 	++i;
   4359 
   4360 	for (int j = 0; j < size; ++j)
   4361 	{
   4362 		CGLTF_CHECK_KEY(tokens[i]);
   4363 
   4364 		if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0)
   4365 		{
   4366 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->uri);
   4367 		}
   4368 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
   4369 		{
   4370 			++i;
   4371 			out_image->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
   4372 			++i;
   4373 		}
   4374 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "mimeType") == 0)
   4375 		{
   4376 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->mime_type);
   4377 		}
   4378 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
   4379 		{
   4380 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->name);
   4381 		}
   4382 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   4383 		{
   4384 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_image->extras);
   4385 		}
   4386 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   4387 		{
   4388 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_image->extensions_count, &out_image->extensions);
   4389 		}
   4390 		else
   4391 		{
   4392 			i = cgltf_skip_json(tokens, i + 1);
   4393 		}
   4394 
   4395 		if (i < 0)
   4396 		{
   4397 			return i;
   4398 		}
   4399 	}
   4400 
   4401 	return i;
   4402 }
   4403 
   4404 static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_sampler* out_sampler)
   4405 {
   4406 	(void)options;
   4407 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4408 
   4409 	out_sampler->wrap_s = 10497;
   4410 	out_sampler->wrap_t = 10497;
   4411 
   4412 	int size = tokens[i].size;
   4413 	++i;
   4414 
   4415 	for (int j = 0; j < size; ++j)
   4416 	{
   4417 		CGLTF_CHECK_KEY(tokens[i]);
   4418 
   4419 		if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
   4420 		{
   4421 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_sampler->name);
   4422 		}
   4423 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "magFilter") == 0)
   4424 		{
   4425 			++i;
   4426 			out_sampler->mag_filter
   4427 				= cgltf_json_to_int(tokens + i, json_chunk);
   4428 			++i;
   4429 		}
   4430 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "minFilter") == 0)
   4431 		{
   4432 			++i;
   4433 			out_sampler->min_filter
   4434 				= cgltf_json_to_int(tokens + i, json_chunk);
   4435 			++i;
   4436 		}
   4437 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapS") == 0)
   4438 		{
   4439 			++i;
   4440 			out_sampler->wrap_s
   4441 				= cgltf_json_to_int(tokens + i, json_chunk);
   4442 			++i;
   4443 		}
   4444 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0)
   4445 		{
   4446 			++i;
   4447 			out_sampler->wrap_t
   4448 				= cgltf_json_to_int(tokens + i, json_chunk);
   4449 			++i;
   4450 		}
   4451 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   4452 		{
   4453 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sampler->extras);
   4454 		}
   4455 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   4456 		{
   4457 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->extensions_count, &out_sampler->extensions);
   4458 		}
   4459 		else
   4460 		{
   4461 			i = cgltf_skip_json(tokens, i + 1);
   4462 		}
   4463 
   4464 		if (i < 0)
   4465 		{
   4466 			return i;
   4467 		}
   4468 	}
   4469 
   4470 	return i;
   4471 }
   4472 
   4473 static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture* out_texture)
   4474 {
   4475 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4476 
   4477 	int size = tokens[i].size;
   4478 	++i;
   4479 
   4480 	for (int j = 0; j < size; ++j)
   4481 	{
   4482 		CGLTF_CHECK_KEY(tokens[i]);
   4483 
   4484 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   4485 		{
   4486 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_texture->name);
   4487 		}
   4488 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "sampler") == 0)
   4489 		{
   4490 			++i;
   4491 			out_texture->sampler = CGLTF_PTRINDEX(cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk));
   4492 			++i;
   4493 		}
   4494 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0)
   4495 		{
   4496 			++i;
   4497 			out_texture->image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
   4498 			++i;
   4499 		}
   4500 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   4501 		{
   4502 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_texture->extras);
   4503 		}
   4504 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   4505 		{
   4506 			++i;
   4507 
   4508 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4509 			if (out_texture->extensions)
   4510 			{
   4511 				return CGLTF_ERROR_JSON;
   4512 			}
   4513 
   4514 			int extensions_size = tokens[i].size;
   4515 			++i;
   4516 			out_texture->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size);
   4517 			out_texture->extensions_count = 0;
   4518 
   4519 			if (!out_texture->extensions)
   4520 			{
   4521 				return CGLTF_ERROR_NOMEM;
   4522 			}
   4523 
   4524 			for (int k = 0; k < extensions_size; ++k)
   4525 			{
   4526 				CGLTF_CHECK_KEY(tokens[i]);
   4527 
   4528 				if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_texture_basisu") == 0)
   4529 				{
   4530 					out_texture->has_basisu = 1;
   4531 					++i;
   4532 					CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4533 					int num_properties = tokens[i].size;
   4534 					++i;
   4535 
   4536 					for (int t = 0; t < num_properties; ++t)
   4537 					{
   4538 						CGLTF_CHECK_KEY(tokens[i]);
   4539 
   4540 						if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0)
   4541 						{
   4542 							++i;
   4543 							out_texture->basisu_image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
   4544 							++i;
   4545 						}
   4546 						else
   4547 						{
   4548 							i = cgltf_skip_json(tokens, i + 1);
   4549 						}
   4550 						if (i < 0)
   4551 						{
   4552 							return i;
   4553 						}
   4554 					}
   4555 				}
   4556 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "EXT_texture_webp") == 0)
   4557 				{
   4558 					out_texture->has_webp = 1;
   4559 					++i;
   4560 					CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4561 					int num_properties = tokens[i].size;
   4562 					++i;
   4563 
   4564 					for (int t = 0; t < num_properties; ++t)
   4565 					{
   4566 						CGLTF_CHECK_KEY(tokens[i]);
   4567 
   4568 						if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0)
   4569 						{
   4570 							++i;
   4571 							out_texture->webp_image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
   4572 							++i;
   4573 						}
   4574 						else
   4575 						{
   4576 							i = cgltf_skip_json(tokens, i + 1);
   4577 						}
   4578 						if (i < 0)
   4579 						{
   4580 							return i;
   4581 						}
   4582 					}
   4583 				}
   4584 				else
   4585 				{
   4586 					i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture->extensions[out_texture->extensions_count++]));
   4587 				}
   4588 
   4589 				if (i < 0)
   4590 				{
   4591 					return i;
   4592 				}
   4593 			}
   4594 		}
   4595 		else
   4596 		{
   4597 			i = cgltf_skip_json(tokens, i + 1);
   4598 		}
   4599 
   4600 		if (i < 0)
   4601 		{
   4602 			return i;
   4603 		}
   4604 	}
   4605 
   4606 	return i;
   4607 }
   4608 
   4609 static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_material* out_material)
   4610 {
   4611 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4612 
   4613 	cgltf_fill_float_array(out_material->pbr_metallic_roughness.base_color_factor, 4, 1.0f);
   4614 	out_material->pbr_metallic_roughness.metallic_factor = 1.0f;
   4615 	out_material->pbr_metallic_roughness.roughness_factor = 1.0f;
   4616 
   4617 	cgltf_fill_float_array(out_material->pbr_specular_glossiness.diffuse_factor, 4, 1.0f);
   4618 	cgltf_fill_float_array(out_material->pbr_specular_glossiness.specular_factor, 3, 1.0f);
   4619 	out_material->pbr_specular_glossiness.glossiness_factor = 1.0f;
   4620 
   4621 	cgltf_fill_float_array(out_material->volume.attenuation_color, 3, 1.0f);
   4622 	out_material->volume.attenuation_distance = FLT_MAX;
   4623 
   4624 	out_material->alpha_cutoff = 0.5f;
   4625 
   4626 	int size = tokens[i].size;
   4627 	++i;
   4628 
   4629 	for (int j = 0; j < size; ++j)
   4630 	{
   4631 		CGLTF_CHECK_KEY(tokens[i]);
   4632 
   4633 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   4634 		{
   4635 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_material->name);
   4636 		}
   4637 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "pbrMetallicRoughness") == 0)
   4638 		{
   4639 			out_material->has_pbr_metallic_roughness = 1;
   4640 			i = cgltf_parse_json_pbr_metallic_roughness(options, tokens, i + 1, json_chunk, &out_material->pbr_metallic_roughness);
   4641 		}
   4642 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "emissiveFactor") == 0)
   4643 		{
   4644 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_material->emissive_factor, 3);
   4645 		}
   4646 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "normalTexture") == 0)
   4647 		{
   4648 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
   4649 				&out_material->normal_texture);
   4650 		}
   4651 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "occlusionTexture") == 0)
   4652 		{
   4653 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
   4654 				&out_material->occlusion_texture);
   4655 		}
   4656 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "emissiveTexture") == 0)
   4657 		{
   4658 			i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
   4659 				&out_material->emissive_texture);
   4660 		}
   4661 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "alphaMode") == 0)
   4662 		{
   4663 			++i;
   4664 			if (cgltf_json_strcmp(tokens + i, json_chunk, "OPAQUE") == 0)
   4665 			{
   4666 				out_material->alpha_mode = cgltf_alpha_mode_opaque;
   4667 			}
   4668 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "MASK") == 0)
   4669 			{
   4670 				out_material->alpha_mode = cgltf_alpha_mode_mask;
   4671 			}
   4672 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "BLEND") == 0)
   4673 			{
   4674 				out_material->alpha_mode = cgltf_alpha_mode_blend;
   4675 			}
   4676 			++i;
   4677 		}
   4678 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "alphaCutoff") == 0)
   4679 		{
   4680 			++i;
   4681 			out_material->alpha_cutoff = cgltf_json_to_float(tokens + i, json_chunk);
   4682 			++i;
   4683 		}
   4684 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "doubleSided") == 0)
   4685 		{
   4686 			++i;
   4687 			out_material->double_sided =
   4688 				cgltf_json_to_bool(tokens + i, json_chunk);
   4689 			++i;
   4690 		}
   4691 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   4692 		{
   4693 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_material->extras);
   4694 		}
   4695 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   4696 		{
   4697 			++i;
   4698 
   4699 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4700 			if(out_material->extensions)
   4701 			{
   4702 				return CGLTF_ERROR_JSON;
   4703 			}
   4704 
   4705 			int extensions_size = tokens[i].size;
   4706 			++i;
   4707 			out_material->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size);
   4708 			out_material->extensions_count= 0;
   4709 
   4710 			if (!out_material->extensions)
   4711 			{
   4712 				return CGLTF_ERROR_NOMEM;
   4713 			}
   4714 
   4715 			for (int k = 0; k < extensions_size; ++k)
   4716 			{
   4717 				CGLTF_CHECK_KEY(tokens[i]);
   4718 
   4719 				if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_pbrSpecularGlossiness") == 0)
   4720 				{
   4721 					out_material->has_pbr_specular_glossiness = 1;
   4722 					i = cgltf_parse_json_pbr_specular_glossiness(options, tokens, i + 1, json_chunk, &out_material->pbr_specular_glossiness);
   4723 				}
   4724 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_unlit") == 0)
   4725 				{
   4726 					out_material->unlit = 1;
   4727 					i = cgltf_skip_json(tokens, i+1);
   4728 				}
   4729 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_clearcoat") == 0)
   4730 				{
   4731 					out_material->has_clearcoat = 1;
   4732 					i = cgltf_parse_json_clearcoat(options, tokens, i + 1, json_chunk, &out_material->clearcoat);
   4733 				}
   4734 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_ior") == 0)
   4735 				{
   4736 					out_material->has_ior = 1;
   4737 					i = cgltf_parse_json_ior(tokens, i + 1, json_chunk, &out_material->ior);
   4738 				}
   4739 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_specular") == 0)
   4740 				{
   4741 					out_material->has_specular = 1;
   4742 					i = cgltf_parse_json_specular(options, tokens, i + 1, json_chunk, &out_material->specular);
   4743 				}
   4744 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_transmission") == 0)
   4745 				{
   4746 					out_material->has_transmission = 1;
   4747 					i = cgltf_parse_json_transmission(options, tokens, i + 1, json_chunk, &out_material->transmission);
   4748 				}
   4749 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_volume") == 0)
   4750 				{
   4751 					out_material->has_volume = 1;
   4752 					i = cgltf_parse_json_volume(options, tokens, i + 1, json_chunk, &out_material->volume);
   4753 				}
   4754 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_sheen") == 0)
   4755 				{
   4756 					out_material->has_sheen = 1;
   4757 					i = cgltf_parse_json_sheen(options, tokens, i + 1, json_chunk, &out_material->sheen);
   4758 				}
   4759 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_emissive_strength") == 0)
   4760 				{
   4761 					out_material->has_emissive_strength = 1;
   4762 					i = cgltf_parse_json_emissive_strength(tokens, i + 1, json_chunk, &out_material->emissive_strength);
   4763 				}
   4764 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_iridescence") == 0)
   4765 				{
   4766 					out_material->has_iridescence = 1;
   4767 					i = cgltf_parse_json_iridescence(options, tokens, i + 1, json_chunk, &out_material->iridescence);
   4768 				}
   4769 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_anisotropy") == 0)
   4770 				{
   4771 					out_material->has_anisotropy = 1;
   4772 					i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->anisotropy);
   4773 				}
   4774 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_dispersion") == 0)
   4775 				{
   4776 					out_material->has_dispersion = 1;
   4777 					i = cgltf_parse_json_dispersion(tokens, i + 1, json_chunk, &out_material->dispersion);
   4778 				}
   4779 				else
   4780 				{
   4781 					i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++]));
   4782 				}
   4783 
   4784 				if (i < 0)
   4785 				{
   4786 					return i;
   4787 				}
   4788 			}
   4789 		}
   4790 		else
   4791 		{
   4792 			i = cgltf_skip_json(tokens, i+1);
   4793 		}
   4794 
   4795 		if (i < 0)
   4796 		{
   4797 			return i;
   4798 		}
   4799 	}
   4800 
   4801 	return i;
   4802 }
   4803 
   4804 static int cgltf_parse_json_accessors(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   4805 {
   4806 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_accessor), (void**)&out_data->accessors, &out_data->accessors_count);
   4807 	if (i < 0)
   4808 	{
   4809 		return i;
   4810 	}
   4811 
   4812 	for (cgltf_size j = 0; j < out_data->accessors_count; ++j)
   4813 	{
   4814 		i = cgltf_parse_json_accessor(options, tokens, i, json_chunk, &out_data->accessors[j]);
   4815 		if (i < 0)
   4816 		{
   4817 			return i;
   4818 		}
   4819 	}
   4820 	return i;
   4821 }
   4822 
   4823 static int cgltf_parse_json_materials(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   4824 {
   4825 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_material), (void**)&out_data->materials, &out_data->materials_count);
   4826 	if (i < 0)
   4827 	{
   4828 		return i;
   4829 	}
   4830 
   4831 	for (cgltf_size j = 0; j < out_data->materials_count; ++j)
   4832 	{
   4833 		i = cgltf_parse_json_material(options, tokens, i, json_chunk, &out_data->materials[j]);
   4834 		if (i < 0)
   4835 		{
   4836 			return i;
   4837 		}
   4838 	}
   4839 	return i;
   4840 }
   4841 
   4842 static int cgltf_parse_json_images(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   4843 {
   4844 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_image), (void**)&out_data->images, &out_data->images_count);
   4845 	if (i < 0)
   4846 	{
   4847 		return i;
   4848 	}
   4849 
   4850 	for (cgltf_size j = 0; j < out_data->images_count; ++j)
   4851 	{
   4852 		i = cgltf_parse_json_image(options, tokens, i, json_chunk, &out_data->images[j]);
   4853 		if (i < 0)
   4854 		{
   4855 			return i;
   4856 		}
   4857 	}
   4858 	return i;
   4859 }
   4860 
   4861 static int cgltf_parse_json_textures(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   4862 {
   4863 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_texture), (void**)&out_data->textures, &out_data->textures_count);
   4864 	if (i < 0)
   4865 	{
   4866 		return i;
   4867 	}
   4868 
   4869 	for (cgltf_size j = 0; j < out_data->textures_count; ++j)
   4870 	{
   4871 		i = cgltf_parse_json_texture(options, tokens, i, json_chunk, &out_data->textures[j]);
   4872 		if (i < 0)
   4873 		{
   4874 			return i;
   4875 		}
   4876 	}
   4877 	return i;
   4878 }
   4879 
   4880 static int cgltf_parse_json_samplers(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   4881 {
   4882 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_sampler), (void**)&out_data->samplers, &out_data->samplers_count);
   4883 	if (i < 0)
   4884 	{
   4885 		return i;
   4886 	}
   4887 
   4888 	for (cgltf_size j = 0; j < out_data->samplers_count; ++j)
   4889 	{
   4890 		i = cgltf_parse_json_sampler(options, tokens, i, json_chunk, &out_data->samplers[j]);
   4891 		if (i < 0)
   4892 		{
   4893 			return i;
   4894 		}
   4895 	}
   4896 	return i;
   4897 }
   4898 
   4899 static int cgltf_parse_json_meshopt_compression(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_meshopt_compression* out_meshopt_compression)
   4900 {
   4901 	(void)options;
   4902 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4903 
   4904 	int size = tokens[i].size;
   4905 	++i;
   4906 
   4907 	for (int j = 0; j < size; ++j)
   4908 	{
   4909 		CGLTF_CHECK_KEY(tokens[i]);
   4910 
   4911 		if (cgltf_json_strcmp(tokens+i, json_chunk, "buffer") == 0)
   4912 		{
   4913 			++i;
   4914 			out_meshopt_compression->buffer = CGLTF_PTRINDEX(cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
   4915 			++i;
   4916 		}
   4917 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
   4918 		{
   4919 			++i;
   4920 			out_meshopt_compression->offset = cgltf_json_to_size(tokens+i, json_chunk);
   4921 			++i;
   4922 		}
   4923 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
   4924 		{
   4925 			++i;
   4926 			out_meshopt_compression->size = cgltf_json_to_size(tokens+i, json_chunk);
   4927 			++i;
   4928 		}
   4929 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteStride") == 0)
   4930 		{
   4931 			++i;
   4932 			out_meshopt_compression->stride = cgltf_json_to_size(tokens+i, json_chunk);
   4933 			++i;
   4934 		}
   4935 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0)
   4936 		{
   4937 			++i;
   4938 			out_meshopt_compression->count = cgltf_json_to_size(tokens+i, json_chunk);
   4939 			++i;
   4940 		}
   4941 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "mode") == 0)
   4942 		{
   4943 			++i;
   4944 			if (cgltf_json_strcmp(tokens+i, json_chunk, "ATTRIBUTES") == 0)
   4945 			{
   4946 				out_meshopt_compression->mode = cgltf_meshopt_compression_mode_attributes;
   4947 			}
   4948 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "TRIANGLES") == 0)
   4949 			{
   4950 				out_meshopt_compression->mode = cgltf_meshopt_compression_mode_triangles;
   4951 			}
   4952 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "INDICES") == 0)
   4953 			{
   4954 				out_meshopt_compression->mode = cgltf_meshopt_compression_mode_indices;
   4955 			}
   4956 			++i;
   4957 		}
   4958 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "filter") == 0)
   4959 		{
   4960 			++i;
   4961 			if (cgltf_json_strcmp(tokens+i, json_chunk, "NONE") == 0)
   4962 			{
   4963 				out_meshopt_compression->filter = cgltf_meshopt_compression_filter_none;
   4964 			}
   4965 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "OCTAHEDRAL") == 0)
   4966 			{
   4967 				out_meshopt_compression->filter = cgltf_meshopt_compression_filter_octahedral;
   4968 			}
   4969 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "QUATERNION") == 0)
   4970 			{
   4971 				out_meshopt_compression->filter = cgltf_meshopt_compression_filter_quaternion;
   4972 			}
   4973 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "EXPONENTIAL") == 0)
   4974 			{
   4975 				out_meshopt_compression->filter = cgltf_meshopt_compression_filter_exponential;
   4976 			}
   4977 			++i;
   4978 		}
   4979 		else
   4980 		{
   4981 			i = cgltf_skip_json(tokens, i+1);
   4982 		}
   4983 
   4984 		if (i < 0)
   4985 		{
   4986 			return i;
   4987 		}
   4988 	}
   4989 
   4990 	return i;
   4991 }
   4992 
   4993 static int cgltf_parse_json_buffer_view(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_buffer_view* out_buffer_view)
   4994 {
   4995 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   4996 
   4997 	int size = tokens[i].size;
   4998 	++i;
   4999 
   5000 	for (int j = 0; j < size; ++j)
   5001 	{
   5002 		CGLTF_CHECK_KEY(tokens[i]);
   5003 
   5004 		if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
   5005 		{
   5006 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer_view->name);
   5007 		}
   5008 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "buffer") == 0)
   5009 		{
   5010 			++i;
   5011 			out_buffer_view->buffer = CGLTF_PTRINDEX(cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
   5012 			++i;
   5013 		}
   5014 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
   5015 		{
   5016 			++i;
   5017 			out_buffer_view->offset =
   5018 					cgltf_json_to_size(tokens+i, json_chunk);
   5019 			++i;
   5020 		}
   5021 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
   5022 		{
   5023 			++i;
   5024 			out_buffer_view->size =
   5025 					cgltf_json_to_size(tokens+i, json_chunk);
   5026 			++i;
   5027 		}
   5028 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteStride") == 0)
   5029 		{
   5030 			++i;
   5031 			out_buffer_view->stride =
   5032 					cgltf_json_to_size(tokens+i, json_chunk);
   5033 			++i;
   5034 		}
   5035 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "target") == 0)
   5036 		{
   5037 			++i;
   5038 			int type = cgltf_json_to_int(tokens+i, json_chunk);
   5039 			switch (type)
   5040 			{
   5041 			case 34962:
   5042 				type = cgltf_buffer_view_type_vertices;
   5043 				break;
   5044 			case 34963:
   5045 				type = cgltf_buffer_view_type_indices;
   5046 				break;
   5047 			default:
   5048 				type = cgltf_buffer_view_type_invalid;
   5049 				break;
   5050 			}
   5051 			out_buffer_view->type = (cgltf_buffer_view_type)type;
   5052 			++i;
   5053 		}
   5054 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5055 		{
   5056 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_buffer_view->extras);
   5057 		}
   5058 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   5059 		{
   5060 			++i;
   5061 
   5062 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5063 			if(out_buffer_view->extensions)
   5064 			{
   5065 				return CGLTF_ERROR_JSON;
   5066 			}
   5067 
   5068 			int extensions_size = tokens[i].size;
   5069 			out_buffer_view->extensions_count = 0;
   5070 			out_buffer_view->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size);
   5071 
   5072 			if (!out_buffer_view->extensions)
   5073 			{
   5074 				return CGLTF_ERROR_NOMEM;
   5075 			}
   5076 
   5077 			++i;
   5078 			for (int k = 0; k < extensions_size; ++k)
   5079 			{
   5080 				CGLTF_CHECK_KEY(tokens[i]);
   5081 
   5082 				if (cgltf_json_strcmp(tokens+i, json_chunk, "EXT_meshopt_compression") == 0)
   5083 				{
   5084 					out_buffer_view->has_meshopt_compression = 1;
   5085 					i = cgltf_parse_json_meshopt_compression(options, tokens, i + 1, json_chunk, &out_buffer_view->meshopt_compression);
   5086 				}
   5087 				else
   5088 				{
   5089 					i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_buffer_view->extensions[out_buffer_view->extensions_count++]));
   5090 				}
   5091 
   5092 				if (i < 0)
   5093 				{
   5094 					return i;
   5095 				}
   5096 			}
   5097 		}
   5098 		else
   5099 		{
   5100 			i = cgltf_skip_json(tokens, i+1);
   5101 		}
   5102 
   5103 		if (i < 0)
   5104 		{
   5105 			return i;
   5106 		}
   5107 	}
   5108 
   5109 	return i;
   5110 }
   5111 
   5112 static int cgltf_parse_json_buffer_views(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   5113 {
   5114 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_buffer_view), (void**)&out_data->buffer_views, &out_data->buffer_views_count);
   5115 	if (i < 0)
   5116 	{
   5117 		return i;
   5118 	}
   5119 
   5120 	for (cgltf_size j = 0; j < out_data->buffer_views_count; ++j)
   5121 	{
   5122 		i = cgltf_parse_json_buffer_view(options, tokens, i, json_chunk, &out_data->buffer_views[j]);
   5123 		if (i < 0)
   5124 		{
   5125 			return i;
   5126 		}
   5127 	}
   5128 	return i;
   5129 }
   5130 
   5131 static int cgltf_parse_json_buffer(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_buffer* out_buffer)
   5132 {
   5133 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5134 
   5135 	int size = tokens[i].size;
   5136 	++i;
   5137 
   5138 	for (int j = 0; j < size; ++j)
   5139 	{
   5140 		CGLTF_CHECK_KEY(tokens[i]);
   5141 
   5142 		if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
   5143 		{
   5144 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->name);
   5145 		}
   5146 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
   5147 		{
   5148 			++i;
   5149 			out_buffer->size =
   5150 					cgltf_json_to_size(tokens+i, json_chunk);
   5151 			++i;
   5152 		}
   5153 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "uri") == 0)
   5154 		{
   5155 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->uri);
   5156 		}
   5157 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5158 		{
   5159 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_buffer->extras);
   5160 		}
   5161 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   5162 		{
   5163 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_buffer->extensions_count, &out_buffer->extensions);
   5164 		}
   5165 		else
   5166 		{
   5167 			i = cgltf_skip_json(tokens, i+1);
   5168 		}
   5169 
   5170 		if (i < 0)
   5171 		{
   5172 			return i;
   5173 		}
   5174 	}
   5175 
   5176 	return i;
   5177 }
   5178 
   5179 static int cgltf_parse_json_buffers(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   5180 {
   5181 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_buffer), (void**)&out_data->buffers, &out_data->buffers_count);
   5182 	if (i < 0)
   5183 	{
   5184 		return i;
   5185 	}
   5186 
   5187 	for (cgltf_size j = 0; j < out_data->buffers_count; ++j)
   5188 	{
   5189 		i = cgltf_parse_json_buffer(options, tokens, i, json_chunk, &out_data->buffers[j]);
   5190 		if (i < 0)
   5191 		{
   5192 			return i;
   5193 		}
   5194 	}
   5195 	return i;
   5196 }
   5197 
   5198 static int cgltf_parse_json_skin(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_skin* out_skin)
   5199 {
   5200 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5201 
   5202 	int size = tokens[i].size;
   5203 	++i;
   5204 
   5205 	for (int j = 0; j < size; ++j)
   5206 	{
   5207 		CGLTF_CHECK_KEY(tokens[i]);
   5208 
   5209 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   5210 		{
   5211 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_skin->name);
   5212 		}
   5213 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "joints") == 0)
   5214 		{
   5215 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_node*), (void**)&out_skin->joints, &out_skin->joints_count);
   5216 			if (i < 0)
   5217 			{
   5218 				return i;
   5219 			}
   5220 
   5221 			for (cgltf_size k = 0; k < out_skin->joints_count; ++k)
   5222 			{
   5223 				out_skin->joints[k] = CGLTF_PTRINDEX(cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
   5224 				++i;
   5225 			}
   5226 		}
   5227 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "skeleton") == 0)
   5228 		{
   5229 			++i;
   5230 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   5231 			out_skin->skeleton = CGLTF_PTRINDEX(cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
   5232 			++i;
   5233 		}
   5234 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "inverseBindMatrices") == 0)
   5235 		{
   5236 			++i;
   5237 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   5238 			out_skin->inverse_bind_matrices = CGLTF_PTRINDEX(cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
   5239 			++i;
   5240 		}
   5241 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5242 		{
   5243 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_skin->extras);
   5244 		}
   5245 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   5246 		{
   5247 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_skin->extensions_count, &out_skin->extensions);
   5248 		}
   5249 		else
   5250 		{
   5251 			i = cgltf_skip_json(tokens, i+1);
   5252 		}
   5253 
   5254 		if (i < 0)
   5255 		{
   5256 			return i;
   5257 		}
   5258 	}
   5259 
   5260 	return i;
   5261 }
   5262 
   5263 static int cgltf_parse_json_skins(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   5264 {
   5265 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_skin), (void**)&out_data->skins, &out_data->skins_count);
   5266 	if (i < 0)
   5267 	{
   5268 		return i;
   5269 	}
   5270 
   5271 	for (cgltf_size j = 0; j < out_data->skins_count; ++j)
   5272 	{
   5273 		i = cgltf_parse_json_skin(options, tokens, i, json_chunk, &out_data->skins[j]);
   5274 		if (i < 0)
   5275 		{
   5276 			return i;
   5277 		}
   5278 	}
   5279 	return i;
   5280 }
   5281 
   5282 static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_camera* out_camera)
   5283 {
   5284 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5285 
   5286 	int size = tokens[i].size;
   5287 	++i;
   5288 
   5289 	for (int j = 0; j < size; ++j)
   5290 	{
   5291 		CGLTF_CHECK_KEY(tokens[i]);
   5292 
   5293 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   5294 		{
   5295 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_camera->name);
   5296 		}
   5297 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "perspective") == 0)
   5298 		{
   5299 			++i;
   5300 
   5301 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5302 
   5303 			int data_size = tokens[i].size;
   5304 			++i;
   5305 
   5306 			if (out_camera->type != cgltf_camera_type_invalid)
   5307 			{
   5308 				return CGLTF_ERROR_JSON;
   5309 			}
   5310 
   5311 			out_camera->type = cgltf_camera_type_perspective;
   5312 
   5313 			for (int k = 0; k < data_size; ++k)
   5314 			{
   5315 				CGLTF_CHECK_KEY(tokens[i]);
   5316 
   5317 				if (cgltf_json_strcmp(tokens+i, json_chunk, "aspectRatio") == 0)
   5318 				{
   5319 					++i;
   5320 					out_camera->data.perspective.has_aspect_ratio = 1;
   5321 					out_camera->data.perspective.aspect_ratio = cgltf_json_to_float(tokens + i, json_chunk);
   5322 					++i;
   5323 				}
   5324 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "yfov") == 0)
   5325 				{
   5326 					++i;
   5327 					out_camera->data.perspective.yfov = cgltf_json_to_float(tokens + i, json_chunk);
   5328 					++i;
   5329 				}
   5330 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "zfar") == 0)
   5331 				{
   5332 					++i;
   5333 					out_camera->data.perspective.has_zfar = 1;
   5334 					out_camera->data.perspective.zfar = cgltf_json_to_float(tokens + i, json_chunk);
   5335 					++i;
   5336 				}
   5337 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "znear") == 0)
   5338 				{
   5339 					++i;
   5340 					out_camera->data.perspective.znear = cgltf_json_to_float(tokens + i, json_chunk);
   5341 					++i;
   5342 				}
   5343 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5344 				{
   5345 					i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_camera->data.perspective.extras);
   5346 				}
   5347 				else
   5348 				{
   5349 					i = cgltf_skip_json(tokens, i+1);
   5350 				}
   5351 
   5352 				if (i < 0)
   5353 				{
   5354 					return i;
   5355 				}
   5356 			}
   5357 		}
   5358 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "orthographic") == 0)
   5359 		{
   5360 			++i;
   5361 
   5362 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5363 
   5364 			int data_size = tokens[i].size;
   5365 			++i;
   5366 
   5367 			if (out_camera->type != cgltf_camera_type_invalid)
   5368 			{
   5369 				return CGLTF_ERROR_JSON;
   5370 			}
   5371 
   5372 			out_camera->type = cgltf_camera_type_orthographic;
   5373 
   5374 			for (int k = 0; k < data_size; ++k)
   5375 			{
   5376 				CGLTF_CHECK_KEY(tokens[i]);
   5377 
   5378 				if (cgltf_json_strcmp(tokens+i, json_chunk, "xmag") == 0)
   5379 				{
   5380 					++i;
   5381 					out_camera->data.orthographic.xmag = cgltf_json_to_float(tokens + i, json_chunk);
   5382 					++i;
   5383 				}
   5384 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "ymag") == 0)
   5385 				{
   5386 					++i;
   5387 					out_camera->data.orthographic.ymag = cgltf_json_to_float(tokens + i, json_chunk);
   5388 					++i;
   5389 				}
   5390 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "zfar") == 0)
   5391 				{
   5392 					++i;
   5393 					out_camera->data.orthographic.zfar = cgltf_json_to_float(tokens + i, json_chunk);
   5394 					++i;
   5395 				}
   5396 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "znear") == 0)
   5397 				{
   5398 					++i;
   5399 					out_camera->data.orthographic.znear = cgltf_json_to_float(tokens + i, json_chunk);
   5400 					++i;
   5401 				}
   5402 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5403 				{
   5404 					i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_camera->data.orthographic.extras);
   5405 				}
   5406 				else
   5407 				{
   5408 					i = cgltf_skip_json(tokens, i+1);
   5409 				}
   5410 
   5411 				if (i < 0)
   5412 				{
   5413 					return i;
   5414 				}
   5415 			}
   5416 		}
   5417 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5418 		{
   5419 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_camera->extras);
   5420 		}
   5421 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   5422 		{
   5423 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_camera->extensions_count, &out_camera->extensions);
   5424 		}
   5425 		else
   5426 		{
   5427 			i = cgltf_skip_json(tokens, i+1);
   5428 		}
   5429 
   5430 		if (i < 0)
   5431 		{
   5432 			return i;
   5433 		}
   5434 	}
   5435 
   5436 	return i;
   5437 }
   5438 
   5439 static int cgltf_parse_json_cameras(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   5440 {
   5441 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_camera), (void**)&out_data->cameras, &out_data->cameras_count);
   5442 	if (i < 0)
   5443 	{
   5444 		return i;
   5445 	}
   5446 
   5447 	for (cgltf_size j = 0; j < out_data->cameras_count; ++j)
   5448 	{
   5449 		i = cgltf_parse_json_camera(options, tokens, i, json_chunk, &out_data->cameras[j]);
   5450 		if (i < 0)
   5451 		{
   5452 			return i;
   5453 		}
   5454 	}
   5455 	return i;
   5456 }
   5457 
   5458 static int cgltf_parse_json_light(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_light* out_light)
   5459 {
   5460 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5461 
   5462 	out_light->color[0] = 1.f;
   5463 	out_light->color[1] = 1.f;
   5464 	out_light->color[2] = 1.f;
   5465 	out_light->intensity = 1.f;
   5466 
   5467 	out_light->spot_inner_cone_angle = 0.f;
   5468 	out_light->spot_outer_cone_angle = 3.1415926535f / 4.0f;
   5469 
   5470 	int size = tokens[i].size;
   5471 	++i;
   5472 
   5473 	for (int j = 0; j < size; ++j)
   5474 	{
   5475 		CGLTF_CHECK_KEY(tokens[i]);
   5476 
   5477 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   5478 		{
   5479 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_light->name);
   5480 		}
   5481 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "color") == 0)
   5482 		{
   5483 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_light->color, 3);
   5484 		}
   5485 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "intensity") == 0)
   5486 		{
   5487 			++i;
   5488 			out_light->intensity = cgltf_json_to_float(tokens + i, json_chunk);
   5489 			++i;
   5490 		}
   5491 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "type") == 0)
   5492 		{
   5493 			++i;
   5494 			if (cgltf_json_strcmp(tokens + i, json_chunk, "directional") == 0)
   5495 			{
   5496 				out_light->type = cgltf_light_type_directional;
   5497 			}
   5498 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "point") == 0)
   5499 			{
   5500 				out_light->type = cgltf_light_type_point;
   5501 			}
   5502 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "spot") == 0)
   5503 			{
   5504 				out_light->type = cgltf_light_type_spot;
   5505 			}
   5506 			++i;
   5507 		}
   5508 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "range") == 0)
   5509 		{
   5510 			++i;
   5511 			out_light->range = cgltf_json_to_float(tokens + i, json_chunk);
   5512 			++i;
   5513 		}
   5514 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "spot") == 0)
   5515 		{
   5516 			++i;
   5517 
   5518 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5519 
   5520 			int data_size = tokens[i].size;
   5521 			++i;
   5522 
   5523 			for (int k = 0; k < data_size; ++k)
   5524 			{
   5525 				CGLTF_CHECK_KEY(tokens[i]);
   5526 
   5527 				if (cgltf_json_strcmp(tokens+i, json_chunk, "innerConeAngle") == 0)
   5528 				{
   5529 					++i;
   5530 					out_light->spot_inner_cone_angle = cgltf_json_to_float(tokens + i, json_chunk);
   5531 					++i;
   5532 				}
   5533 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "outerConeAngle") == 0)
   5534 				{
   5535 					++i;
   5536 					out_light->spot_outer_cone_angle = cgltf_json_to_float(tokens + i, json_chunk);
   5537 					++i;
   5538 				}
   5539 				else
   5540 				{
   5541 					i = cgltf_skip_json(tokens, i+1);
   5542 				}
   5543 
   5544 				if (i < 0)
   5545 				{
   5546 					return i;
   5547 				}
   5548 			}
   5549 		}
   5550 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5551 		{
   5552 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_light->extras);
   5553 		}
   5554 		else
   5555 		{
   5556 			i = cgltf_skip_json(tokens, i+1);
   5557 		}
   5558 
   5559 		if (i < 0)
   5560 		{
   5561 			return i;
   5562 		}
   5563 	}
   5564 
   5565 	return i;
   5566 }
   5567 
   5568 static int cgltf_parse_json_lights(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   5569 {
   5570 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_light), (void**)&out_data->lights, &out_data->lights_count);
   5571 	if (i < 0)
   5572 	{
   5573 		return i;
   5574 	}
   5575 
   5576 	for (cgltf_size j = 0; j < out_data->lights_count; ++j)
   5577 	{
   5578 		i = cgltf_parse_json_light(options, tokens, i, json_chunk, &out_data->lights[j]);
   5579 		if (i < 0)
   5580 		{
   5581 			return i;
   5582 		}
   5583 	}
   5584 	return i;
   5585 }
   5586 
   5587 static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_node* out_node)
   5588 {
   5589 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5590 
   5591 	out_node->rotation[3] = 1.0f;
   5592 	out_node->scale[0] = 1.0f;
   5593 	out_node->scale[1] = 1.0f;
   5594 	out_node->scale[2] = 1.0f;
   5595 	out_node->matrix[0] = 1.0f;
   5596 	out_node->matrix[5] = 1.0f;
   5597 	out_node->matrix[10] = 1.0f;
   5598 	out_node->matrix[15] = 1.0f;
   5599 
   5600 	int size = tokens[i].size;
   5601 	++i;
   5602 
   5603 	for (int j = 0; j < size; ++j)
   5604 	{
   5605 		CGLTF_CHECK_KEY(tokens[i]);
   5606 
   5607 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   5608 		{
   5609 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_node->name);
   5610 		}
   5611 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "children") == 0)
   5612 		{
   5613 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_node*), (void**)&out_node->children, &out_node->children_count);
   5614 			if (i < 0)
   5615 			{
   5616 				return i;
   5617 			}
   5618 
   5619 			for (cgltf_size k = 0; k < out_node->children_count; ++k)
   5620 			{
   5621 				out_node->children[k] = CGLTF_PTRINDEX(cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
   5622 				++i;
   5623 			}
   5624 		}
   5625 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "mesh") == 0)
   5626 		{
   5627 			++i;
   5628 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   5629 			out_node->mesh = CGLTF_PTRINDEX(cgltf_mesh, cgltf_json_to_int(tokens + i, json_chunk));
   5630 			++i;
   5631 		}
   5632 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "skin") == 0)
   5633 		{
   5634 			++i;
   5635 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   5636 			out_node->skin = CGLTF_PTRINDEX(cgltf_skin, cgltf_json_to_int(tokens + i, json_chunk));
   5637 			++i;
   5638 		}
   5639 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "camera") == 0)
   5640 		{
   5641 			++i;
   5642 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   5643 			out_node->camera = CGLTF_PTRINDEX(cgltf_camera, cgltf_json_to_int(tokens + i, json_chunk));
   5644 			++i;
   5645 		}
   5646 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "translation") == 0)
   5647 		{
   5648 			out_node->has_translation = 1;
   5649 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->translation, 3);
   5650 		}
   5651 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "rotation") == 0)
   5652 		{
   5653 			out_node->has_rotation = 1;
   5654 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->rotation, 4);
   5655 		}
   5656 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "scale") == 0)
   5657 		{
   5658 			out_node->has_scale = 1;
   5659 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->scale, 3);
   5660 		}
   5661 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "matrix") == 0)
   5662 		{
   5663 			out_node->has_matrix = 1;
   5664 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->matrix, 16);
   5665 		}
   5666 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "weights") == 0)
   5667 		{
   5668 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_float), (void**)&out_node->weights, &out_node->weights_count);
   5669 			if (i < 0)
   5670 			{
   5671 				return i;
   5672 			}
   5673 
   5674 			i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_node->weights, (int)out_node->weights_count);
   5675 		}
   5676 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5677 		{
   5678 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_node->extras);
   5679 		}
   5680 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   5681 		{
   5682 			++i;
   5683 
   5684 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5685 			if(out_node->extensions)
   5686 			{
   5687 				return CGLTF_ERROR_JSON;
   5688 			}
   5689 
   5690 			int extensions_size = tokens[i].size;
   5691 			out_node->extensions_count= 0;
   5692 			out_node->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size);
   5693 
   5694 			if (!out_node->extensions)
   5695 			{
   5696 				return CGLTF_ERROR_NOMEM;
   5697 			}
   5698 
   5699 			++i;
   5700 
   5701 			for (int k = 0; k < extensions_size; ++k)
   5702 			{
   5703 				CGLTF_CHECK_KEY(tokens[i]);
   5704 
   5705 				if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_lights_punctual") == 0)
   5706 				{
   5707 					++i;
   5708 
   5709 					CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5710 
   5711 					int data_size = tokens[i].size;
   5712 					++i;
   5713 
   5714 					for (int m = 0; m < data_size; ++m)
   5715 					{
   5716 						CGLTF_CHECK_KEY(tokens[i]);
   5717 
   5718 						if (cgltf_json_strcmp(tokens + i, json_chunk, "light") == 0)
   5719 						{
   5720 							++i;
   5721 							CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   5722 							out_node->light = CGLTF_PTRINDEX(cgltf_light, cgltf_json_to_int(tokens + i, json_chunk));
   5723 							++i;
   5724 						}
   5725 						else
   5726 						{
   5727 							i = cgltf_skip_json(tokens, i + 1);
   5728 						}
   5729 
   5730 						if (i < 0)
   5731 						{
   5732 							return i;
   5733 						}
   5734 					}
   5735 				}
   5736 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "EXT_mesh_gpu_instancing") == 0)
   5737 				{
   5738 					out_node->has_mesh_gpu_instancing = 1;
   5739 					i = cgltf_parse_json_mesh_gpu_instancing(options, tokens, i + 1, json_chunk, &out_node->mesh_gpu_instancing);
   5740 				}
   5741 				else
   5742 				{
   5743 					i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_node->extensions[out_node->extensions_count++]));
   5744 				}
   5745 
   5746 				if (i < 0)
   5747 				{
   5748 					return i;
   5749 				}
   5750 			}
   5751 		}
   5752 		else
   5753 		{
   5754 			i = cgltf_skip_json(tokens, i+1);
   5755 		}
   5756 
   5757 		if (i < 0)
   5758 		{
   5759 			return i;
   5760 		}
   5761 	}
   5762 
   5763 	return i;
   5764 }
   5765 
   5766 static int cgltf_parse_json_nodes(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   5767 {
   5768 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_node), (void**)&out_data->nodes, &out_data->nodes_count);
   5769 	if (i < 0)
   5770 	{
   5771 		return i;
   5772 	}
   5773 
   5774 	for (cgltf_size j = 0; j < out_data->nodes_count; ++j)
   5775 	{
   5776 		i = cgltf_parse_json_node(options, tokens, i, json_chunk, &out_data->nodes[j]);
   5777 		if (i < 0)
   5778 		{
   5779 			return i;
   5780 		}
   5781 	}
   5782 	return i;
   5783 }
   5784 
   5785 static int cgltf_parse_json_scene(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_scene* out_scene)
   5786 {
   5787 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5788 
   5789 	int size = tokens[i].size;
   5790 	++i;
   5791 
   5792 	for (int j = 0; j < size; ++j)
   5793 	{
   5794 		CGLTF_CHECK_KEY(tokens[i]);
   5795 
   5796 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   5797 		{
   5798 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_scene->name);
   5799 		}
   5800 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "nodes") == 0)
   5801 		{
   5802 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_node*), (void**)&out_scene->nodes, &out_scene->nodes_count);
   5803 			if (i < 0)
   5804 			{
   5805 				return i;
   5806 			}
   5807 
   5808 			for (cgltf_size k = 0; k < out_scene->nodes_count; ++k)
   5809 			{
   5810 				out_scene->nodes[k] = CGLTF_PTRINDEX(cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
   5811 				++i;
   5812 			}
   5813 		}
   5814 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5815 		{
   5816 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_scene->extras);
   5817 		}
   5818 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   5819 		{
   5820 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_scene->extensions_count, &out_scene->extensions);
   5821 		}
   5822 		else
   5823 		{
   5824 			i = cgltf_skip_json(tokens, i+1);
   5825 		}
   5826 
   5827 		if (i < 0)
   5828 		{
   5829 			return i;
   5830 		}
   5831 	}
   5832 
   5833 	return i;
   5834 }
   5835 
   5836 static int cgltf_parse_json_scenes(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   5837 {
   5838 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_scene), (void**)&out_data->scenes, &out_data->scenes_count);
   5839 	if (i < 0)
   5840 	{
   5841 		return i;
   5842 	}
   5843 
   5844 	for (cgltf_size j = 0; j < out_data->scenes_count; ++j)
   5845 	{
   5846 		i = cgltf_parse_json_scene(options, tokens, i, json_chunk, &out_data->scenes[j]);
   5847 		if (i < 0)
   5848 		{
   5849 			return i;
   5850 		}
   5851 	}
   5852 	return i;
   5853 }
   5854 
   5855 static int cgltf_parse_json_animation_sampler(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_animation_sampler* out_sampler)
   5856 {
   5857 	(void)options;
   5858 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5859 
   5860 	int size = tokens[i].size;
   5861 	++i;
   5862 
   5863 	for (int j = 0; j < size; ++j)
   5864 	{
   5865 		CGLTF_CHECK_KEY(tokens[i]);
   5866 
   5867 		if (cgltf_json_strcmp(tokens+i, json_chunk, "input") == 0)
   5868 		{
   5869 			++i;
   5870 			out_sampler->input = CGLTF_PTRINDEX(cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
   5871 			++i;
   5872 		}
   5873 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "output") == 0)
   5874 		{
   5875 			++i;
   5876 			out_sampler->output = CGLTF_PTRINDEX(cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
   5877 			++i;
   5878 		}
   5879 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "interpolation") == 0)
   5880 		{
   5881 			++i;
   5882 			if (cgltf_json_strcmp(tokens + i, json_chunk, "LINEAR") == 0)
   5883 			{
   5884 				out_sampler->interpolation = cgltf_interpolation_type_linear;
   5885 			}
   5886 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "STEP") == 0)
   5887 			{
   5888 				out_sampler->interpolation = cgltf_interpolation_type_step;
   5889 			}
   5890 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "CUBICSPLINE") == 0)
   5891 			{
   5892 				out_sampler->interpolation = cgltf_interpolation_type_cubic_spline;
   5893 			}
   5894 			++i;
   5895 		}
   5896 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5897 		{
   5898 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sampler->extras);
   5899 		}
   5900 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   5901 		{
   5902 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->extensions_count, &out_sampler->extensions);
   5903 		}
   5904 		else
   5905 		{
   5906 			i = cgltf_skip_json(tokens, i+1);
   5907 		}
   5908 
   5909 		if (i < 0)
   5910 		{
   5911 			return i;
   5912 		}
   5913 	}
   5914 
   5915 	return i;
   5916 }
   5917 
   5918 static int cgltf_parse_json_animation_channel(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_animation_channel* out_channel)
   5919 {
   5920 	(void)options;
   5921 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5922 
   5923 	int size = tokens[i].size;
   5924 	++i;
   5925 
   5926 	for (int j = 0; j < size; ++j)
   5927 	{
   5928 		CGLTF_CHECK_KEY(tokens[i]);
   5929 
   5930 		if (cgltf_json_strcmp(tokens+i, json_chunk, "sampler") == 0)
   5931 		{
   5932 			++i;
   5933 			out_channel->sampler = CGLTF_PTRINDEX(cgltf_animation_sampler, cgltf_json_to_int(tokens + i, json_chunk));
   5934 			++i;
   5935 		}
   5936 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "target") == 0)
   5937 		{
   5938 			++i;
   5939 
   5940 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   5941 
   5942 			int target_size = tokens[i].size;
   5943 			++i;
   5944 
   5945 			for (int k = 0; k < target_size; ++k)
   5946 			{
   5947 				CGLTF_CHECK_KEY(tokens[i]);
   5948 
   5949 				if (cgltf_json_strcmp(tokens+i, json_chunk, "node") == 0)
   5950 				{
   5951 					++i;
   5952 					out_channel->target_node = CGLTF_PTRINDEX(cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
   5953 					++i;
   5954 				}
   5955 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "path") == 0)
   5956 				{
   5957 					++i;
   5958 					if (cgltf_json_strcmp(tokens+i, json_chunk, "translation") == 0)
   5959 					{
   5960 						out_channel->target_path = cgltf_animation_path_type_translation;
   5961 					}
   5962 					else if (cgltf_json_strcmp(tokens+i, json_chunk, "rotation") == 0)
   5963 					{
   5964 						out_channel->target_path = cgltf_animation_path_type_rotation;
   5965 					}
   5966 					else if (cgltf_json_strcmp(tokens+i, json_chunk, "scale") == 0)
   5967 					{
   5968 						out_channel->target_path = cgltf_animation_path_type_scale;
   5969 					}
   5970 					else if (cgltf_json_strcmp(tokens+i, json_chunk, "weights") == 0)
   5971 					{
   5972 						out_channel->target_path = cgltf_animation_path_type_weights;
   5973 					}
   5974 					++i;
   5975 				}
   5976 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   5977 				{
   5978 					i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_channel->extras);
   5979 				}
   5980 				else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   5981 				{
   5982 					i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_channel->extensions_count, &out_channel->extensions);
   5983 				}
   5984 				else
   5985 				{
   5986 					i = cgltf_skip_json(tokens, i+1);
   5987 				}
   5988 
   5989 				if (i < 0)
   5990 				{
   5991 					return i;
   5992 				}
   5993 			}
   5994 		}
   5995 		else
   5996 		{
   5997 			i = cgltf_skip_json(tokens, i+1);
   5998 		}
   5999 
   6000 		if (i < 0)
   6001 		{
   6002 			return i;
   6003 		}
   6004 	}
   6005 
   6006 	return i;
   6007 }
   6008 
   6009 static int cgltf_parse_json_animation(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_animation* out_animation)
   6010 {
   6011 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   6012 
   6013 	int size = tokens[i].size;
   6014 	++i;
   6015 
   6016 	for (int j = 0; j < size; ++j)
   6017 	{
   6018 		CGLTF_CHECK_KEY(tokens[i]);
   6019 
   6020 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   6021 		{
   6022 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_animation->name);
   6023 		}
   6024 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "samplers") == 0)
   6025 		{
   6026 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_animation_sampler), (void**)&out_animation->samplers, &out_animation->samplers_count);
   6027 			if (i < 0)
   6028 			{
   6029 				return i;
   6030 			}
   6031 
   6032 			for (cgltf_size k = 0; k < out_animation->samplers_count; ++k)
   6033 			{
   6034 				i = cgltf_parse_json_animation_sampler(options, tokens, i, json_chunk, &out_animation->samplers[k]);
   6035 				if (i < 0)
   6036 				{
   6037 					return i;
   6038 				}
   6039 			}
   6040 		}
   6041 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "channels") == 0)
   6042 		{
   6043 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_animation_channel), (void**)&out_animation->channels, &out_animation->channels_count);
   6044 			if (i < 0)
   6045 			{
   6046 				return i;
   6047 			}
   6048 
   6049 			for (cgltf_size k = 0; k < out_animation->channels_count; ++k)
   6050 			{
   6051 				i = cgltf_parse_json_animation_channel(options, tokens, i, json_chunk, &out_animation->channels[k]);
   6052 				if (i < 0)
   6053 				{
   6054 					return i;
   6055 				}
   6056 			}
   6057 		}
   6058 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   6059 		{
   6060 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_animation->extras);
   6061 		}
   6062 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   6063 		{
   6064 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_animation->extensions_count, &out_animation->extensions);
   6065 		}
   6066 		else
   6067 		{
   6068 			i = cgltf_skip_json(tokens, i+1);
   6069 		}
   6070 
   6071 		if (i < 0)
   6072 		{
   6073 			return i;
   6074 		}
   6075 	}
   6076 
   6077 	return i;
   6078 }
   6079 
   6080 static int cgltf_parse_json_animations(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   6081 {
   6082 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_animation), (void**)&out_data->animations, &out_data->animations_count);
   6083 	if (i < 0)
   6084 	{
   6085 		return i;
   6086 	}
   6087 
   6088 	for (cgltf_size j = 0; j < out_data->animations_count; ++j)
   6089 	{
   6090 		i = cgltf_parse_json_animation(options, tokens, i, json_chunk, &out_data->animations[j]);
   6091 		if (i < 0)
   6092 		{
   6093 			return i;
   6094 		}
   6095 	}
   6096 	return i;
   6097 }
   6098 
   6099 static int cgltf_parse_json_variant(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_material_variant* out_variant)
   6100 {
   6101 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   6102 
   6103 	int size = tokens[i].size;
   6104 	++i;
   6105 
   6106 	for (int j = 0; j < size; ++j)
   6107 	{
   6108 		CGLTF_CHECK_KEY(tokens[i]);
   6109 
   6110 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   6111 		{
   6112 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_variant->name);
   6113 		}
   6114 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   6115 		{
   6116 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_variant->extras);
   6117 		}
   6118 		else
   6119 		{
   6120 			i = cgltf_skip_json(tokens, i+1);
   6121 		}
   6122 
   6123 		if (i < 0)
   6124 		{
   6125 			return i;
   6126 		}
   6127 	}
   6128 
   6129 	return i;
   6130 }
   6131 
   6132 static int cgltf_parse_json_variants(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   6133 {
   6134 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_material_variant), (void**)&out_data->variants, &out_data->variants_count);
   6135 	if (i < 0)
   6136 	{
   6137 		return i;
   6138 	}
   6139 
   6140 	for (cgltf_size j = 0; j < out_data->variants_count; ++j)
   6141 	{
   6142 		i = cgltf_parse_json_variant(options, tokens, i, json_chunk, &out_data->variants[j]);
   6143 		if (i < 0)
   6144 		{
   6145 			return i;
   6146 		}
   6147 	}
   6148 	return i;
   6149 }
   6150 
   6151 static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_asset* out_asset)
   6152 {
   6153 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   6154 
   6155 	int size = tokens[i].size;
   6156 	++i;
   6157 
   6158 	for (int j = 0; j < size; ++j)
   6159 	{
   6160 		CGLTF_CHECK_KEY(tokens[i]);
   6161 
   6162 		if (cgltf_json_strcmp(tokens+i, json_chunk, "copyright") == 0)
   6163 		{
   6164 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->copyright);
   6165 		}
   6166 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "generator") == 0)
   6167 		{
   6168 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->generator);
   6169 		}
   6170 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "version") == 0)
   6171 		{
   6172 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->version);
   6173 		}
   6174 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "minVersion") == 0)
   6175 		{
   6176 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->min_version);
   6177 		}
   6178 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
   6179 		{
   6180 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_asset->extras);
   6181 		}
   6182 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   6183 		{
   6184 			i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_asset->extensions_count, &out_asset->extensions);
   6185 		}
   6186 		else
   6187 		{
   6188 			i = cgltf_skip_json(tokens, i+1);
   6189 		}
   6190 
   6191 		if (i < 0)
   6192 		{
   6193 			return i;
   6194 		}
   6195 	}
   6196 
   6197 	if (out_asset->version && CGLTF_ATOF(out_asset->version) < 2)
   6198 	{
   6199 		return CGLTF_ERROR_LEGACY;
   6200 	}
   6201 
   6202 	return i;
   6203 }
   6204 
   6205 cgltf_size cgltf_num_components(cgltf_type type) {
   6206 	switch (type)
   6207 	{
   6208 	case cgltf_type_vec2:
   6209 		return 2;
   6210 	case cgltf_type_vec3:
   6211 		return 3;
   6212 	case cgltf_type_vec4:
   6213 		return 4;
   6214 	case cgltf_type_mat2:
   6215 		return 4;
   6216 	case cgltf_type_mat3:
   6217 		return 9;
   6218 	case cgltf_type_mat4:
   6219 		return 16;
   6220 	case cgltf_type_invalid:
   6221 	case cgltf_type_scalar:
   6222 	default:
   6223 		return 1;
   6224 	}
   6225 }
   6226 
   6227 cgltf_size cgltf_component_size(cgltf_component_type component_type) {
   6228 	switch (component_type)
   6229 	{
   6230 	case cgltf_component_type_r_8:
   6231 	case cgltf_component_type_r_8u:
   6232 		return 1;
   6233 	case cgltf_component_type_r_16:
   6234 	case cgltf_component_type_r_16u:
   6235 		return 2;
   6236 	case cgltf_component_type_r_32u:
   6237 	case cgltf_component_type_r_32f:
   6238 		return 4;
   6239 	case cgltf_component_type_invalid:
   6240 	default:
   6241 		return 0;
   6242 	}
   6243 }
   6244 
   6245 cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type)
   6246 {
   6247 	cgltf_size component_size = cgltf_component_size(component_type);
   6248 	if (type == cgltf_type_mat2 && component_size == 1)
   6249 	{
   6250 		return 8 * component_size;
   6251 	}
   6252 	else if (type == cgltf_type_mat3 && (component_size == 1 || component_size == 2))
   6253 	{
   6254 		return 12 * component_size;
   6255 	}
   6256 	return component_size * cgltf_num_components(type);
   6257 }
   6258 
   6259 static int cgltf_fixup_pointers(cgltf_data* out_data);
   6260 
   6261 static int cgltf_parse_json_root(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   6262 {
   6263 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   6264 
   6265 	int size = tokens[i].size;
   6266 	++i;
   6267 
   6268 	for (int j = 0; j < size; ++j)
   6269 	{
   6270 		CGLTF_CHECK_KEY(tokens[i]);
   6271 
   6272 		if (cgltf_json_strcmp(tokens + i, json_chunk, "asset") == 0)
   6273 		{
   6274 			i = cgltf_parse_json_asset(options, tokens, i + 1, json_chunk, &out_data->asset);
   6275 		}
   6276 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "meshes") == 0)
   6277 		{
   6278 			i = cgltf_parse_json_meshes(options, tokens, i + 1, json_chunk, out_data);
   6279 		}
   6280 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "accessors") == 0)
   6281 		{
   6282 			i = cgltf_parse_json_accessors(options, tokens, i + 1, json_chunk, out_data);
   6283 		}
   6284 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "bufferViews") == 0)
   6285 		{
   6286 			i = cgltf_parse_json_buffer_views(options, tokens, i + 1, json_chunk, out_data);
   6287 		}
   6288 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "buffers") == 0)
   6289 		{
   6290 			i = cgltf_parse_json_buffers(options, tokens, i + 1, json_chunk, out_data);
   6291 		}
   6292 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "materials") == 0)
   6293 		{
   6294 			i = cgltf_parse_json_materials(options, tokens, i + 1, json_chunk, out_data);
   6295 		}
   6296 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "images") == 0)
   6297 		{
   6298 			i = cgltf_parse_json_images(options, tokens, i + 1, json_chunk, out_data);
   6299 		}
   6300 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "textures") == 0)
   6301 		{
   6302 			i = cgltf_parse_json_textures(options, tokens, i + 1, json_chunk, out_data);
   6303 		}
   6304 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "samplers") == 0)
   6305 		{
   6306 			i = cgltf_parse_json_samplers(options, tokens, i + 1, json_chunk, out_data);
   6307 		}
   6308 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "skins") == 0)
   6309 		{
   6310 			i = cgltf_parse_json_skins(options, tokens, i + 1, json_chunk, out_data);
   6311 		}
   6312 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "cameras") == 0)
   6313 		{
   6314 			i = cgltf_parse_json_cameras(options, tokens, i + 1, json_chunk, out_data);
   6315 		}
   6316 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "nodes") == 0)
   6317 		{
   6318 			i = cgltf_parse_json_nodes(options, tokens, i + 1, json_chunk, out_data);
   6319 		}
   6320 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "scenes") == 0)
   6321 		{
   6322 			i = cgltf_parse_json_scenes(options, tokens, i + 1, json_chunk, out_data);
   6323 		}
   6324 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "scene") == 0)
   6325 		{
   6326 			++i;
   6327 			out_data->scene = CGLTF_PTRINDEX(cgltf_scene, cgltf_json_to_int(tokens + i, json_chunk));
   6328 			++i;
   6329 		}
   6330 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "animations") == 0)
   6331 		{
   6332 			i = cgltf_parse_json_animations(options, tokens, i + 1, json_chunk, out_data);
   6333 		}
   6334 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "extras") == 0)
   6335 		{
   6336 			i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_data->extras);
   6337 		}
   6338 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   6339 		{
   6340 			++i;
   6341 
   6342 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   6343 			if(out_data->data_extensions)
   6344 			{
   6345 				return CGLTF_ERROR_JSON;
   6346 			}
   6347 
   6348 			int extensions_size = tokens[i].size;
   6349 			out_data->data_extensions_count = 0;
   6350 			out_data->data_extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size);
   6351 
   6352 			if (!out_data->data_extensions)
   6353 			{
   6354 				return CGLTF_ERROR_NOMEM;
   6355 			}
   6356 
   6357 			++i;
   6358 
   6359 			for (int k = 0; k < extensions_size; ++k)
   6360 			{
   6361 				CGLTF_CHECK_KEY(tokens[i]);
   6362 
   6363 				if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_lights_punctual") == 0)
   6364 				{
   6365 					++i;
   6366 
   6367 					CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   6368 
   6369 					int data_size = tokens[i].size;
   6370 					++i;
   6371 
   6372 					for (int m = 0; m < data_size; ++m)
   6373 					{
   6374 						CGLTF_CHECK_KEY(tokens[i]);
   6375 
   6376 						if (cgltf_json_strcmp(tokens + i, json_chunk, "lights") == 0)
   6377 						{
   6378 							i = cgltf_parse_json_lights(options, tokens, i + 1, json_chunk, out_data);
   6379 						}
   6380 						else
   6381 						{
   6382 							i = cgltf_skip_json(tokens, i + 1);
   6383 						}
   6384 
   6385 						if (i < 0)
   6386 						{
   6387 							return i;
   6388 						}
   6389 					}
   6390 				}
   6391 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_variants") == 0)
   6392 				{
   6393 					++i;
   6394 
   6395 					CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   6396 
   6397 					int data_size = tokens[i].size;
   6398 					++i;
   6399 
   6400 					for (int m = 0; m < data_size; ++m)
   6401 					{
   6402 						CGLTF_CHECK_KEY(tokens[i]);
   6403 
   6404 						if (cgltf_json_strcmp(tokens + i, json_chunk, "variants") == 0)
   6405 						{
   6406 							i = cgltf_parse_json_variants(options, tokens, i + 1, json_chunk, out_data);
   6407 						}
   6408 						else
   6409 						{
   6410 							i = cgltf_skip_json(tokens, i + 1);
   6411 						}
   6412 
   6413 						if (i < 0)
   6414 						{
   6415 							return i;
   6416 						}
   6417 					}
   6418 				}
   6419 				else
   6420 				{
   6421 					i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_data->data_extensions[out_data->data_extensions_count++]));
   6422 				}
   6423 
   6424 				if (i < 0)
   6425 				{
   6426 					return i;
   6427 				}
   6428 			}
   6429 		}
   6430 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensionsUsed") == 0)
   6431 		{
   6432 			i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_data->extensions_used, &out_data->extensions_used_count);
   6433 		}
   6434 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensionsRequired") == 0)
   6435 		{
   6436 			i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_data->extensions_required, &out_data->extensions_required_count);
   6437 		}
   6438 		else
   6439 		{
   6440 			i = cgltf_skip_json(tokens, i + 1);
   6441 		}
   6442 
   6443 		if (i < 0)
   6444 		{
   6445 			return i;
   6446 		}
   6447 	}
   6448 
   6449 	return i;
   6450 }
   6451 
   6452 cgltf_result cgltf_parse_json(cgltf_options* options, const uint8_t* json_chunk, cgltf_size size, cgltf_data** out_data)
   6453 {
   6454 	jsmn_parser parser = { 0, 0, 0 };
   6455 
   6456 	if (options->json_token_count == 0)
   6457 	{
   6458 		int token_count = jsmn_parse(&parser, (const char*)json_chunk, size, NULL, 0);
   6459 
   6460 		if (token_count <= 0)
   6461 		{
   6462 			return cgltf_result_invalid_json;
   6463 		}
   6464 
   6465 		options->json_token_count = token_count;
   6466 	}
   6467 
   6468 	jsmntok_t* tokens = (jsmntok_t*)options->memory.alloc_func(options->memory.user_data, sizeof(jsmntok_t) * (options->json_token_count + 1));
   6469 
   6470 	if (!tokens)
   6471 	{
   6472 		return cgltf_result_out_of_memory;
   6473 	}
   6474 
   6475 	jsmn_init(&parser);
   6476 
   6477 	int token_count = jsmn_parse(&parser, (const char*)json_chunk, size, tokens, options->json_token_count);
   6478 
   6479 	if (token_count <= 0)
   6480 	{
   6481 		options->memory.free_func(options->memory.user_data, tokens);
   6482 		return cgltf_result_invalid_json;
   6483 	}
   6484 
   6485 	// this makes sure that we always have an UNDEFINED token at the end of the stream
   6486 	// for invalid JSON inputs this makes sure we don't perform out of bound reads of token data
   6487 	tokens[token_count].type = JSMN_UNDEFINED;
   6488 
   6489 	cgltf_data* data = (cgltf_data*)options->memory.alloc_func(options->memory.user_data, sizeof(cgltf_data));
   6490 
   6491 	if (!data)
   6492 	{
   6493 		options->memory.free_func(options->memory.user_data, tokens);
   6494 		return cgltf_result_out_of_memory;
   6495 	}
   6496 
   6497 	memset(data, 0, sizeof(cgltf_data));
   6498 	data->memory = options->memory;
   6499 	data->file = options->file;
   6500 
   6501 	int i = cgltf_parse_json_root(options, tokens, 0, json_chunk, data);
   6502 
   6503 	options->memory.free_func(options->memory.user_data, tokens);
   6504 
   6505 	if (i < 0)
   6506 	{
   6507 		cgltf_free(data);
   6508 
   6509 		switch (i)
   6510 		{
   6511 		case CGLTF_ERROR_NOMEM: return cgltf_result_out_of_memory;
   6512 		case CGLTF_ERROR_LEGACY: return cgltf_result_legacy_gltf;
   6513 		default: return cgltf_result_invalid_gltf;
   6514 		}
   6515 	}
   6516 
   6517 	if (cgltf_fixup_pointers(data) < 0)
   6518 	{
   6519 		cgltf_free(data);
   6520 		return cgltf_result_invalid_gltf;
   6521 	}
   6522 
   6523 	data->json = (const char*)json_chunk;
   6524 	data->json_size = size;
   6525 
   6526 	*out_data = data;
   6527 
   6528 	return cgltf_result_success;
   6529 }
   6530 
   6531 static int cgltf_fixup_pointers(cgltf_data* data)
   6532 {
   6533 	for (cgltf_size i = 0; i < data->meshes_count; ++i)
   6534 	{
   6535 		for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
   6536 		{
   6537 			CGLTF_PTRFIXUP(data->meshes[i].primitives[j].indices, data->accessors, data->accessors_count);
   6538 			CGLTF_PTRFIXUP(data->meshes[i].primitives[j].material, data->materials, data->materials_count);
   6539 
   6540 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
   6541 			{
   6542 				CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].attributes[k].data, data->accessors, data->accessors_count);
   6543 			}
   6544 
   6545 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
   6546 			{
   6547 				for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
   6548 				{
   6549 					CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].targets[k].attributes[m].data, data->accessors, data->accessors_count);
   6550 				}
   6551 			}
   6552 
   6553 			if (data->meshes[i].primitives[j].has_draco_mesh_compression)
   6554 			{
   6555 				CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.buffer_view, data->buffer_views, data->buffer_views_count);
   6556 				for (cgltf_size m = 0; m < data->meshes[i].primitives[j].draco_mesh_compression.attributes_count; ++m)
   6557 				{
   6558 					CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.attributes[m].data, data->accessors, data->accessors_count);
   6559 				}
   6560 			}
   6561 
   6562 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
   6563 			{
   6564 				CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].mappings[k].material, data->materials, data->materials_count);
   6565 			}
   6566 		}
   6567 	}
   6568 
   6569 	for (cgltf_size i = 0; i < data->accessors_count; ++i)
   6570 	{
   6571 		CGLTF_PTRFIXUP(data->accessors[i].buffer_view, data->buffer_views, data->buffer_views_count);
   6572 
   6573 		if (data->accessors[i].is_sparse)
   6574 		{
   6575 			CGLTF_PTRFIXUP_REQ(data->accessors[i].sparse.indices_buffer_view, data->buffer_views, data->buffer_views_count);
   6576 			CGLTF_PTRFIXUP_REQ(data->accessors[i].sparse.values_buffer_view, data->buffer_views, data->buffer_views_count);
   6577 		}
   6578 
   6579 		if (data->accessors[i].buffer_view)
   6580 		{
   6581 			data->accessors[i].stride = data->accessors[i].buffer_view->stride;
   6582 		}
   6583 
   6584 		if (data->accessors[i].stride == 0)
   6585 		{
   6586 			data->accessors[i].stride = cgltf_calc_size(data->accessors[i].type, data->accessors[i].component_type);
   6587 		}
   6588 	}
   6589 
   6590 	for (cgltf_size i = 0; i < data->textures_count; ++i)
   6591 	{
   6592 		CGLTF_PTRFIXUP(data->textures[i].image, data->images, data->images_count);
   6593 		CGLTF_PTRFIXUP(data->textures[i].basisu_image, data->images, data->images_count);
   6594 		CGLTF_PTRFIXUP(data->textures[i].webp_image, data->images, data->images_count);
   6595 		CGLTF_PTRFIXUP(data->textures[i].sampler, data->samplers, data->samplers_count);
   6596 	}
   6597 
   6598 	for (cgltf_size i = 0; i < data->images_count; ++i)
   6599 	{
   6600 		CGLTF_PTRFIXUP(data->images[i].buffer_view, data->buffer_views, data->buffer_views_count);
   6601 	}
   6602 
   6603 	for (cgltf_size i = 0; i < data->materials_count; ++i)
   6604 	{
   6605 		CGLTF_PTRFIXUP(data->materials[i].normal_texture.texture, data->textures, data->textures_count);
   6606 		CGLTF_PTRFIXUP(data->materials[i].emissive_texture.texture, data->textures, data->textures_count);
   6607 		CGLTF_PTRFIXUP(data->materials[i].occlusion_texture.texture, data->textures, data->textures_count);
   6608 
   6609 		CGLTF_PTRFIXUP(data->materials[i].pbr_metallic_roughness.base_color_texture.texture, data->textures, data->textures_count);
   6610 		CGLTF_PTRFIXUP(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture, data->textures, data->textures_count);
   6611 
   6612 		CGLTF_PTRFIXUP(data->materials[i].pbr_specular_glossiness.diffuse_texture.texture, data->textures, data->textures_count);
   6613 		CGLTF_PTRFIXUP(data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.texture, data->textures, data->textures_count);
   6614 
   6615 		CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_texture.texture, data->textures, data->textures_count);
   6616 		CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_roughness_texture.texture, data->textures, data->textures_count);
   6617 		CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_normal_texture.texture, data->textures, data->textures_count);
   6618 
   6619 		CGLTF_PTRFIXUP(data->materials[i].specular.specular_texture.texture, data->textures, data->textures_count);
   6620 		CGLTF_PTRFIXUP(data->materials[i].specular.specular_color_texture.texture, data->textures, data->textures_count);
   6621 
   6622 		CGLTF_PTRFIXUP(data->materials[i].transmission.transmission_texture.texture, data->textures, data->textures_count);
   6623 
   6624 		CGLTF_PTRFIXUP(data->materials[i].volume.thickness_texture.texture, data->textures, data->textures_count);
   6625 
   6626 		CGLTF_PTRFIXUP(data->materials[i].sheen.sheen_color_texture.texture, data->textures, data->textures_count);
   6627 		CGLTF_PTRFIXUP(data->materials[i].sheen.sheen_roughness_texture.texture, data->textures, data->textures_count);
   6628 
   6629 		CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_texture.texture, data->textures, data->textures_count);
   6630 		CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_thickness_texture.texture, data->textures, data->textures_count);
   6631 
   6632 		CGLTF_PTRFIXUP(data->materials[i].anisotropy.anisotropy_texture.texture, data->textures, data->textures_count);
   6633 	}
   6634 
   6635 	for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
   6636 	{
   6637 		CGLTF_PTRFIXUP_REQ(data->buffer_views[i].buffer, data->buffers, data->buffers_count);
   6638 
   6639 		if (data->buffer_views[i].has_meshopt_compression)
   6640 		{
   6641 			CGLTF_PTRFIXUP_REQ(data->buffer_views[i].meshopt_compression.buffer, data->buffers, data->buffers_count);
   6642 		}
   6643 	}
   6644 
   6645 	for (cgltf_size i = 0; i < data->skins_count; ++i)
   6646 	{
   6647 		for (cgltf_size j = 0; j < data->skins[i].joints_count; ++j)
   6648 		{
   6649 			CGLTF_PTRFIXUP_REQ(data->skins[i].joints[j], data->nodes, data->nodes_count);
   6650 		}
   6651 
   6652 		CGLTF_PTRFIXUP(data->skins[i].skeleton, data->nodes, data->nodes_count);
   6653 		CGLTF_PTRFIXUP(data->skins[i].inverse_bind_matrices, data->accessors, data->accessors_count);
   6654 	}
   6655 
   6656 	for (cgltf_size i = 0; i < data->nodes_count; ++i)
   6657 	{
   6658 		for (cgltf_size j = 0; j < data->nodes[i].children_count; ++j)
   6659 		{
   6660 			CGLTF_PTRFIXUP_REQ(data->nodes[i].children[j], data->nodes, data->nodes_count);
   6661 
   6662 			if (data->nodes[i].children[j]->parent)
   6663 			{
   6664 				return CGLTF_ERROR_JSON;
   6665 			}
   6666 
   6667 			data->nodes[i].children[j]->parent = &data->nodes[i];
   6668 		}
   6669 
   6670 		CGLTF_PTRFIXUP(data->nodes[i].mesh, data->meshes, data->meshes_count);
   6671 		CGLTF_PTRFIXUP(data->nodes[i].skin, data->skins, data->skins_count);
   6672 		CGLTF_PTRFIXUP(data->nodes[i].camera, data->cameras, data->cameras_count);
   6673 		CGLTF_PTRFIXUP(data->nodes[i].light, data->lights, data->lights_count);
   6674 
   6675 		if (data->nodes[i].has_mesh_gpu_instancing)
   6676 		{
   6677 			for (cgltf_size m = 0; m < data->nodes[i].mesh_gpu_instancing.attributes_count; ++m)
   6678 			{
   6679 				CGLTF_PTRFIXUP_REQ(data->nodes[i].mesh_gpu_instancing.attributes[m].data, data->accessors, data->accessors_count);
   6680 			}
   6681 		}
   6682 	}
   6683 
   6684 	for (cgltf_size i = 0; i < data->scenes_count; ++i)
   6685 	{
   6686 		for (cgltf_size j = 0; j < data->scenes[i].nodes_count; ++j)
   6687 		{
   6688 			CGLTF_PTRFIXUP_REQ(data->scenes[i].nodes[j], data->nodes, data->nodes_count);
   6689 
   6690 			if (data->scenes[i].nodes[j]->parent)
   6691 			{
   6692 				return CGLTF_ERROR_JSON;
   6693 			}
   6694 		}
   6695 	}
   6696 
   6697 	CGLTF_PTRFIXUP(data->scene, data->scenes, data->scenes_count);
   6698 
   6699 	for (cgltf_size i = 0; i < data->animations_count; ++i)
   6700 	{
   6701 		for (cgltf_size j = 0; j < data->animations[i].samplers_count; ++j)
   6702 		{
   6703 			CGLTF_PTRFIXUP_REQ(data->animations[i].samplers[j].input, data->accessors, data->accessors_count);
   6704 			CGLTF_PTRFIXUP_REQ(data->animations[i].samplers[j].output, data->accessors, data->accessors_count);
   6705 		}
   6706 
   6707 		for (cgltf_size j = 0; j < data->animations[i].channels_count; ++j)
   6708 		{
   6709 			CGLTF_PTRFIXUP_REQ(data->animations[i].channels[j].sampler, data->animations[i].samplers, data->animations[i].samplers_count);
   6710 			CGLTF_PTRFIXUP(data->animations[i].channels[j].target_node, data->nodes, data->nodes_count);
   6711 		}
   6712 	}
   6713 
   6714 	return 0;
   6715 }
   6716 
   6717 /*
   6718  * -- jsmn.c start --
   6719  * Source: https://github.com/zserge/jsmn
   6720  * License: MIT
   6721  *
   6722  * Copyright (c) 2010 Serge A. Zaitsev
   6723 
   6724  * Permission is hereby granted, free of charge, to any person obtaining a copy
   6725  * of this software and associated documentation files (the "Software"), to deal
   6726  * in the Software without restriction, including without limitation the rights
   6727  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   6728  * copies of the Software, and to permit persons to whom the Software is
   6729  * furnished to do so, subject to the following conditions:
   6730 
   6731  * The above copyright notice and this permission notice shall be included in
   6732  * all copies or substantial portions of the Software.
   6733 
   6734  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   6735  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   6736  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   6737  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   6738  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   6739  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   6740  * THE SOFTWARE.
   6741  */
   6742 
   6743 /**
   6744  * Allocates a fresh unused token from the token pull.
   6745  */
   6746 static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
   6747 				   jsmntok_t *tokens, size_t num_tokens) {
   6748 	jsmntok_t *tok;
   6749 	if (parser->toknext >= num_tokens) {
   6750 		return NULL;
   6751 	}
   6752 	tok = &tokens[parser->toknext++];
   6753 	tok->start = tok->end = -1;
   6754 	tok->size = 0;
   6755 #ifdef JSMN_PARENT_LINKS
   6756 	tok->parent = -1;
   6757 #endif
   6758 	return tok;
   6759 }
   6760 
   6761 /**
   6762  * Fills token type and boundaries.
   6763  */
   6764 static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
   6765 				ptrdiff_t start, ptrdiff_t end) {
   6766 	token->type = type;
   6767 	token->start = start;
   6768 	token->end = end;
   6769 	token->size = 0;
   6770 }
   6771 
   6772 /**
   6773  * Fills next available token with JSON primitive.
   6774  */
   6775 static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
   6776 				size_t len, jsmntok_t *tokens, size_t num_tokens) {
   6777 	jsmntok_t *token;
   6778 	ptrdiff_t start;
   6779 
   6780 	start = parser->pos;
   6781 
   6782 	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
   6783 		switch (js[parser->pos]) {
   6784 #ifndef JSMN_STRICT
   6785 		/* In strict mode primitive must be followed by "," or "}" or "]" */
   6786 		case ':':
   6787 #endif
   6788 		case '\t' : case '\r' : case '\n' : case ' ' :
   6789 		case ','  : case ']'  : case '}' :
   6790 			goto found;
   6791 		}
   6792 		if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
   6793 			parser->pos = start;
   6794 			return JSMN_ERROR_INVAL;
   6795 		}
   6796 	}
   6797 #ifdef JSMN_STRICT
   6798 	/* In strict mode primitive must be followed by a comma/object/array */
   6799 	parser->pos = start;
   6800 	return JSMN_ERROR_PART;
   6801 #endif
   6802 
   6803 found:
   6804 	if (tokens == NULL) {
   6805 		parser->pos--;
   6806 		return 0;
   6807 	}
   6808 	token = jsmn_alloc_token(parser, tokens, num_tokens);
   6809 	if (token == NULL) {
   6810 		parser->pos = start;
   6811 		return JSMN_ERROR_NOMEM;
   6812 	}
   6813 	jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
   6814 #ifdef JSMN_PARENT_LINKS
   6815 	token->parent = parser->toksuper;
   6816 #endif
   6817 	parser->pos--;
   6818 	return 0;
   6819 }
   6820 
   6821 /**
   6822  * Fills next token with JSON string.
   6823  */
   6824 static int jsmn_parse_string(jsmn_parser *parser, const char *js,
   6825 				 size_t len, jsmntok_t *tokens, size_t num_tokens) {
   6826 	jsmntok_t *token;
   6827 
   6828 	ptrdiff_t start = parser->pos;
   6829 
   6830 	parser->pos++;
   6831 
   6832 	/* Skip starting quote */
   6833 	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
   6834 		char c = js[parser->pos];
   6835 
   6836 		/* Quote: end of string */
   6837 		if (c == '\"') {
   6838 			if (tokens == NULL) {
   6839 				return 0;
   6840 			}
   6841 			token = jsmn_alloc_token(parser, tokens, num_tokens);
   6842 			if (token == NULL) {
   6843 				parser->pos = start;
   6844 				return JSMN_ERROR_NOMEM;
   6845 			}
   6846 			jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
   6847 #ifdef JSMN_PARENT_LINKS
   6848 			token->parent = parser->toksuper;
   6849 #endif
   6850 			return 0;
   6851 		}
   6852 
   6853 		/* Backslash: Quoted symbol expected */
   6854 		if (c == '\\' && parser->pos + 1 < len) {
   6855 			int i;
   6856 			parser->pos++;
   6857 			switch (js[parser->pos]) {
   6858 			/* Allowed escaped symbols */
   6859 			case '\"': case '/' : case '\\' : case 'b' :
   6860 			case 'f' : case 'r' : case 'n'  : case 't' :
   6861 				break;
   6862 				/* Allows escaped symbol \uXXXX */
   6863 			case 'u':
   6864 				parser->pos++;
   6865 				for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) {
   6866 					/* If it isn't a hex character we have an error */
   6867 					if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
   6868 						 (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
   6869 						 (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
   6870 						parser->pos = start;
   6871 						return JSMN_ERROR_INVAL;
   6872 					}
   6873 					parser->pos++;
   6874 				}
   6875 				parser->pos--;
   6876 				break;
   6877 				/* Unexpected symbol */
   6878 			default:
   6879 				parser->pos = start;
   6880 				return JSMN_ERROR_INVAL;
   6881 			}
   6882 		}
   6883 	}
   6884 	parser->pos = start;
   6885 	return JSMN_ERROR_PART;
   6886 }
   6887 
   6888 /**
   6889  * Parse JSON string and fill tokens.
   6890  */
   6891 static int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
   6892 		   jsmntok_t *tokens, size_t num_tokens) {
   6893 	int r;
   6894 	int i;
   6895 	jsmntok_t *token;
   6896 	int count = parser->toknext;
   6897 
   6898 	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
   6899 		char c;
   6900 		jsmntype_t type;
   6901 
   6902 		c = js[parser->pos];
   6903 		switch (c) {
   6904 		case '{': case '[':
   6905 			count++;
   6906 			if (tokens == NULL) {
   6907 				break;
   6908 			}
   6909 			token = jsmn_alloc_token(parser, tokens, num_tokens);
   6910 			if (token == NULL)
   6911 				return JSMN_ERROR_NOMEM;
   6912 			if (parser->toksuper != -1) {
   6913 				tokens[parser->toksuper].size++;
   6914 #ifdef JSMN_PARENT_LINKS
   6915 				token->parent = parser->toksuper;
   6916 #endif
   6917 			}
   6918 			token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
   6919 			token->start = parser->pos;
   6920 			parser->toksuper = parser->toknext - 1;
   6921 			break;
   6922 		case '}': case ']':
   6923 			if (tokens == NULL)
   6924 				break;
   6925 			type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
   6926 #ifdef JSMN_PARENT_LINKS
   6927 			if (parser->toknext < 1) {
   6928 				return JSMN_ERROR_INVAL;
   6929 			}
   6930 			token = &tokens[parser->toknext - 1];
   6931 			for (;;) {
   6932 				if (token->start != -1 && token->end == -1) {
   6933 					if (token->type != type) {
   6934 						return JSMN_ERROR_INVAL;
   6935 					}
   6936 					token->end = parser->pos + 1;
   6937 					parser->toksuper = token->parent;
   6938 					break;
   6939 				}
   6940 				if (token->parent == -1) {
   6941 					if(token->type != type || parser->toksuper == -1) {
   6942 						return JSMN_ERROR_INVAL;
   6943 					}
   6944 					break;
   6945 				}
   6946 				token = &tokens[token->parent];
   6947 			}
   6948 #else
   6949 			for (i = parser->toknext - 1; i >= 0; i--) {
   6950 				token = &tokens[i];
   6951 				if (token->start != -1 && token->end == -1) {
   6952 					if (token->type != type) {
   6953 						return JSMN_ERROR_INVAL;
   6954 					}
   6955 					parser->toksuper = -1;
   6956 					token->end = parser->pos + 1;
   6957 					break;
   6958 				}
   6959 			}
   6960 			/* Error if unmatched closing bracket */
   6961 			if (i == -1) return JSMN_ERROR_INVAL;
   6962 			for (; i >= 0; i--) {
   6963 				token = &tokens[i];
   6964 				if (token->start != -1 && token->end == -1) {
   6965 					parser->toksuper = i;
   6966 					break;
   6967 				}
   6968 			}
   6969 #endif
   6970 			break;
   6971 		case '\"':
   6972 			r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
   6973 			if (r < 0) return r;
   6974 			count++;
   6975 			if (parser->toksuper != -1 && tokens != NULL)
   6976 				tokens[parser->toksuper].size++;
   6977 			break;
   6978 		case '\t' : case '\r' : case '\n' : case ' ':
   6979 			break;
   6980 		case ':':
   6981 			parser->toksuper = parser->toknext - 1;
   6982 			break;
   6983 		case ',':
   6984 			if (tokens != NULL && parser->toksuper != -1 &&
   6985 					tokens[parser->toksuper].type != JSMN_ARRAY &&
   6986 					tokens[parser->toksuper].type != JSMN_OBJECT) {
   6987 #ifdef JSMN_PARENT_LINKS
   6988 				parser->toksuper = tokens[parser->toksuper].parent;
   6989 #else
   6990 				for (i = parser->toknext - 1; i >= 0; i--) {
   6991 					if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
   6992 						if (tokens[i].start != -1 && tokens[i].end == -1) {
   6993 							parser->toksuper = i;
   6994 							break;
   6995 						}
   6996 					}
   6997 				}
   6998 #endif
   6999 			}
   7000 			break;
   7001 #ifdef JSMN_STRICT
   7002 			/* In strict mode primitives are: numbers and booleans */
   7003 		case '-': case '0': case '1' : case '2': case '3' : case '4':
   7004 		case '5': case '6': case '7' : case '8': case '9':
   7005 		case 't': case 'f': case 'n' :
   7006 			/* And they must not be keys of the object */
   7007 			if (tokens != NULL && parser->toksuper != -1) {
   7008 				jsmntok_t *t = &tokens[parser->toksuper];
   7009 				if (t->type == JSMN_OBJECT ||
   7010 						(t->type == JSMN_STRING && t->size != 0)) {
   7011 					return JSMN_ERROR_INVAL;
   7012 				}
   7013 			}
   7014 #else
   7015 			/* In non-strict mode every unquoted value is a primitive */
   7016 		default:
   7017 #endif
   7018 			r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
   7019 			if (r < 0) return r;
   7020 			count++;
   7021 			if (parser->toksuper != -1 && tokens != NULL)
   7022 				tokens[parser->toksuper].size++;
   7023 			break;
   7024 
   7025 #ifdef JSMN_STRICT
   7026 			/* Unexpected char in strict mode */
   7027 		default:
   7028 			return JSMN_ERROR_INVAL;
   7029 #endif
   7030 		}
   7031 	}
   7032 
   7033 	if (tokens != NULL) {
   7034 		for (i = parser->toknext - 1; i >= 0; i--) {
   7035 			/* Unmatched opened object or array */
   7036 			if (tokens[i].start != -1 && tokens[i].end == -1) {
   7037 				return JSMN_ERROR_PART;
   7038 			}
   7039 		}
   7040 	}
   7041 
   7042 	return count;
   7043 }
   7044 
   7045 /**
   7046  * Creates a new parser based over a given  buffer with an array of tokens
   7047  * available.
   7048  */
   7049 static void jsmn_init(jsmn_parser *parser) {
   7050 	parser->pos = 0;
   7051 	parser->toknext = 0;
   7052 	parser->toksuper = -1;
   7053 }
   7054 /*
   7055  * -- jsmn.c end --
   7056  */
   7057 
   7058 #endif /* #ifdef CGLTF_IMPLEMENTATION */
   7059 
   7060 /* cgltf is distributed under MIT license:
   7061  *
   7062  * Copyright (c) 2018-2021 Johannes Kuhlmann
   7063 
   7064  * Permission is hereby granted, free of charge, to any person obtaining a copy
   7065  * of this software and associated documentation files (the "Software"), to deal
   7066  * in the Software without restriction, including without limitation the rights
   7067  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   7068  * copies of the Software, and to permit persons to whom the Software is
   7069  * furnished to do so, subject to the following conditions:
   7070 
   7071  * The above copyright notice and this permission notice shall be included in all
   7072  * copies or substantial portions of the Software.
   7073 
   7074  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   7075  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   7076  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   7077  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   7078  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   7079  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   7080  * SOFTWARE.
   7081  */