medfall

A super great game engine
Log | Files | Refs

cgltf.h (117448B)


      1 /**
      2  * cgltf - a single-file glTF 2.0 parser written in C99.
      3  *
      4  * Version: 1.1
      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 callbacks. Should be zero-initialized
     28  * 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  * and may be useful if you're not dealing with normal files.
     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_read_float` reads a certain element from an accessor and converts it to
     62  * floating point, assuming that `cgltf_load_buffers` has already been called. The passed-in element
     63  * size is the number of floats in the output buffer, which should be in the range [1, 16]. Returns
     64  * false if the passed-in element_size is too small, or if the accessor is sparse.
     65  *
     66  * `cgltf_accessor_read_index` is similar to its floating-point counterpart, but it returns size_t
     67  * and only works with single-component data types.
     68  */
     69 #ifndef CGLTF_H_INCLUDED__
     70 #define CGLTF_H_INCLUDED__
     71 
     72 #include <stddef.h>
     73 
     74 #ifdef __cplusplus
     75 extern "C" {
     76 #endif
     77 
     78 typedef size_t cgltf_size;
     79 typedef float cgltf_float;
     80 typedef int cgltf_int;
     81 typedef int cgltf_bool;
     82 
     83 typedef enum cgltf_file_type
     84 {
     85 	cgltf_file_type_invalid,
     86 	cgltf_file_type_gltf,
     87 	cgltf_file_type_glb,
     88 } cgltf_file_type;
     89 
     90 typedef struct cgltf_options
     91 {
     92 	cgltf_file_type type; /* invalid == auto detect */
     93 	cgltf_size json_token_count; /* 0 == auto */
     94 	void* (*memory_alloc)(void* user, cgltf_size size);
     95 	void (*memory_free) (void* user, void* ptr);
     96 	void* memory_user_data;
     97 } cgltf_options;
     98 
     99 typedef enum cgltf_result
    100 {
    101 	cgltf_result_success,
    102 	cgltf_result_data_too_short,
    103 	cgltf_result_unknown_format,
    104 	cgltf_result_invalid_json,
    105 	cgltf_result_invalid_gltf,
    106 	cgltf_result_invalid_options,
    107 	cgltf_result_file_not_found,
    108 	cgltf_result_io_error,
    109 	cgltf_result_out_of_memory,
    110 } cgltf_result;
    111 
    112 typedef enum cgltf_buffer_view_type
    113 {
    114 	cgltf_buffer_view_type_invalid,
    115 	cgltf_buffer_view_type_indices,
    116 	cgltf_buffer_view_type_vertices,
    117 } cgltf_buffer_view_type;
    118 
    119 typedef enum cgltf_attribute_type
    120 {
    121 	cgltf_attribute_type_invalid,
    122 	cgltf_attribute_type_position,
    123 	cgltf_attribute_type_normal,
    124 	cgltf_attribute_type_tangent,
    125 	cgltf_attribute_type_texcoord,
    126 	cgltf_attribute_type_color,
    127 	cgltf_attribute_type_joints,
    128 	cgltf_attribute_type_weights,
    129 } cgltf_attribute_type;
    130 
    131 typedef enum cgltf_component_type
    132 {
    133 	cgltf_component_type_invalid,
    134 	cgltf_component_type_r_8, /* BYTE */
    135 	cgltf_component_type_r_8u, /* UNSIGNED_BYTE */
    136 	cgltf_component_type_r_16, /* SHORT */
    137 	cgltf_component_type_r_16u, /* UNSIGNED_SHORT */
    138 	cgltf_component_type_r_32u, /* UNSIGNED_INT */
    139 	cgltf_component_type_r_32f, /* FLOAT */
    140 } cgltf_component_type;
    141 
    142 typedef enum cgltf_type
    143 {
    144 	cgltf_type_invalid,
    145 	cgltf_type_scalar,
    146 	cgltf_type_vec2,
    147 	cgltf_type_vec3,
    148 	cgltf_type_vec4,
    149 	cgltf_type_mat2,
    150 	cgltf_type_mat3,
    151 	cgltf_type_mat4,
    152 } cgltf_type;
    153 
    154 typedef enum cgltf_primitive_type
    155 {
    156 	cgltf_primitive_type_points,
    157 	cgltf_primitive_type_lines,
    158 	cgltf_primitive_type_line_loop,
    159 	cgltf_primitive_type_line_strip,
    160 	cgltf_primitive_type_triangles,
    161 	cgltf_primitive_type_triangle_strip,
    162 	cgltf_primitive_type_triangle_fan,
    163 } cgltf_primitive_type;
    164 
    165 typedef enum cgltf_alpha_mode
    166 {
    167 	cgltf_alpha_mode_opaque,
    168 	cgltf_alpha_mode_mask,
    169 	cgltf_alpha_mode_blend,
    170 } cgltf_alpha_mode;
    171 
    172 typedef enum cgltf_animation_path_type {
    173 	cgltf_animation_path_type_invalid,
    174 	cgltf_animation_path_type_translation,
    175 	cgltf_animation_path_type_rotation,
    176 	cgltf_animation_path_type_scale,
    177 	cgltf_animation_path_type_weights,
    178 } cgltf_animation_path_type;
    179 
    180 typedef enum cgltf_interpolation_type {
    181 	cgltf_interpolation_type_linear,
    182 	cgltf_interpolation_type_step,
    183 	cgltf_interpolation_type_cubic_spline,
    184 } cgltf_interpolation_type;
    185 
    186 typedef enum cgltf_camera_type {
    187 	cgltf_camera_type_invalid,
    188 	cgltf_camera_type_perspective,
    189 	cgltf_camera_type_orthographic,
    190 } cgltf_camera_type;
    191 
    192 typedef enum cgltf_light_type {
    193 	cgltf_light_type_invalid,
    194 	cgltf_light_type_directional,
    195 	cgltf_light_type_point,
    196 	cgltf_light_type_spot,
    197 } cgltf_light_type;
    198 
    199 typedef struct cgltf_buffer
    200 {
    201 	cgltf_size size;
    202 	char* uri;
    203 	void* data; /* loaded by cgltf_load_buffers */
    204 } cgltf_buffer;
    205 
    206 typedef struct cgltf_buffer_view
    207 {
    208 	cgltf_buffer* buffer;
    209 	cgltf_size offset;
    210 	cgltf_size size;
    211 	cgltf_size stride; /* 0 == automatically determined by accessor */
    212 	cgltf_buffer_view_type type;
    213 } cgltf_buffer_view;
    214 
    215 typedef struct cgltf_accessor_sparse
    216 {
    217 	cgltf_size count;
    218 	cgltf_buffer_view* indices_buffer_view;
    219 	cgltf_size indices_byte_offset;
    220 	cgltf_component_type indices_component_type;
    221 	cgltf_buffer_view* values_buffer_view;
    222 	cgltf_size values_byte_offset;
    223 } cgltf_accessor_sparse;
    224 
    225 typedef struct cgltf_accessor
    226 {
    227 	cgltf_component_type component_type;
    228 	cgltf_bool normalized;
    229 	cgltf_type type;
    230 	cgltf_size offset;
    231 	cgltf_size count;
    232 	cgltf_size stride;
    233 	cgltf_buffer_view* buffer_view;
    234 	cgltf_bool has_min;
    235 	cgltf_float min[16];
    236 	cgltf_bool has_max;
    237 	cgltf_float max[16];
    238 	cgltf_bool is_sparse;
    239 	cgltf_accessor_sparse sparse;
    240 } cgltf_accessor;
    241 
    242 typedef struct cgltf_attribute
    243 {
    244 	char* name;
    245 	cgltf_attribute_type type;
    246 	cgltf_int index;
    247 	cgltf_accessor* data;
    248 } cgltf_attribute;
    249 
    250 typedef struct cgltf_image 
    251 {
    252 	char* name;
    253 	char* uri;
    254 	cgltf_buffer_view* buffer_view;
    255 	char* mime_type;
    256 } cgltf_image;
    257 
    258 typedef struct cgltf_sampler
    259 {
    260 	cgltf_int mag_filter;
    261 	cgltf_int min_filter;
    262 	cgltf_int wrap_s;
    263 	cgltf_int wrap_t;
    264 } cgltf_sampler;
    265 
    266 typedef struct cgltf_texture
    267 {
    268 	char* name;
    269 	cgltf_image* image;
    270 	cgltf_sampler* sampler;
    271 } cgltf_texture;
    272 
    273 typedef struct cgltf_texture_transform
    274 {
    275 	cgltf_float offset[2];
    276 	cgltf_float rotation;
    277 	cgltf_float scale[2];
    278 	cgltf_int texcoord;
    279 } cgltf_texture_transform;
    280 
    281 typedef struct cgltf_texture_view
    282 {	
    283 	cgltf_texture* texture;
    284 	cgltf_int texcoord;
    285 	cgltf_float scale; /* equivalent to strength for occlusion_texture */
    286 	cgltf_bool has_transform;
    287 	cgltf_texture_transform transform;
    288 } cgltf_texture_view;
    289 
    290 typedef struct cgltf_pbr_metallic_roughness
    291 {
    292 	cgltf_texture_view base_color_texture;
    293 	cgltf_texture_view metallic_roughness_texture;
    294 
    295 	cgltf_float base_color_factor[4];
    296 	cgltf_float metallic_factor;
    297 	cgltf_float roughness_factor;
    298 } cgltf_pbr_metallic_roughness;
    299 
    300 typedef struct cgltf_pbr_specular_glossiness
    301 {
    302 	cgltf_texture_view diffuse_texture;
    303 	cgltf_texture_view specular_glossiness_texture;
    304 
    305 	cgltf_float diffuse_factor[4];
    306 	cgltf_float specular_factor[3];
    307 	cgltf_float glossiness_factor;
    308 } cgltf_pbr_specular_glossiness;
    309 
    310 typedef struct cgltf_material
    311 {
    312 	char* name;
    313 	cgltf_bool has_pbr_metallic_roughness;
    314 	cgltf_bool has_pbr_specular_glossiness;
    315 	cgltf_pbr_metallic_roughness pbr_metallic_roughness;
    316 	cgltf_pbr_specular_glossiness pbr_specular_glossiness;
    317 	cgltf_texture_view normal_texture;
    318 	cgltf_texture_view occlusion_texture;
    319 	cgltf_texture_view emissive_texture;
    320 	cgltf_float emissive_factor[3];
    321 	cgltf_alpha_mode alpha_mode;
    322 	cgltf_float alpha_cutoff;
    323 	cgltf_bool double_sided;
    324 	cgltf_bool unlit;
    325 } cgltf_material;
    326 
    327 typedef struct cgltf_morph_target {
    328 	cgltf_attribute* attributes;
    329 	cgltf_size attributes_count;
    330 } cgltf_morph_target;
    331 
    332 typedef struct cgltf_primitive {
    333 	cgltf_primitive_type type;
    334 	cgltf_accessor* indices;
    335 	cgltf_material* material;
    336 	cgltf_attribute* attributes;
    337 	cgltf_size attributes_count;
    338 	cgltf_morph_target* targets;
    339 	cgltf_size targets_count;
    340 } cgltf_primitive;
    341 
    342 typedef struct cgltf_mesh {
    343 	char* name;
    344 	cgltf_primitive* primitives;
    345 	cgltf_size primitives_count;
    346 	cgltf_float* weights;
    347 	cgltf_size weights_count;
    348 } cgltf_mesh;
    349 
    350 typedef struct cgltf_node cgltf_node;
    351 
    352 typedef struct cgltf_skin {
    353 	char* name;
    354 	cgltf_node** joints;
    355 	cgltf_size joints_count;
    356 	cgltf_node* skeleton;
    357 	cgltf_accessor* inverse_bind_matrices;
    358 } cgltf_skin;
    359 
    360 typedef struct cgltf_camera_perspective {
    361 	cgltf_float aspect_ratio;
    362 	cgltf_float yfov;
    363 	cgltf_float zfar;
    364 	cgltf_float znear;
    365 } cgltf_camera_perspective;
    366 
    367 typedef struct cgltf_camera_orthographic {
    368 	cgltf_float xmag;
    369 	cgltf_float ymag;
    370 	cgltf_float zfar;
    371 	cgltf_float znear;
    372 } cgltf_camera_orthographic;
    373 
    374 typedef struct cgltf_camera {
    375 	char* name;
    376 	cgltf_camera_type type;
    377 	union {
    378 		cgltf_camera_perspective perspective;
    379 		cgltf_camera_orthographic orthographic;
    380 	};
    381 } cgltf_camera;
    382 
    383 typedef struct cgltf_light {
    384 	char* name;
    385 	cgltf_float color[3];
    386 	cgltf_float intensity;
    387 	cgltf_light_type type;
    388 	cgltf_float range;
    389 	cgltf_float spot_inner_cone_angle;
    390 	cgltf_float spot_outer_cone_angle;
    391 } cgltf_light;
    392 
    393 typedef struct cgltf_node {
    394 	char* name;
    395 	cgltf_node* parent;
    396 	cgltf_node** children;
    397 	cgltf_size children_count;
    398 	cgltf_skin* skin;
    399 	cgltf_mesh* mesh;
    400 	cgltf_camera* camera;
    401 	cgltf_light* light;
    402 	cgltf_float* weights;
    403 	cgltf_size weights_count;
    404 	cgltf_bool has_translation;
    405 	cgltf_bool has_rotation;
    406 	cgltf_bool has_scale;
    407 	cgltf_bool has_matrix;
    408 	cgltf_float translation[3];
    409 	cgltf_float rotation[4];
    410 	cgltf_float scale[3];
    411 	cgltf_float matrix[16];
    412 } cgltf_node;
    413 
    414 typedef struct cgltf_scene {
    415 	char* name;
    416 	cgltf_node** nodes;
    417 	cgltf_size nodes_count;
    418 } cgltf_scene;
    419 
    420 typedef struct cgltf_animation_sampler {
    421 	cgltf_accessor* input;
    422 	cgltf_accessor* output;
    423 	cgltf_interpolation_type interpolation;
    424 } cgltf_animation_sampler;
    425 
    426 typedef struct cgltf_animation_channel {
    427 	cgltf_animation_sampler* sampler;
    428 	cgltf_node* target_node;
    429 	cgltf_animation_path_type target_path;
    430 } cgltf_animation_channel;
    431 
    432 typedef struct cgltf_animation {
    433 	char* name;
    434 	cgltf_animation_sampler* samplers;
    435 	cgltf_size samplers_count;
    436 	cgltf_animation_channel* channels;
    437 	cgltf_size channels_count;
    438 } cgltf_animation;
    439 
    440 typedef struct cgltf_asset {
    441 	char* copyright;
    442 	char* generator;
    443 	char* version;
    444 	char* min_version;
    445 } cgltf_asset;
    446 
    447 typedef struct cgltf_data
    448 {
    449 	cgltf_file_type file_type;
    450 	void* file_data;
    451 
    452 	cgltf_asset asset;
    453 
    454 	cgltf_mesh* meshes;
    455 	cgltf_size meshes_count;
    456 
    457 	cgltf_material* materials;
    458 	cgltf_size materials_count;
    459 
    460 	cgltf_accessor* accessors;
    461 	cgltf_size accessors_count;
    462 
    463 	cgltf_buffer_view* buffer_views;
    464 	cgltf_size buffer_views_count;
    465 
    466 	cgltf_buffer* buffers;
    467 	cgltf_size buffers_count;
    468 
    469 	cgltf_image* images;
    470 	cgltf_size images_count;
    471 
    472 	cgltf_texture* textures;
    473 	cgltf_size textures_count;
    474 
    475 	cgltf_sampler* samplers;
    476 	cgltf_size samplers_count;
    477 
    478 	cgltf_skin* skins;
    479 	cgltf_size skins_count;
    480 
    481 	cgltf_camera* cameras;
    482 	cgltf_size cameras_count;
    483 
    484 	cgltf_light* lights;
    485 	cgltf_size lights_count;
    486 
    487 	cgltf_node* nodes;
    488 	cgltf_size nodes_count;
    489 
    490 	cgltf_scene* scenes;
    491 	cgltf_size scenes_count;
    492 
    493 	cgltf_scene* scene;
    494 
    495 	cgltf_animation* animations;
    496 	cgltf_size animations_count;
    497 
    498 	const void* bin;
    499 	cgltf_size bin_size;
    500 
    501 	void (*memory_free) (void* user, void* ptr);
    502 	void* memory_user_data;
    503 } cgltf_data;
    504 
    505 cgltf_result cgltf_parse(
    506 		const cgltf_options* options,
    507 		const void* data,
    508 		cgltf_size size,
    509 		cgltf_data** out_data);
    510 
    511 cgltf_result cgltf_parse_file(
    512 		const cgltf_options* options,
    513 		const char* path,
    514 		cgltf_data** out_data);
    515 
    516 cgltf_result cgltf_load_buffers(
    517 		const cgltf_options* options,
    518 		cgltf_data* data,
    519 		const char* gltf_path);
    520 
    521 
    522 cgltf_result cgltf_load_buffer_base64(const cgltf_options* options, cgltf_size size, const char* base64, void** out_data);
    523 
    524 cgltf_result cgltf_validate(
    525 		cgltf_data* data);
    526 
    527 void cgltf_free(cgltf_data* data);
    528 
    529 void cgltf_node_transform_local(const cgltf_node* node, cgltf_float* out_matrix);
    530 void cgltf_node_transform_world(const cgltf_node* node, cgltf_float* out_matrix);
    531 
    532 cgltf_bool cgltf_accessor_read_float(const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size);
    533 cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size index);
    534 
    535 #ifdef __cplusplus
    536 }
    537 #endif
    538 
    539 #endif /* #ifndef CGLTF_H_INCLUDED__ */
    540 
    541 /*
    542  *
    543  * Stop now, if you are only interested in the API.
    544  * Below, you find the implementation.
    545  *
    546  */
    547 
    548 #ifdef __INTELLISENSE__
    549 /* This makes MSVC intellisense work. */
    550 #define CGLTF_IMPLEMENTATION
    551 #endif
    552 
    553 #ifdef CGLTF_IMPLEMENTATION
    554 
    555 #include <stdint.h> /* For uint8_t, uint32_t */
    556 #include <string.h> /* For strncpy */
    557 #include <stdlib.h> /* For malloc, free */
    558 #include <stdio.h>  /* For fopen */
    559 #include <limits.h> /* For UINT_MAX etc */
    560 
    561 /*
    562  * -- jsmn.h start --
    563  * Source: https://github.com/zserge/jsmn
    564  * License: MIT
    565  */
    566 typedef enum {
    567 	JSMN_UNDEFINED = 0,
    568 	JSMN_OBJECT = 1,
    569 	JSMN_ARRAY = 2,
    570 	JSMN_STRING = 3,
    571 	JSMN_PRIMITIVE = 4
    572 } jsmntype_t;
    573 enum jsmnerr {
    574 	/* Not enough tokens were provided */
    575 	JSMN_ERROR_NOMEM = -1,
    576 	/* Invalid character inside JSON string */
    577 	JSMN_ERROR_INVAL = -2,
    578 	/* The string is not a full JSON packet, more bytes expected */
    579 	JSMN_ERROR_PART = -3
    580 };
    581 typedef struct {
    582 	jsmntype_t type;
    583 	int start;
    584 	int end;
    585 	int size;
    586 #ifdef JSMN_PARENT_LINKS
    587 	int parent;
    588 #endif
    589 } jsmntok_t;
    590 typedef struct {
    591 	unsigned int pos; /* offset in the JSON string */
    592 	unsigned int toknext; /* next token to allocate */
    593 	int toksuper; /* superior token node, e.g parent object or array */
    594 } jsmn_parser;
    595 static void jsmn_init(jsmn_parser *parser);
    596 static int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, jsmntok_t *tokens, size_t num_tokens);
    597 /*
    598  * -- jsmn.h end --
    599  */
    600 
    601 
    602 static const cgltf_size GlbHeaderSize = 12;
    603 static const cgltf_size GlbChunkHeaderSize = 8;
    604 static const uint32_t GlbVersion = 2;
    605 static const uint32_t GlbMagic = 0x46546C67;
    606 static const uint32_t GlbMagicJsonChunk = 0x4E4F534A;
    607 static const uint32_t GlbMagicBinChunk = 0x004E4942;
    608 
    609 static void* cgltf_default_alloc(void* user, cgltf_size size)
    610 {
    611 	(void)user;
    612 	return malloc(size);
    613 }
    614 
    615 static void cgltf_default_free(void* user, void* ptr)
    616 {
    617 	(void)user;
    618 	free(ptr);
    619 }
    620 
    621 static void* cgltf_calloc(cgltf_options* options, size_t element_size, cgltf_size count)
    622 {
    623 	if (SIZE_MAX / element_size < count)
    624 	{
    625 		return NULL;
    626 	}
    627 	void* result = options->memory_alloc(options->memory_user_data, element_size * count);
    628 	if (!result)
    629 	{
    630 		return NULL;
    631 	}
    632 	memset(result, 0, element_size * count);
    633 	return result;
    634 }
    635 
    636 static cgltf_result cgltf_parse_json(cgltf_options* options, const uint8_t* json_chunk, cgltf_size size, cgltf_data** out_data);
    637 
    638 cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_size size, cgltf_data** out_data)
    639 {
    640 	if (size < GlbHeaderSize)
    641 	{
    642 		return cgltf_result_data_too_short;
    643 	}
    644 
    645 	if (options == NULL)
    646 	{
    647 		return cgltf_result_invalid_options;
    648 	}
    649 
    650 	cgltf_options fixed_options = *options;
    651 	if (fixed_options.memory_alloc == NULL)
    652 	{
    653 		fixed_options.memory_alloc = &cgltf_default_alloc;
    654 	}
    655 	if (fixed_options.memory_free == NULL)
    656 	{
    657 		fixed_options.memory_free = &cgltf_default_free;
    658 	}
    659 
    660 	uint32_t tmp;
    661 	// Magic
    662 	memcpy(&tmp, data, 4);
    663 	if (tmp != GlbMagic)
    664 	{
    665 		if (fixed_options.type == cgltf_file_type_invalid)
    666 		{
    667 			fixed_options.type = cgltf_file_type_gltf;
    668 		}
    669 		else if (fixed_options.type == cgltf_file_type_glb)
    670 		{
    671 			return cgltf_result_unknown_format;
    672 		}
    673 	}
    674 
    675 	if (fixed_options.type == cgltf_file_type_gltf)
    676 	{
    677 		cgltf_result json_result = cgltf_parse_json(&fixed_options, (const uint8_t*)data, size, out_data);
    678 		if (json_result != cgltf_result_success)
    679 		{
    680 			return json_result;
    681 		}
    682 
    683 		(*out_data)->file_type = cgltf_file_type_gltf;
    684 
    685 		return cgltf_result_success;
    686 	}
    687 
    688 	const uint8_t* ptr = (const uint8_t*)data;
    689 	// Version
    690 	memcpy(&tmp, ptr + 4, 4);
    691 	uint32_t version = tmp;
    692 	if (version != GlbVersion)
    693 	{
    694 		return cgltf_result_unknown_format;
    695 	}
    696 
    697 	// Total length
    698 	memcpy(&tmp, ptr + 8, 4);
    699 	if (tmp > size)
    700 	{
    701 		return cgltf_result_data_too_short;
    702 	}
    703 
    704 	const uint8_t* json_chunk = ptr + GlbHeaderSize;
    705 
    706 	if (GlbHeaderSize + GlbChunkHeaderSize > size)
    707 	{
    708 		return cgltf_result_data_too_short;
    709 	}
    710 
    711 	// JSON chunk: length
    712 	uint32_t json_length;
    713 	memcpy(&json_length, json_chunk, 4);
    714 	if (GlbHeaderSize + GlbChunkHeaderSize + json_length > size)
    715 	{
    716 		return cgltf_result_data_too_short;
    717 	}
    718 
    719 	// JSON chunk: magic
    720 	memcpy(&tmp, json_chunk + 4, 4);
    721 	if (tmp != GlbMagicJsonChunk)
    722 	{
    723 		return cgltf_result_unknown_format;
    724 	}
    725 
    726 	json_chunk += GlbChunkHeaderSize;
    727 
    728 	const void* bin = 0;
    729 	cgltf_size bin_size = 0;
    730 
    731 	if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size)
    732 	{
    733 		// We can read another chunk
    734 		const uint8_t* bin_chunk = json_chunk + json_length;
    735 
    736 		// Bin chunk: length
    737 		uint32_t bin_length;
    738 		memcpy(&bin_length, bin_chunk, 4);
    739 		if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize + bin_length > size)
    740 		{
    741 			return cgltf_result_data_too_short;
    742 		}
    743 
    744 		// Bin chunk: magic
    745 		memcpy(&tmp, bin_chunk + 4, 4);
    746 		if (tmp != GlbMagicBinChunk)
    747 		{
    748 			return cgltf_result_unknown_format;
    749 		}
    750 
    751 		bin_chunk += GlbChunkHeaderSize;
    752 
    753 		bin = bin_chunk;
    754 		bin_size = bin_length;
    755 	}
    756 
    757 	cgltf_result json_result = cgltf_parse_json(&fixed_options, json_chunk, json_length, out_data);
    758 	if (json_result != cgltf_result_success)
    759 	{
    760 		return json_result;
    761 	}
    762 
    763 	(*out_data)->file_type = cgltf_file_type_glb;
    764 	(*out_data)->bin = bin;
    765 	(*out_data)->bin_size = bin_size;
    766 
    767 	return cgltf_result_success;
    768 }
    769 
    770 cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cgltf_data** out_data)
    771 {
    772 	if (options == NULL)
    773 	{
    774 		return cgltf_result_invalid_options;
    775 	}
    776 
    777 	void* (*memory_alloc)(void*, cgltf_size) = options->memory_alloc ? options->memory_alloc : &cgltf_default_alloc;
    778 	void (*memory_free)(void*, void*) = options->memory_free ? options->memory_free : &cgltf_default_free;
    779 
    780 	FILE* file = fopen(path, "rb");
    781 	if (!file)
    782 	{
    783 		return cgltf_result_file_not_found;
    784 	}
    785 
    786 	fseek(file, 0, SEEK_END);
    787 
    788 	long length = ftell(file);
    789 	if (length < 0)
    790 	{
    791 		fclose(file);
    792 		return cgltf_result_io_error;
    793 	}
    794 
    795 	fseek(file, 0, SEEK_SET);
    796 
    797 	char* file_data = (char*)memory_alloc(options->memory_user_data, length);
    798 	if (!file_data)
    799 	{
    800 		fclose(file);
    801 		return cgltf_result_out_of_memory;
    802 	}
    803 
    804 	cgltf_size file_size = (cgltf_size)length;
    805 	cgltf_size read_size = fread(file_data, 1, file_size, file);
    806 
    807 	fclose(file);
    808 
    809 	if (read_size != file_size)
    810 	{
    811 		memory_free(options->memory_user_data, file_data);
    812 		return cgltf_result_io_error;
    813 	}
    814 
    815 	cgltf_result result = cgltf_parse(options, file_data, file_size, out_data);
    816 
    817 	if (result != cgltf_result_success)
    818 	{
    819 		memory_free(options->memory_user_data, file_data);
    820 		return result;
    821 	}
    822 
    823 	(*out_data)->file_data = file_data;
    824 
    825 	return cgltf_result_success;
    826 }
    827 
    828 static void cgltf_combine_paths(char* path, const char* base, const char* uri)
    829 {
    830 	const char* s0 = strrchr(base, '/');
    831 	const char* s1 = strrchr(base, '\\');
    832 	const char* slash = s0 ? (s1 && s1 > s0 ? s1 : s0) : s1;
    833 
    834 	if (slash)
    835 	{
    836 		size_t prefix = slash - base + 1;
    837 
    838 		strncpy(path, base, prefix);
    839 		strcpy(path + prefix, uri);
    840 	}
    841 	else
    842 	{
    843 		strcpy(path, base);
    844 	}
    845 }
    846 
    847 static cgltf_result cgltf_load_buffer_file(const cgltf_options* options, cgltf_size size, const char* uri, const char* gltf_path, void** out_data)
    848 {
    849 	void* (*memory_alloc)(void*, cgltf_size) = options->memory_alloc ? options->memory_alloc : &cgltf_default_alloc;
    850 	void (*memory_free)(void*, void*) = options->memory_free ? options->memory_free : &cgltf_default_free;
    851 
    852 	char* path = (char*)memory_alloc(options->memory_user_data, strlen(uri) + strlen(gltf_path) + 1);
    853 	if (!path)
    854 	{
    855 		return cgltf_result_out_of_memory;
    856 	}
    857 
    858 	cgltf_combine_paths(path, gltf_path, uri);
    859 
    860 	FILE* file = fopen(path, "rb");
    861 
    862 	memory_free(options->memory_user_data, path);
    863 
    864 	if (!file)
    865 	{
    866 		return cgltf_result_file_not_found;
    867 	}
    868 
    869 	char* file_data = (char*)memory_alloc(options->memory_user_data, size);
    870 	if (!file_data)
    871 	{
    872 		fclose(file);
    873 		return cgltf_result_out_of_memory;
    874 	}
    875 
    876 	cgltf_size read_size = fread(file_data, 1, size, file);
    877 
    878 	fclose(file);
    879 
    880 	if (read_size != size)
    881 	{
    882 		memory_free(options->memory_user_data, file_data);
    883 		return cgltf_result_io_error;
    884 	}
    885 
    886 	*out_data = file_data;
    887 
    888 	return cgltf_result_success;
    889 }
    890 
    891 cgltf_result cgltf_load_buffer_base64(const cgltf_options* options, cgltf_size size, const char* base64, void** out_data)
    892 {
    893 	void* (*memory_alloc)(void*, cgltf_size) = options->memory_alloc ? options->memory_alloc : &cgltf_default_alloc;
    894 	void (*memory_free)(void*, void*) = options->memory_free ? options->memory_free : &cgltf_default_free;
    895 
    896 	unsigned char* data = (unsigned char*)memory_alloc(options->memory_user_data, size);
    897 	if (!data)
    898 	{
    899 		return cgltf_result_out_of_memory;
    900 	}
    901 
    902 	unsigned int buffer = 0;
    903 	unsigned int buffer_bits = 0;
    904 
    905 	for (cgltf_size i = 0; i < size; ++i)
    906 	{
    907 		while (buffer_bits < 8)
    908 		{
    909 			char ch = *base64++;
    910 
    911 			int index =
    912 				(unsigned)(ch - 'A') < 26 ? (ch - 'A') :
    913 				(unsigned)(ch - 'a') < 26 ? (ch - 'a') + 26 :
    914 				(unsigned)(ch - '0') < 10 ? (ch - '0') + 52 :
    915 				ch == '+' ? 62 :
    916 				ch == '/' ? 63 :
    917 				-1;
    918 
    919 			if (index < 0)
    920 			{
    921 				memory_free(options->memory_user_data, data);
    922 				return cgltf_result_io_error;
    923 			}
    924 
    925 			buffer = (buffer << 6) | index;
    926 			buffer_bits += 6;
    927 		}
    928 
    929 		data[i] = (unsigned char)(buffer >> (buffer_bits - 8));
    930 		buffer_bits -= 8;
    931 	}
    932 
    933 	*out_data = data;
    934 
    935 	return cgltf_result_success;
    936 }
    937 
    938 cgltf_result cgltf_load_buffers(const cgltf_options* options, cgltf_data* data, const char* gltf_path)
    939 {
    940 	if (options == NULL)
    941 	{
    942 		return cgltf_result_invalid_options;
    943 	}
    944 
    945 	if (data->buffers_count && data->buffers[0].data == NULL && data->buffers[0].uri == NULL && data->bin)
    946 	{
    947 		if (data->bin_size < data->buffers[0].size)
    948 		{
    949 			return cgltf_result_data_too_short;
    950 		}
    951 
    952 		data->buffers[0].data = (void*)data->bin;
    953 	}
    954 
    955 	for (cgltf_size i = 0; i < data->buffers_count; ++i)
    956 	{
    957 		if (data->buffers[i].data)
    958 		{
    959 			continue;
    960 		}
    961 
    962 		const char* uri = data->buffers[i].uri;
    963 
    964 		if (uri == NULL)
    965 		{
    966 			continue;
    967 		}
    968 
    969 		if (strncmp(uri, "data:", 5) == 0)
    970 		{
    971 			const char* comma = strchr(uri, ',');
    972 
    973 			if (comma && comma - uri >= 7 && strncmp(comma - 7, ";base64", 7) == 0)
    974 			{
    975 				cgltf_result res = cgltf_load_buffer_base64(options, data->buffers[i].size, comma + 1, &data->buffers[i].data);
    976 
    977 				if (res != cgltf_result_success)
    978 				{
    979 					return res;
    980 				}
    981 			}
    982 			else
    983 			{
    984 				return cgltf_result_unknown_format;
    985 			}
    986 		}
    987 		else if (strstr(uri, "://") == NULL)
    988 		{
    989 			cgltf_result res = cgltf_load_buffer_file(options, data->buffers[i].size, uri, gltf_path, &data->buffers[i].data);
    990 
    991 			if (res != cgltf_result_success)
    992 			{
    993 				return res;
    994 			}
    995 		}
    996 		else
    997 		{
    998 			return cgltf_result_unknown_format;
    999 		}
   1000 	}
   1001 
   1002 	return cgltf_result_success;
   1003 }
   1004 
   1005 static cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type);
   1006 
   1007 static cgltf_size cgltf_calc_index_bound(cgltf_buffer_view* buffer_view, cgltf_size offset, cgltf_component_type component_type, cgltf_size count)
   1008 {
   1009 	char* data = (char*)buffer_view->buffer->data + offset + buffer_view->offset;
   1010 	cgltf_size bound = 0;
   1011 
   1012 	switch (component_type)
   1013 	{
   1014 	case cgltf_component_type_r_8u:
   1015 		for (size_t i = 0; i < count; ++i)
   1016 		{
   1017 			cgltf_size v = ((unsigned char*)data)[i];
   1018 			bound = bound > v ? bound : v;
   1019 		}
   1020 		break;
   1021 
   1022 	case cgltf_component_type_r_16u:
   1023 		for (size_t i = 0; i < count; ++i)
   1024 		{
   1025 			cgltf_size v = ((unsigned short*)data)[i];
   1026 			bound = bound > v ? bound : v;
   1027 		}
   1028 		break;
   1029 
   1030 	case cgltf_component_type_r_32u:
   1031 		for (size_t i = 0; i < count; ++i)
   1032 		{
   1033 			cgltf_size v = ((unsigned int*)data)[i];
   1034 			bound = bound > v ? bound : v;
   1035 		}
   1036 		break;
   1037 
   1038 	default:
   1039 		;
   1040 	}
   1041 
   1042 	return bound;
   1043 }
   1044 
   1045 cgltf_result cgltf_validate(cgltf_data* data)
   1046 {
   1047 	for (cgltf_size i = 0; i < data->accessors_count; ++i)
   1048 	{
   1049 		cgltf_accessor* accessor = &data->accessors[i];
   1050 
   1051 		cgltf_size element_size = cgltf_calc_size(accessor->type, accessor->component_type);
   1052 
   1053 		if (accessor->buffer_view)
   1054 		{
   1055 			cgltf_size req_size = accessor->offset + accessor->stride * (accessor->count - 1) + element_size;
   1056 
   1057 			if (accessor->buffer_view->size < req_size)
   1058 			{
   1059 				return cgltf_result_data_too_short;
   1060 			}
   1061 		}
   1062 
   1063 		if (accessor->is_sparse)
   1064 		{
   1065 			cgltf_accessor_sparse* sparse = &accessor->sparse;
   1066 
   1067 			cgltf_size indices_component_size = cgltf_calc_size(cgltf_type_scalar, sparse->indices_component_type);
   1068 			cgltf_size indices_req_size = sparse->indices_byte_offset + indices_component_size * sparse->count;
   1069 			cgltf_size values_req_size = sparse->values_byte_offset + element_size * sparse->count;
   1070 
   1071 			if (sparse->indices_buffer_view->size < indices_req_size ||
   1072 				sparse->values_buffer_view->size < values_req_size)
   1073 			{
   1074 				return cgltf_result_data_too_short;
   1075 			}
   1076 
   1077 			if (sparse->indices_component_type != cgltf_component_type_r_8u &&
   1078 				sparse->indices_component_type != cgltf_component_type_r_16u &&
   1079 				sparse->indices_component_type != cgltf_component_type_r_32u)
   1080 			{
   1081 				return cgltf_result_invalid_gltf;
   1082 			}
   1083 
   1084 			if (sparse->indices_buffer_view->buffer->data)
   1085 			{
   1086 				cgltf_size index_bound = cgltf_calc_index_bound(sparse->indices_buffer_view, sparse->indices_byte_offset, sparse->indices_component_type, sparse->count);
   1087 
   1088 				if (index_bound >= accessor->count)
   1089 				{
   1090 					return cgltf_result_data_too_short;
   1091 				}
   1092 			}
   1093 		}
   1094 	}
   1095 
   1096 	for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
   1097 	{
   1098 		cgltf_size req_size = data->buffer_views[i].offset + data->buffer_views[i].size;
   1099 
   1100 		if (data->buffer_views[i].buffer && data->buffer_views[i].buffer->size < req_size)
   1101 		{
   1102 			return cgltf_result_data_too_short;
   1103 		}
   1104 	}
   1105 
   1106 	for (cgltf_size i = 0; i < data->meshes_count; ++i)
   1107 	{
   1108 		if (data->meshes[i].weights)
   1109 		{
   1110 			if (data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].weights_count)
   1111 			{
   1112 				return cgltf_result_invalid_gltf;
   1113 			}
   1114 		}
   1115 
   1116 		for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
   1117 		{
   1118 			if (data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count)
   1119 			{
   1120 				return cgltf_result_invalid_gltf;
   1121 			}
   1122 
   1123 			if (data->meshes[i].primitives[j].attributes_count)
   1124 			{
   1125 				cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data;
   1126 
   1127 				for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
   1128 				{
   1129 					if (data->meshes[i].primitives[j].attributes[k].data->count != first->count)
   1130 					{
   1131 						return cgltf_result_invalid_gltf;
   1132 					}
   1133 				}
   1134 
   1135 				for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
   1136 				{
   1137 					for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
   1138 					{
   1139 						if (data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count)
   1140 						{
   1141 							return cgltf_result_invalid_gltf;
   1142 						}
   1143 					}
   1144 				}
   1145 
   1146 				cgltf_accessor* indices = data->meshes[i].primitives[j].indices;
   1147 
   1148 				if (indices &&
   1149 					indices->component_type != cgltf_component_type_r_8u &&
   1150 					indices->component_type != cgltf_component_type_r_16u &&
   1151 					indices->component_type != cgltf_component_type_r_32u)
   1152 				{
   1153 					return cgltf_result_invalid_gltf;
   1154 				}
   1155 
   1156 				if (indices && indices->buffer_view && indices->buffer_view->buffer->data)
   1157 				{
   1158 					cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count);
   1159 
   1160 					if (index_bound >= first->count)
   1161 					{
   1162 						return cgltf_result_data_too_short;
   1163 					}
   1164 				}
   1165 			}
   1166 		}
   1167 	}
   1168 
   1169 	for (cgltf_size i = 0; i < data->nodes_count; ++i)
   1170 	{
   1171 		if (data->nodes[i].weights && data->nodes[i].mesh)
   1172 		{
   1173 			if (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count)
   1174 			{
   1175 				return cgltf_result_invalid_gltf;
   1176 			}
   1177 		}
   1178 	}
   1179 
   1180 	return cgltf_result_success;
   1181 }
   1182 
   1183 void cgltf_free(cgltf_data* data)
   1184 {
   1185 	if (!data)
   1186 	{
   1187 		return;
   1188 	}
   1189 
   1190 	data->memory_free(data->memory_user_data, data->asset.copyright);
   1191 	data->memory_free(data->memory_user_data, data->asset.generator);
   1192 	data->memory_free(data->memory_user_data, data->asset.version);
   1193 	data->memory_free(data->memory_user_data, data->asset.min_version);
   1194 
   1195 	data->memory_free(data->memory_user_data, data->accessors);
   1196 	data->memory_free(data->memory_user_data, data->buffer_views);
   1197 
   1198 	for (cgltf_size i = 0; i < data->buffers_count; ++i)
   1199 	{
   1200 		if (data->buffers[i].data != data->bin)
   1201 		{
   1202 			data->memory_free(data->memory_user_data, data->buffers[i].data);
   1203 		}
   1204 
   1205 		data->memory_free(data->memory_user_data, data->buffers[i].uri);
   1206 	}
   1207 
   1208 	data->memory_free(data->memory_user_data, data->buffers);
   1209 
   1210 	for (cgltf_size i = 0; i < data->meshes_count; ++i)
   1211 	{
   1212 		data->memory_free(data->memory_user_data, data->meshes[i].name);
   1213 
   1214 		for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
   1215 		{
   1216 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
   1217 			{
   1218 				data->memory_free(data->memory_user_data, data->meshes[i].primitives[j].attributes[k].name);
   1219 			}
   1220 
   1221 			data->memory_free(data->memory_user_data, data->meshes[i].primitives[j].attributes);
   1222 
   1223 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
   1224 			{
   1225 				for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
   1226 				{
   1227 					data->memory_free(data->memory_user_data, data->meshes[i].primitives[j].targets[k].attributes[m].name);
   1228 				}
   1229 
   1230 				data->memory_free(data->memory_user_data, data->meshes[i].primitives[j].targets[k].attributes);
   1231 			}
   1232 
   1233 			data->memory_free(data->memory_user_data, data->meshes[i].primitives[j].targets);
   1234 		}
   1235 
   1236 		data->memory_free(data->memory_user_data, data->meshes[i].primitives);
   1237 		data->memory_free(data->memory_user_data, data->meshes[i].weights);
   1238 	}
   1239 
   1240 	data->memory_free(data->memory_user_data, data->meshes);
   1241 
   1242 	for (cgltf_size i = 0; i < data->materials_count; ++i)
   1243 	{
   1244 		data->memory_free(data->memory_user_data, data->materials[i].name);
   1245 	}
   1246 
   1247 	data->memory_free(data->memory_user_data, data->materials);
   1248 
   1249 	for (cgltf_size i = 0; i < data->images_count; ++i) 
   1250 	{
   1251 		data->memory_free(data->memory_user_data, data->images[i].name);
   1252 		data->memory_free(data->memory_user_data, data->images[i].uri);
   1253 		data->memory_free(data->memory_user_data, data->images[i].mime_type);
   1254 	}
   1255 
   1256 	data->memory_free(data->memory_user_data, data->images);
   1257 
   1258 	for (cgltf_size i = 0; i < data->textures_count; ++i)
   1259 	{
   1260 		data->memory_free(data->memory_user_data, data->textures[i].name);
   1261 	}
   1262 
   1263 	data->memory_free(data->memory_user_data, data->textures);
   1264 
   1265 	data->memory_free(data->memory_user_data, data->samplers);
   1266 
   1267 	for (cgltf_size i = 0; i < data->skins_count; ++i)
   1268 	{
   1269 		data->memory_free(data->memory_user_data, data->skins[i].name);
   1270 		data->memory_free(data->memory_user_data, data->skins[i].joints);
   1271 	}
   1272 
   1273 	data->memory_free(data->memory_user_data, data->skins);
   1274 
   1275 	for (cgltf_size i = 0; i < data->cameras_count; ++i)
   1276 	{
   1277 		data->memory_free(data->memory_user_data, data->cameras[i].name);
   1278 	}
   1279 
   1280 	data->memory_free(data->memory_user_data, data->cameras);
   1281 
   1282 	for (cgltf_size i = 0; i < data->lights_count; ++i)
   1283 	{
   1284 		data->memory_free(data->memory_user_data, data->lights[i].name);
   1285 	}
   1286 
   1287 	data->memory_free(data->memory_user_data, data->lights);
   1288 
   1289 	for (cgltf_size i = 0; i < data->nodes_count; ++i)
   1290 	{
   1291 		data->memory_free(data->memory_user_data, data->nodes[i].name);
   1292 		data->memory_free(data->memory_user_data, data->nodes[i].children);
   1293 		data->memory_free(data->memory_user_data, data->nodes[i].weights);
   1294 	}
   1295 
   1296 	data->memory_free(data->memory_user_data, data->nodes);
   1297 
   1298 	for (cgltf_size i = 0; i < data->scenes_count; ++i)
   1299 	{
   1300 		data->memory_free(data->memory_user_data, data->scenes[i].name);
   1301 		data->memory_free(data->memory_user_data, data->scenes[i].nodes);
   1302 	}
   1303 
   1304 	data->memory_free(data->memory_user_data, data->scenes);
   1305 
   1306 	for (cgltf_size i = 0; i < data->animations_count; ++i)
   1307 	{
   1308 		data->memory_free(data->memory_user_data, data->animations[i].name);
   1309 		data->memory_free(data->memory_user_data, data->animations[i].samplers);
   1310 		data->memory_free(data->memory_user_data, data->animations[i].channels);
   1311 	}
   1312 
   1313 	data->memory_free(data->memory_user_data, data->animations);
   1314 
   1315 	data->memory_free(data->memory_user_data, data->file_data);
   1316 
   1317 	data->memory_free(data->memory_user_data, data);
   1318 }
   1319 
   1320 void cgltf_node_transform_local(const cgltf_node* node, cgltf_float* out_matrix)
   1321 {
   1322 	cgltf_float* lm = out_matrix;
   1323 
   1324 	if (node->has_matrix)
   1325 	{
   1326 		memcpy(lm, node->matrix, sizeof(float) * 16);
   1327 	}
   1328 	else
   1329 	{
   1330 		float tx = node->translation[0];
   1331 		float ty = node->translation[1];
   1332 		float tz = node->translation[2];
   1333 
   1334 		float qx = node->rotation[0];
   1335 		float qy = node->rotation[1];
   1336 		float qz = node->rotation[2];
   1337 		float qw = node->rotation[3];
   1338 
   1339 		float sx = node->scale[0];
   1340 		float sy = node->scale[1];
   1341 		float sz = node->scale[2];
   1342 
   1343 		lm[0] = (1 - 2 * qy*qy - 2 * qz*qz) * sx;
   1344 		lm[1] = (2 * qx*qy + 2 * qz*qw) * sy;
   1345 		lm[2] = (2 * qx*qz - 2 * qy*qw) * sz;
   1346 		lm[3] = 0.f;
   1347 
   1348 		lm[4] = (2 * qx*qy - 2 * qz*qw) * sx;
   1349 		lm[5] = (1 - 2 * qx*qx - 2 * qz*qz) * sy;
   1350 		lm[6] = (2 * qy*qz + 2 * qx*qw) * sz;
   1351 		lm[7] = 0.f;
   1352 
   1353 		lm[8] = (2 * qx*qz + 2 * qy*qw) * sx;
   1354 		lm[9] = (2 * qy*qz - 2 * qx*qw) * sy;
   1355 		lm[10] = (1 - 2 * qx*qx - 2 * qy*qy) * sz;
   1356 		lm[11] = 0.f;
   1357 
   1358 		lm[12] = tx;
   1359 		lm[13] = ty;
   1360 		lm[14] = tz;
   1361 		lm[15] = 1.f;
   1362 	}
   1363 }
   1364 
   1365 void cgltf_node_transform_world(const cgltf_node* node, cgltf_float* out_matrix)
   1366 {
   1367 	cgltf_float* lm = out_matrix;
   1368 	cgltf_node_transform_local(node, lm);
   1369 
   1370 	const cgltf_node* parent = node->parent;
   1371 
   1372 	while (parent)
   1373 	{
   1374 		float pm[16];
   1375 		cgltf_node_transform_local(parent, pm);
   1376 
   1377 		for (int i = 0; i < 4; ++i)
   1378 		{
   1379 			float l0 = lm[i * 4 + 0];
   1380 			float l1 = lm[i * 4 + 1];
   1381 			float l2 = lm[i * 4 + 2];
   1382 
   1383 			float r0 = l0 * pm[0] + l1 * pm[4] + l2 * pm[8];
   1384 			float r1 = l0 * pm[1] + l1 * pm[5] + l2 * pm[9];
   1385 			float r2 = l0 * pm[2] + l1 * pm[6] + l2 * pm[10];
   1386 
   1387 			lm[i * 4 + 0] = r0;
   1388 			lm[i * 4 + 1] = r1;
   1389 			lm[i * 4 + 2] = r2;
   1390 		}
   1391 
   1392 		lm[12] += pm[12];
   1393 		lm[13] += pm[13];
   1394 		lm[14] += pm[14];
   1395 
   1396 		parent = parent->parent;
   1397 	}
   1398 }
   1399 
   1400 static cgltf_size cgltf_component_read_index(const void* in, cgltf_component_type component_type)
   1401 {
   1402 	switch (component_type)
   1403 	{
   1404 		case cgltf_component_type_r_16:
   1405 			return *((const int16_t*) in);
   1406 		case cgltf_component_type_r_16u:
   1407 			return *((const uint16_t*) in);
   1408 		case cgltf_component_type_r_32u:
   1409 			return *((const uint32_t*) in);
   1410 		case cgltf_component_type_r_32f:
   1411 			return *((const float*) in);
   1412 		case cgltf_component_type_r_8:
   1413 			return *((const int8_t*) in);
   1414 		case cgltf_component_type_r_8u:
   1415 		case cgltf_component_type_invalid:
   1416 		default:
   1417 			return *((const uint8_t*) in);
   1418 	}
   1419 }
   1420 
   1421 static cgltf_float cgltf_component_read_float(const void* in, cgltf_component_type component_type, cgltf_bool normalized)
   1422 {
   1423 	if (component_type == cgltf_component_type_r_32f)
   1424 	{
   1425 		return *((const float*) in);
   1426 	}
   1427 
   1428 	if (normalized)
   1429 	{
   1430 		switch (component_type)
   1431 		{
   1432 			case cgltf_component_type_r_32u:
   1433 				return *((const uint32_t*) in) / (float) UINT_MAX;
   1434 			case cgltf_component_type_r_16:
   1435 				return *((const int16_t*) in) / (float) SHRT_MAX;
   1436 			case cgltf_component_type_r_16u:
   1437 				return *((const uint16_t*) in) / (float) USHRT_MAX;
   1438 			case cgltf_component_type_r_8:
   1439 				return *((const int8_t*) in) / (float) SCHAR_MAX;
   1440 			case cgltf_component_type_r_8u:
   1441 			case cgltf_component_type_invalid:
   1442 			default:
   1443 				return *((const uint8_t*) in) / (float) CHAR_MAX;
   1444 		}
   1445 	}
   1446 
   1447 	return cgltf_component_read_index(in, component_type);
   1448 }
   1449 
   1450 static cgltf_size cgltf_num_components(cgltf_type type);
   1451 static cgltf_size cgltf_component_size(cgltf_component_type component_type);
   1452 
   1453 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)
   1454 {
   1455 	cgltf_size num_components = cgltf_num_components(type);
   1456 
   1457 	if (element_size < num_components) {
   1458 		return 0;
   1459 	}
   1460 
   1461 	// There are three special cases for component extraction, see #data-alignment in the 2.0 spec.
   1462 
   1463 	cgltf_size component_size = cgltf_component_size(component_type);
   1464 
   1465 	if (type == cgltf_type_mat2 && component_size == 1)
   1466 	{
   1467 		out[0] = cgltf_component_read_float(element, component_type, normalized);
   1468 		out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
   1469 		out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
   1470 		out[3] = cgltf_component_read_float(element + 5, component_type, normalized);
   1471 		return 1;
   1472 	}
   1473 
   1474 	if (type == cgltf_type_mat3 && component_size == 1)
   1475 	{
   1476 		out[0] = cgltf_component_read_float(element, component_type, normalized);
   1477 		out[1] = cgltf_component_read_float(element + 1, component_type, normalized);
   1478 		out[2] = cgltf_component_read_float(element + 2, component_type, normalized);
   1479 		out[3] = cgltf_component_read_float(element + 4, component_type, normalized);
   1480 		out[4] = cgltf_component_read_float(element + 5, component_type, normalized);
   1481 		out[5] = cgltf_component_read_float(element + 6, component_type, normalized);
   1482 		out[6] = cgltf_component_read_float(element + 8, component_type, normalized);
   1483 		out[7] = cgltf_component_read_float(element + 9, component_type, normalized);
   1484 		out[8] = cgltf_component_read_float(element + 10, component_type, normalized);
   1485 		return 1;
   1486 	}
   1487 
   1488 	if (type == cgltf_type_mat3 && component_size == 2)
   1489 	{
   1490 		out[0] = cgltf_component_read_float(element, component_type, normalized);
   1491 		out[1] = cgltf_component_read_float(element + 2, component_type, normalized);
   1492 		out[2] = cgltf_component_read_float(element + 4, component_type, normalized);
   1493 		out[3] = cgltf_component_read_float(element + 8, component_type, normalized);
   1494 		out[4] = cgltf_component_read_float(element + 10, component_type, normalized);
   1495 		out[5] = cgltf_component_read_float(element + 12, component_type, normalized);
   1496 		out[6] = cgltf_component_read_float(element + 16, component_type, normalized);
   1497 		out[7] = cgltf_component_read_float(element + 18, component_type, normalized);
   1498 		out[8] = cgltf_component_read_float(element + 20, component_type, normalized);
   1499 		return 1;
   1500 	}
   1501 
   1502 	for (cgltf_size i = 0; i < num_components; ++i)
   1503 	{
   1504 		out[i] = cgltf_component_read_float(element + component_size * i, component_type, normalized);
   1505 	}
   1506 	return 1;
   1507 }
   1508 
   1509 
   1510 cgltf_bool cgltf_accessor_read_float(const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size)
   1511 {
   1512 	if (accessor->is_sparse || accessor->buffer_view == NULL)
   1513 	{
   1514 		return 0;
   1515 	}
   1516 
   1517 	cgltf_size offset = accessor->offset + accessor->buffer_view->offset;
   1518 	const uint8_t* element = (const uint8_t*) accessor->buffer_view->buffer->data;
   1519 	element += offset + accessor->stride * index;
   1520 	return cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, out, element_size);
   1521 }
   1522 
   1523 cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size index)
   1524 {
   1525 	if (accessor->buffer_view)
   1526 	{
   1527 		cgltf_size offset = accessor->offset + accessor->buffer_view->offset;
   1528 		const uint8_t* element = (const uint8_t*) accessor->buffer_view->buffer->data;
   1529 		element += offset + accessor->stride * index;
   1530 		return cgltf_component_read_index(element, accessor->component_type);
   1531 	}
   1532 
   1533 	return 0;
   1534 }
   1535 
   1536 #define CGLTF_ERROR_JSON -1
   1537 #define CGLTF_ERROR_NOMEM -2
   1538 
   1539 #define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; }
   1540 #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 */
   1541 
   1542 #define CGLTF_PTRINDEX(type, idx) (type*)(cgltf_size)(idx + 1)
   1543 #define CGLTF_PTRFIXUP(var, data, size) if (var) { if ((cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1]; }
   1544 #define CGLTF_PTRFIXUP_REQ(var, data, size) if (!var || (cgltf_size)var > size) { return CGLTF_ERROR_JSON; } var = &data[(cgltf_size)var-1];
   1545 
   1546 static int cgltf_json_strcmp(jsmntok_t const* tok, const uint8_t* json_chunk, const char* str)
   1547 {
   1548 	CGLTF_CHECK_TOKTYPE(*tok, JSMN_STRING);
   1549 	size_t const str_len = strlen(str);
   1550 	size_t const name_length = tok->end - tok->start;
   1551 	return (str_len == name_length) ? strncmp((const char*)json_chunk + tok->start, str, str_len) : 128;
   1552 }
   1553 
   1554 static int cgltf_json_to_int(jsmntok_t const* tok, const uint8_t* json_chunk)
   1555 {
   1556 	CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
   1557 	char tmp[128];
   1558 	int size = (cgltf_size)(tok->end - tok->start) < sizeof(tmp) ? tok->end - tok->start : sizeof(tmp) - 1;
   1559 	strncpy(tmp, (const char*)json_chunk + tok->start, size);
   1560 	tmp[size] = 0;
   1561 	return atoi(tmp);
   1562 }
   1563 
   1564 static cgltf_float cgltf_json_to_float(jsmntok_t const* tok, const uint8_t* json_chunk)
   1565 {
   1566 	CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
   1567 	char tmp[128];
   1568 	int size = (cgltf_size)(tok->end - tok->start) < sizeof(tmp) ? tok->end - tok->start : sizeof(tmp) - 1;
   1569 	strncpy(tmp, (const char*)json_chunk + tok->start, size);
   1570 	tmp[size] = 0;
   1571 	return (cgltf_float)atof(tmp);
   1572 }
   1573 
   1574 static cgltf_bool cgltf_json_to_bool(jsmntok_t const* tok, const uint8_t* json_chunk)
   1575 {
   1576 	int size = tok->end - tok->start;
   1577 	return size == 4 && memcmp(json_chunk + tok->start, "true", 4) == 0;
   1578 }
   1579 
   1580 static int cgltf_skip_json(jsmntok_t const* tokens, int i)
   1581 {
   1582 	if (tokens[i].type == JSMN_ARRAY)
   1583 	{
   1584 		int size = tokens[i].size;
   1585 		++i;
   1586 		for (int j = 0; j < size; ++j)
   1587 		{
   1588 			i = cgltf_skip_json(tokens, i);
   1589 			if (i < 0)
   1590 			{
   1591 				return i;
   1592 			}
   1593 		}
   1594 	}
   1595 	else if (tokens[i].type == JSMN_OBJECT)
   1596 	{
   1597 		int size = tokens[i].size;
   1598 		++i;
   1599 		for (int j = 0; j < size; ++j)
   1600 		{
   1601 			CGLTF_CHECK_KEY(tokens[i]);
   1602 			++i;
   1603 			i = cgltf_skip_json(tokens, i);
   1604 			if (i < 0)
   1605 			{
   1606 				return i;
   1607 			}
   1608 		}
   1609 	}
   1610 	else if (tokens[i].type == JSMN_PRIMITIVE
   1611 		 || tokens[i].type == JSMN_STRING)
   1612 	{
   1613 		return i + 1;
   1614 	}
   1615 	return i;
   1616 }
   1617 
   1618 static void cgltf_fill_float_array(float* out_array, int size, float value)
   1619 {
   1620 	for (int j = 0; j < size; ++j)
   1621 	{
   1622 		out_array[j] = value;
   1623 	}
   1624 }
   1625 
   1626 static int cgltf_parse_json_float_array(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, float* out_array, int size)
   1627 {
   1628 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
   1629 	if (tokens[i].size != size)
   1630 	{
   1631 		return CGLTF_ERROR_JSON;
   1632 	}
   1633 	++i;
   1634 	for (int j = 0; j < size; ++j)
   1635 	{
   1636 		CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   1637 		out_array[j] = cgltf_json_to_float(tokens + i, json_chunk);
   1638 		++i;
   1639 	}
   1640 	return i;
   1641 }
   1642 
   1643 static int cgltf_parse_json_string(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, char** out_string)
   1644 {
   1645 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING);
   1646 	if (*out_string)
   1647 	{
   1648 		return CGLTF_ERROR_JSON;
   1649 	}
   1650 	int size = tokens[i].end - tokens[i].start;
   1651 	char* result = (char*)options->memory_alloc(options->memory_user_data, size + 1);
   1652 	if (!result)
   1653 	{
   1654 		return CGLTF_ERROR_NOMEM;
   1655 	}
   1656 	strncpy(result, (const char*)json_chunk + tokens[i].start, size);
   1657 	result[size] = 0;
   1658 	*out_string = result;
   1659 	return i + 1;
   1660 }
   1661 
   1662 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)
   1663 {
   1664 	(void)json_chunk;
   1665 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
   1666 	if (*out_array)
   1667 	{
   1668 		return CGLTF_ERROR_JSON;
   1669 	}
   1670 	int size = tokens[i].size;
   1671 	void* result = cgltf_calloc(options, element_size, size);
   1672 	if (!result)
   1673 	{
   1674 		return CGLTF_ERROR_NOMEM;
   1675 	}
   1676 	*out_array = result;
   1677 	*out_size = size;
   1678 	return i + 1;
   1679 }
   1680 
   1681 static void cgltf_parse_attribute_type(const char* name, cgltf_attribute_type* out_type, int* out_index)
   1682 {
   1683 	const char* us = strchr(name, '_');
   1684 	size_t len = us ? us - name : strlen(name);
   1685 
   1686 	if (len == 8 && strncmp(name, "POSITION", 8) == 0)
   1687 	{
   1688 		*out_type = cgltf_attribute_type_position;
   1689 	}
   1690 	else if (len == 6 && strncmp(name, "NORMAL", 6) == 0)
   1691 	{
   1692 		*out_type = cgltf_attribute_type_normal;
   1693 	}
   1694 	else if (len == 7 && strncmp(name, "TANGENT", 7) == 0)
   1695 	{
   1696 		*out_type = cgltf_attribute_type_tangent;
   1697 	}
   1698 	else if (len == 8 && strncmp(name, "TEXCOORD", 8) == 0)
   1699 	{
   1700 		*out_type = cgltf_attribute_type_texcoord;
   1701 	}
   1702 	else if (len == 5 && strncmp(name, "COLOR", 5) == 0)
   1703 	{
   1704 		*out_type = cgltf_attribute_type_color;
   1705 	}
   1706 	else if (len == 6 && strncmp(name, "JOINTS", 6) == 0)
   1707 	{
   1708 		*out_type = cgltf_attribute_type_joints;
   1709 	}
   1710 	else if (len == 7 && strncmp(name, "WEIGHTS", 7) == 0)
   1711 	{
   1712 		*out_type = cgltf_attribute_type_weights;
   1713 	}
   1714 	else
   1715 	{
   1716 		*out_type = cgltf_attribute_type_invalid;
   1717 	}
   1718 
   1719 	if (us && *out_type != cgltf_attribute_type_invalid)
   1720 	{
   1721 		*out_index = atoi(us + 1);
   1722 	}
   1723 }
   1724 
   1725 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)
   1726 {
   1727 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   1728 
   1729 	if (*out_attributes)
   1730 	{
   1731 		return CGLTF_ERROR_JSON;
   1732 	}
   1733 
   1734 	*out_attributes_count = tokens[i].size;
   1735 	*out_attributes = (cgltf_attribute*)cgltf_calloc(options, sizeof(cgltf_attribute), *out_attributes_count);
   1736 	++i;
   1737 
   1738 	if (!*out_attributes)
   1739 	{
   1740 		return CGLTF_ERROR_NOMEM;
   1741 	}
   1742 
   1743 	for (cgltf_size j = 0; j < *out_attributes_count; ++j)
   1744 	{
   1745 		CGLTF_CHECK_KEY(tokens[i]);
   1746 
   1747 		i = cgltf_parse_json_string(options, tokens, i, json_chunk, &(*out_attributes)[j].name);
   1748 		if (i < 0)
   1749 		{
   1750 			return CGLTF_ERROR_JSON;
   1751 		}
   1752 
   1753 		cgltf_parse_attribute_type((*out_attributes)[j].name, &(*out_attributes)[j].type, &(*out_attributes)[j].index);
   1754 
   1755 		(*out_attributes)[j].data = CGLTF_PTRINDEX(cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
   1756 		++i;
   1757 	}
   1758 
   1759 	return i;
   1760 }
   1761 
   1762 static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_primitive* out_prim)
   1763 {
   1764 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   1765 
   1766 	out_prim->type = cgltf_primitive_type_triangles;
   1767 
   1768 	int size = tokens[i].size;
   1769 	++i;
   1770 
   1771 	for (int j = 0; j < size; ++j)
   1772 	{
   1773 		CGLTF_CHECK_KEY(tokens[i]);
   1774 
   1775 		if (cgltf_json_strcmp(tokens+i, json_chunk, "mode") == 0)
   1776 		{
   1777 			++i;
   1778 			out_prim->type
   1779 					= (cgltf_primitive_type)
   1780 					cgltf_json_to_int(tokens+i, json_chunk);
   1781 			++i;
   1782 		}
   1783 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0)
   1784 		{
   1785 			++i;
   1786 			out_prim->indices = CGLTF_PTRINDEX(cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
   1787 			++i;
   1788 		}
   1789 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "material") == 0)
   1790 		{
   1791 			++i;
   1792 			out_prim->material = CGLTF_PTRINDEX(cgltf_material, cgltf_json_to_int(tokens + i, json_chunk));
   1793 			++i;
   1794 		}
   1795 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "attributes") == 0)
   1796 		{
   1797 			i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_prim->attributes, &out_prim->attributes_count);
   1798 		}
   1799 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "targets") == 0)
   1800 		{
   1801 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_morph_target), (void**)&out_prim->targets, &out_prim->targets_count);
   1802 			if (i < 0)
   1803 			{
   1804 				return i;
   1805 			}
   1806 
   1807 			for (cgltf_size k = 0; k < out_prim->targets_count; ++k)
   1808 			{
   1809 				i = cgltf_parse_json_attribute_list(options, tokens, i, json_chunk, &out_prim->targets[k].attributes, &out_prim->targets[k].attributes_count);
   1810 				if (i < 0)
   1811 				{
   1812 					return i;
   1813 				}
   1814 			}
   1815 		}
   1816 		else
   1817 		{
   1818 			i = cgltf_skip_json(tokens, i+1);
   1819 		}
   1820 
   1821 		if (i < 0)
   1822 		{
   1823 			return i;
   1824 		}
   1825 	}
   1826 
   1827 	return i;
   1828 }
   1829 
   1830 static int cgltf_parse_json_mesh(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_mesh* out_mesh)
   1831 {
   1832 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   1833 
   1834 	int size = tokens[i].size;
   1835 	++i;
   1836 
   1837 	for (int j = 0; j < size; ++j)
   1838 	{
   1839 		CGLTF_CHECK_KEY(tokens[i]);
   1840 
   1841 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   1842 		{
   1843 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_mesh->name);
   1844 		}
   1845 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "primitives") == 0)
   1846 		{
   1847 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_primitive), (void**)&out_mesh->primitives, &out_mesh->primitives_count);
   1848 			if (i < 0)
   1849 			{
   1850 				return i;
   1851 			}
   1852 
   1853 			for (cgltf_size prim_index = 0; prim_index < out_mesh->primitives_count; ++prim_index)
   1854 			{
   1855 				i = cgltf_parse_json_primitive(options, tokens, i, json_chunk, &out_mesh->primitives[prim_index]);
   1856 				if (i < 0)
   1857 				{
   1858 					return i;
   1859 				}
   1860 			}
   1861 		}
   1862 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "weights") == 0)
   1863 		{
   1864 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_float), (void**)&out_mesh->weights, &out_mesh->weights_count);
   1865 			if (i < 0)
   1866 			{
   1867 				return i;
   1868 			}
   1869 
   1870 			i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_mesh->weights, (int)out_mesh->weights_count);
   1871 		}
   1872 		else
   1873 		{
   1874 			i = cgltf_skip_json(tokens, i+1);
   1875 		}
   1876 
   1877 		if (i < 0)
   1878 		{
   1879 			return i;
   1880 		}
   1881 	}
   1882 
   1883 	return i;
   1884 }
   1885 
   1886 static int cgltf_parse_json_meshes(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   1887 {
   1888 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_mesh), (void**)&out_data->meshes, &out_data->meshes_count);
   1889 	if (i < 0)
   1890 	{
   1891 		return i;
   1892 	}
   1893 
   1894 	for (cgltf_size j = 0; j < out_data->meshes_count; ++j)
   1895 	{
   1896 		i = cgltf_parse_json_mesh(options, tokens, i, json_chunk, &out_data->meshes[j]);
   1897 		if (i < 0)
   1898 		{
   1899 			return i;
   1900 		}
   1901 	}
   1902 	return i;
   1903 }
   1904 
   1905 static cgltf_component_type cgltf_json_to_component_type(jsmntok_t const* tok, const uint8_t* json_chunk)
   1906 {
   1907 	int type = cgltf_json_to_int(tok, json_chunk);
   1908 
   1909 	switch (type)
   1910 	{
   1911 	case 5120:
   1912 		return cgltf_component_type_r_8;
   1913 	case 5121:
   1914 		return cgltf_component_type_r_8u;
   1915 	case 5122:
   1916 		return cgltf_component_type_r_16;
   1917 	case 5123:
   1918 		return cgltf_component_type_r_16u;
   1919 	case 5125:
   1920 		return cgltf_component_type_r_32u;
   1921 	case 5126:
   1922 		return cgltf_component_type_r_32f;
   1923 	default:
   1924 		return cgltf_component_type_invalid;
   1925 	}
   1926 }
   1927 
   1928 static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor_sparse* out_sparse)
   1929 {
   1930 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   1931 
   1932 	int size = tokens[i].size;
   1933 	++i;
   1934 
   1935 	for (int j = 0; j < size; ++j)
   1936 	{
   1937 		CGLTF_CHECK_KEY(tokens[i]);
   1938 
   1939 		if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0)
   1940 		{
   1941 			++i;
   1942 			out_sparse->count = cgltf_json_to_int(tokens + i, json_chunk);
   1943 			++i;
   1944 		}
   1945 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0)
   1946 		{
   1947 			++i;
   1948 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   1949 
   1950 			int indices_size = tokens[i].size;
   1951 			++i;
   1952 
   1953 			for (int k = 0; k < indices_size; ++k)
   1954 			{
   1955 				CGLTF_CHECK_KEY(tokens[i]);
   1956 
   1957 				if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
   1958 				{
   1959 					++i;
   1960 					out_sparse->indices_buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
   1961 					++i;
   1962 				}
   1963 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
   1964 				{
   1965 					++i;
   1966 					out_sparse->indices_byte_offset = cgltf_json_to_int(tokens + i, json_chunk);
   1967 					++i;
   1968 				}
   1969 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "componentType") == 0)
   1970 				{
   1971 					++i;
   1972 					out_sparse->indices_component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
   1973 					++i;
   1974 				}
   1975 				else
   1976 				{
   1977 					i = cgltf_skip_json(tokens, i+1);
   1978 				}
   1979 
   1980 				if (i < 0)
   1981 				{
   1982 					return i;
   1983 				}
   1984 			}
   1985 		}
   1986 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "values") == 0)
   1987 		{
   1988 			++i;
   1989 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   1990 
   1991 			int values_size = tokens[i].size;
   1992 			++i;
   1993 
   1994 			for (int k = 0; k < values_size; ++k)
   1995 			{
   1996 				CGLTF_CHECK_KEY(tokens[i]);
   1997 
   1998 				if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
   1999 				{
   2000 					++i;
   2001 					out_sparse->values_buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
   2002 					++i;
   2003 				}
   2004 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
   2005 				{
   2006 					++i;
   2007 					out_sparse->values_byte_offset = cgltf_json_to_int(tokens + i, json_chunk);
   2008 					++i;
   2009 				}
   2010 				else
   2011 				{
   2012 					i = cgltf_skip_json(tokens, i+1);
   2013 				}
   2014 
   2015 				if (i < 0)
   2016 				{
   2017 					return i;
   2018 				}
   2019 			}
   2020 		}
   2021 		else
   2022 		{
   2023 			i = cgltf_skip_json(tokens, i+1);
   2024 		}
   2025 
   2026 		if (i < 0)
   2027 		{
   2028 			return i;
   2029 		}
   2030 	}
   2031 
   2032 	return i;
   2033 }
   2034 
   2035 static int cgltf_parse_json_accessor(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor* out_accessor)
   2036 {
   2037 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2038 
   2039 	int size = tokens[i].size;
   2040 	++i;
   2041 
   2042 	for (int j = 0; j < size; ++j)
   2043 	{
   2044 		CGLTF_CHECK_KEY(tokens[i]);
   2045 
   2046 		if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
   2047 		{
   2048 			++i;
   2049 			out_accessor->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
   2050 			++i;
   2051 		}
   2052 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
   2053 		{
   2054 			++i;
   2055 			out_accessor->offset =
   2056 					cgltf_json_to_int(tokens+i, json_chunk);
   2057 			++i;
   2058 		}
   2059 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "componentType") == 0)
   2060 		{
   2061 			++i;
   2062 			out_accessor->component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
   2063 			++i;
   2064 		}
   2065 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "normalized") == 0)
   2066 		{
   2067 			++i;
   2068 			out_accessor->normalized = cgltf_json_to_bool(tokens+i, json_chunk);
   2069 			++i;
   2070 		}
   2071 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0)
   2072 		{
   2073 			++i;
   2074 			out_accessor->count =
   2075 					cgltf_json_to_int(tokens+i, json_chunk);
   2076 			++i;
   2077 		}
   2078 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "type") == 0)
   2079 		{
   2080 			++i;
   2081 			if (cgltf_json_strcmp(tokens+i, json_chunk, "SCALAR") == 0)
   2082 			{
   2083 				out_accessor->type = cgltf_type_scalar;
   2084 			}
   2085 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "VEC2") == 0)
   2086 			{
   2087 				out_accessor->type = cgltf_type_vec2;
   2088 			}
   2089 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "VEC3") == 0)
   2090 			{
   2091 				out_accessor->type = cgltf_type_vec3;
   2092 			}
   2093 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "VEC4") == 0)
   2094 			{
   2095 				out_accessor->type = cgltf_type_vec4;
   2096 			}
   2097 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "MAT2") == 0)
   2098 			{
   2099 				out_accessor->type = cgltf_type_mat2;
   2100 			}
   2101 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "MAT3") == 0)
   2102 			{
   2103 				out_accessor->type = cgltf_type_mat3;
   2104 			}
   2105 			else if (cgltf_json_strcmp(tokens+i, json_chunk, "MAT4") == 0)
   2106 			{
   2107 				out_accessor->type = cgltf_type_mat4;
   2108 			}
   2109 			++i;
   2110 		}
   2111 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "min") == 0)
   2112 		{
   2113 			++i;
   2114 			out_accessor->has_min = 1;
   2115 			// note: we can't parse the precise number of elements since type may not have been computed yet
   2116 			int min_size = tokens[i].size > 16 ? 16 : tokens[i].size;
   2117 			i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->min, min_size);
   2118 		}
   2119 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "max") == 0)
   2120 		{
   2121 			++i;
   2122 			out_accessor->has_max = 1;
   2123 			// note: we can't parse the precise number of elements since type may not have been computed yet
   2124 			int max_size = tokens[i].size > 16 ? 16 : tokens[i].size;
   2125 			i = cgltf_parse_json_float_array(tokens, i, json_chunk, out_accessor->max, max_size);
   2126 		}
   2127 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "sparse") == 0)
   2128 		{
   2129 			out_accessor->is_sparse = 1;
   2130 			i = cgltf_parse_json_accessor_sparse(tokens, i + 1, json_chunk, &out_accessor->sparse);
   2131 		}
   2132 		else
   2133 		{
   2134 			i = cgltf_skip_json(tokens, i+1);
   2135 		}
   2136 
   2137 		if (i < 0)
   2138 		{
   2139 			return i;
   2140 		}
   2141 	}
   2142 
   2143 	return i;
   2144 }
   2145 
   2146 static int cgltf_parse_json_texture_transform(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture_transform* out_texture_transform)
   2147 {
   2148 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2149 
   2150 	int size = tokens[i].size;
   2151 	++i;
   2152 
   2153 	for (int j = 0; j < size; ++j)
   2154 	{
   2155 		CGLTF_CHECK_KEY(tokens[i]);
   2156 
   2157 		if (cgltf_json_strcmp(tokens + i, json_chunk, "offset") == 0)
   2158 		{
   2159 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->offset, 2);
   2160 		}
   2161 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "rotation") == 0)
   2162 		{
   2163 			++i;
   2164 			out_texture_transform->rotation = cgltf_json_to_float(tokens + i, json_chunk);
   2165 			++i;
   2166 		}
   2167 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0)
   2168 		{
   2169 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_texture_transform->scale, 2);
   2170 		}
   2171 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "texCoord") == 0)
   2172 		{
   2173 			++i;
   2174 			out_texture_transform->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
   2175 			++i;
   2176 		}
   2177 		else
   2178 		{
   2179 			i = cgltf_skip_json(tokens, i + 1);
   2180 		}
   2181 
   2182 		if (i < 0)
   2183 		{
   2184 			return i;
   2185 		}
   2186 	}
   2187 
   2188 	return i;
   2189 }
   2190 
   2191 static int cgltf_parse_json_texture_view(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture_view* out_texture_view)
   2192 {
   2193 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2194 
   2195 	out_texture_view->scale = 1.0f;
   2196 	cgltf_fill_float_array(out_texture_view->transform.scale, 2, 1.0f);
   2197 
   2198 	int size = tokens[i].size;
   2199 	++i;
   2200 
   2201 	for (int j = 0; j < size; ++j)
   2202 	{
   2203 		CGLTF_CHECK_KEY(tokens[i]);
   2204 
   2205 		if (cgltf_json_strcmp(tokens + i, json_chunk, "index") == 0)
   2206 		{
   2207 			++i;
   2208 			out_texture_view->texture = CGLTF_PTRINDEX(cgltf_texture, cgltf_json_to_int(tokens + i, json_chunk));
   2209 			++i;
   2210 		}
   2211 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "texCoord") == 0)
   2212 		{
   2213 			++i;
   2214 			out_texture_view->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
   2215 			++i;
   2216 		}
   2217 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0) 
   2218 		{
   2219 			++i;
   2220 			out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
   2221 			++i;
   2222 		}
   2223 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "strength") == 0)
   2224 		{
   2225 			++i;
   2226 			out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
   2227 			++i;
   2228 		}
   2229 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   2230 		{
   2231 			++i;
   2232 
   2233 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2234 
   2235 			int extensions_size = tokens[i].size;
   2236 			++i;
   2237 
   2238 			for (int k = 0; k < extensions_size; ++k)
   2239 			{
   2240 				if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_texture_transform") == 0)
   2241 				{
   2242 					out_texture_view->has_transform = 1;
   2243 					i = cgltf_parse_json_texture_transform(tokens, i + 1, json_chunk, &out_texture_view->transform);
   2244 				}
   2245 				else
   2246 				{
   2247 					i = cgltf_skip_json(tokens, i+1);
   2248 				}
   2249 			}
   2250 		}
   2251 		else
   2252 		{
   2253 			i = cgltf_skip_json(tokens, i + 1);
   2254 		}
   2255 
   2256 		if (i < 0)
   2257 		{
   2258 			return i;
   2259 		}
   2260 	}
   2261 
   2262 	return i;
   2263 }
   2264 
   2265 static int cgltf_parse_json_pbr_metallic_roughness(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_pbr_metallic_roughness* out_pbr)
   2266 {
   2267 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2268 
   2269 	int size = tokens[i].size;
   2270 	++i;
   2271 
   2272 	for (int j = 0; j < size; ++j)
   2273 	{
   2274 		CGLTF_CHECK_KEY(tokens[i]);
   2275 
   2276 		if (cgltf_json_strcmp(tokens+i, json_chunk, "metallicFactor") == 0)
   2277 		{
   2278 			++i;
   2279 			out_pbr->metallic_factor = 
   2280 				cgltf_json_to_float(tokens + i, json_chunk);
   2281 			++i;
   2282 		}
   2283 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0) 
   2284 		{
   2285 			++i;
   2286 			out_pbr->roughness_factor =
   2287 				cgltf_json_to_float(tokens+i, json_chunk);
   2288 			++i;
   2289 		}
   2290 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "baseColorFactor") == 0)
   2291 		{
   2292 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->base_color_factor, 4);
   2293 		}
   2294 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "baseColorTexture") == 0)
   2295 		{
   2296 			i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk,
   2297 				&out_pbr->base_color_texture);
   2298 		}
   2299 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "metallicRoughnessTexture") == 0)
   2300 		{
   2301 			i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk,
   2302 				&out_pbr->metallic_roughness_texture);
   2303 		}
   2304 		else
   2305 		{
   2306 			i = cgltf_skip_json(tokens, i+1);
   2307 		}
   2308 
   2309 		if (i < 0)
   2310 		{
   2311 			return i;
   2312 		}
   2313 	}
   2314 
   2315 	return i;
   2316 }
   2317 
   2318 static int cgltf_parse_json_pbr_specular_glossiness(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_pbr_specular_glossiness* out_pbr)
   2319 {
   2320 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2321 	int size = tokens[i].size;
   2322 	++i;
   2323 
   2324 	for (int j = 0; j < size; ++j)
   2325 	{
   2326 		CGLTF_CHECK_KEY(tokens[i]);
   2327 
   2328 		if (cgltf_json_strcmp(tokens+i, json_chunk, "diffuseFactor") == 0)
   2329 		{
   2330 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->diffuse_factor, 4);
   2331 			if (i < 0)
   2332 			{
   2333 				return i;
   2334 			}
   2335 		}
   2336 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "specularFactor") == 0)
   2337 		{
   2338 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_pbr->specular_factor, 3);
   2339 			if (i < 0)
   2340 			{
   2341 				return i;
   2342 			}
   2343 		}
   2344 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "glossinessFactor") == 0)
   2345 		{
   2346 			++i;
   2347 			out_pbr->glossiness_factor = cgltf_json_to_float(tokens + i, json_chunk);
   2348 			++i;
   2349 		}
   2350 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "diffuseTexture") == 0)
   2351 		{
   2352 			i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk, &out_pbr->diffuse_texture);
   2353 			if (i < 0)
   2354 			{
   2355 				return i;
   2356 			}
   2357 		}
   2358 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "specularGlossinessTexture") == 0)
   2359 		{
   2360 			i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk, &out_pbr->specular_glossiness_texture);
   2361 			if (i < 0)
   2362 			{
   2363 				return i;
   2364 			}
   2365 		}
   2366 		else
   2367 		{
   2368 			i = cgltf_skip_json(tokens, i+1);
   2369 		}
   2370 
   2371 		if (i < 0)
   2372 		{
   2373 			return i;
   2374 		}
   2375 
   2376 	}
   2377 
   2378 	return i;
   2379 }
   2380 
   2381 static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_image* out_image)
   2382 {
   2383 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2384 
   2385 	int size = tokens[i].size;
   2386 	++i;
   2387 
   2388 	for (int j = 0; j < size; ++j) 
   2389 	{
   2390 		CGLTF_CHECK_KEY(tokens[i]);
   2391 
   2392 		if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0) 
   2393 		{
   2394 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->uri);
   2395 		}
   2396 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
   2397 		{
   2398 			++i;
   2399 			out_image->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
   2400 			++i;
   2401 		}
   2402 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "mimeType") == 0)
   2403 		{
   2404 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->mime_type);
   2405 		}
   2406 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
   2407 		{
   2408 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->name);
   2409 		}
   2410 		else
   2411 		{
   2412 			i = cgltf_skip_json(tokens, i + 1);
   2413 		}
   2414 
   2415 		if (i < 0)
   2416 		{
   2417 			return i;
   2418 		}
   2419 	}
   2420 
   2421 	return i;
   2422 }
   2423 
   2424 static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_sampler* out_sampler)
   2425 {
   2426 	(void)options;
   2427 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2428 
   2429 	out_sampler->wrap_s = 10497;
   2430 	out_sampler->wrap_t = 10497;
   2431 
   2432 	int size = tokens[i].size;
   2433 	++i;
   2434 
   2435 	for (int j = 0; j < size; ++j)
   2436 	{
   2437 		CGLTF_CHECK_KEY(tokens[i]);
   2438 
   2439 		if (cgltf_json_strcmp(tokens + i, json_chunk, "magFilter") == 0) 
   2440 		{
   2441 			++i;
   2442 			out_sampler->mag_filter
   2443 				= cgltf_json_to_int(tokens + i, json_chunk);
   2444 			++i;
   2445 		}
   2446 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "minFilter") == 0)
   2447 		{
   2448 			++i;
   2449 			out_sampler->min_filter
   2450 				= cgltf_json_to_int(tokens + i, json_chunk);
   2451 			++i;
   2452 		}
   2453 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapS") == 0)
   2454 		{
   2455 			++i;
   2456 			out_sampler->wrap_s
   2457 				= cgltf_json_to_int(tokens + i, json_chunk);
   2458 			++i;
   2459 		}
   2460 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0) 
   2461 		{
   2462 			++i;
   2463 			out_sampler->wrap_t
   2464 				= cgltf_json_to_int(tokens + i, json_chunk);
   2465 			++i;
   2466 		}
   2467 		else
   2468 		{
   2469 			i = cgltf_skip_json(tokens, i + 1);
   2470 		}
   2471 
   2472 		if (i < 0)
   2473 		{
   2474 			return i;
   2475 		}
   2476 	}
   2477 
   2478 	return i;
   2479 }
   2480 
   2481 
   2482 static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture* out_texture)
   2483 {
   2484 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2485 
   2486 	int size = tokens[i].size;
   2487 	++i;
   2488 
   2489 	for (int j = 0; j < size; ++j)
   2490 	{
   2491 		CGLTF_CHECK_KEY(tokens[i]);
   2492 
   2493 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   2494 		{
   2495 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_texture->name);
   2496 		}
   2497 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "sampler") == 0)
   2498 		{
   2499 			++i;
   2500 			out_texture->sampler = CGLTF_PTRINDEX(cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk));
   2501 			++i;
   2502 		}
   2503 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0) 
   2504 		{
   2505 			++i;
   2506 			out_texture->image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
   2507 			++i;
   2508 		}
   2509 		else
   2510 		{
   2511 			i = cgltf_skip_json(tokens, i + 1);
   2512 		}
   2513 
   2514 		if (i < 0)
   2515 		{
   2516 			return i;
   2517 		}
   2518 	}
   2519 
   2520 	return i;
   2521 }
   2522 
   2523 static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_material* out_material)
   2524 {
   2525 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2526 
   2527 	cgltf_fill_float_array(out_material->pbr_metallic_roughness.base_color_factor, 4, 1.0f);
   2528 	out_material->pbr_metallic_roughness.metallic_factor = 1.0f;
   2529 	out_material->pbr_metallic_roughness.roughness_factor = 1.0f;
   2530 
   2531 	cgltf_fill_float_array(out_material->pbr_specular_glossiness.diffuse_factor, 4, 1.0f);
   2532 	cgltf_fill_float_array(out_material->pbr_specular_glossiness.specular_factor, 3, 1.0f);
   2533 	out_material->pbr_specular_glossiness.glossiness_factor = 1.0f;
   2534 
   2535 	out_material->alpha_cutoff = 0.5f;
   2536 
   2537 	int size = tokens[i].size;
   2538 	++i;
   2539 
   2540 	for (int j = 0; j < size; ++j)
   2541 	{
   2542 		CGLTF_CHECK_KEY(tokens[i]);
   2543 
   2544 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   2545 		{
   2546 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_material->name);
   2547 		}
   2548 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "pbrMetallicRoughness") == 0)
   2549 		{
   2550 			out_material->has_pbr_metallic_roughness = 1;
   2551 			i = cgltf_parse_json_pbr_metallic_roughness(tokens, i + 1, json_chunk, &out_material->pbr_metallic_roughness);
   2552 		}
   2553 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "emissiveFactor") == 0)
   2554 		{
   2555 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_material->emissive_factor, 3);
   2556 		}
   2557 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "normalTexture") == 0)
   2558 		{
   2559 			i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk,
   2560 				&out_material->normal_texture);
   2561 		}
   2562 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "occlusionTexture") == 0)
   2563 		{
   2564 			i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk,
   2565 				&out_material->occlusion_texture);
   2566 		}
   2567 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "emissiveTexture") == 0)
   2568 		{
   2569 			i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk,
   2570 				&out_material->emissive_texture);
   2571 		}
   2572 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "alphaMode") == 0)
   2573 		{
   2574 			++i;
   2575 			if (cgltf_json_strcmp(tokens + i, json_chunk, "OPAQUE") == 0)
   2576 			{
   2577 				out_material->alpha_mode = cgltf_alpha_mode_opaque;
   2578 			}
   2579 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "MASK") == 0)
   2580 			{
   2581 				out_material->alpha_mode = cgltf_alpha_mode_mask;
   2582 			}
   2583 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "BLEND") == 0)
   2584 			{
   2585 				out_material->alpha_mode = cgltf_alpha_mode_blend;
   2586 			}
   2587 			++i;
   2588 		}
   2589 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "alphaCutoff") == 0)
   2590 		{
   2591 			++i;
   2592 			out_material->alpha_cutoff = cgltf_json_to_float(tokens + i, json_chunk);
   2593 			++i;
   2594 		}
   2595 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "doubleSided") == 0)
   2596 		{
   2597 			++i;
   2598 			out_material->double_sided =
   2599 				cgltf_json_to_bool(tokens + i, json_chunk);
   2600 			++i;
   2601 		}
   2602 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   2603 		{
   2604 			++i;
   2605 
   2606 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2607 
   2608 			int extensions_size = tokens[i].size;
   2609 			++i;
   2610 
   2611 			for (int k = 0; k < extensions_size; ++k)
   2612 			{
   2613 				CGLTF_CHECK_KEY(tokens[i]);
   2614 
   2615 				if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_pbrSpecularGlossiness") == 0)
   2616 				{
   2617 					out_material->has_pbr_specular_glossiness = 1;
   2618 					i = cgltf_parse_json_pbr_specular_glossiness(tokens, i + 1, json_chunk, &out_material->pbr_specular_glossiness);
   2619 				}
   2620 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_unlit") == 0)
   2621 				{
   2622 					out_material->unlit = 1;
   2623 					i = cgltf_skip_json(tokens, i+1);
   2624 				}
   2625 				else
   2626 				{
   2627 					i = cgltf_skip_json(tokens, i+1);
   2628 				}
   2629 
   2630 				if (i < 0)
   2631 				{
   2632 					return i;
   2633 				}
   2634 			}
   2635 		}
   2636 		else
   2637 		{
   2638 			i = cgltf_skip_json(tokens, i+1);
   2639 		}
   2640 
   2641 		if (i < 0)
   2642 		{
   2643 			return i;
   2644 		}
   2645 	}
   2646 
   2647 	return i;
   2648 }
   2649 
   2650 static int cgltf_parse_json_accessors(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   2651 {
   2652 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_accessor), (void**)&out_data->accessors, &out_data->accessors_count);
   2653 	if (i < 0)
   2654 	{
   2655 		return i;
   2656 	}
   2657 
   2658 	for (cgltf_size j = 0; j < out_data->accessors_count; ++j)
   2659 	{
   2660 		i = cgltf_parse_json_accessor(tokens, i, json_chunk, &out_data->accessors[j]);
   2661 		if (i < 0)
   2662 		{
   2663 			return i;
   2664 		}
   2665 	}
   2666 	return i;
   2667 }
   2668 
   2669 static int cgltf_parse_json_materials(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   2670 {
   2671 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_material), (void**)&out_data->materials, &out_data->materials_count);
   2672 	if (i < 0)
   2673 	{
   2674 		return i;
   2675 	}
   2676 
   2677 	for (cgltf_size j = 0; j < out_data->materials_count; ++j)
   2678 	{
   2679 		i = cgltf_parse_json_material(options, tokens, i, json_chunk, &out_data->materials[j]);
   2680 		if (i < 0)
   2681 		{
   2682 			return i;
   2683 		}
   2684 	}
   2685 	return i;
   2686 }
   2687 
   2688 static int cgltf_parse_json_images(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   2689 {
   2690 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_image), (void**)&out_data->images, &out_data->images_count);
   2691 	if (i < 0)
   2692 	{
   2693 		return i;
   2694 	}
   2695 
   2696 	for (cgltf_size j = 0; j < out_data->images_count; ++j)
   2697 	{
   2698 		i = cgltf_parse_json_image(options, tokens, i, json_chunk, &out_data->images[j]);
   2699 		if (i < 0)
   2700 		{
   2701 			return i;
   2702 		}
   2703 	}
   2704 	return i;
   2705 }
   2706 
   2707 static int cgltf_parse_json_textures(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   2708 {
   2709 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_texture), (void**)&out_data->textures, &out_data->textures_count);
   2710 	if (i < 0)
   2711 	{
   2712 		return i;
   2713 	}
   2714 
   2715 	for (cgltf_size j = 0; j < out_data->textures_count; ++j)
   2716 	{
   2717 		i = cgltf_parse_json_texture(options, tokens, i, json_chunk, &out_data->textures[j]);
   2718 		if (i < 0)
   2719 		{
   2720 			return i;
   2721 		}
   2722 	}
   2723 	return i;
   2724 }
   2725 
   2726 static int cgltf_parse_json_samplers(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   2727 {
   2728 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_sampler), (void**)&out_data->samplers, &out_data->samplers_count);
   2729 	if (i < 0)
   2730 	{
   2731 		return i;
   2732 	}
   2733 
   2734 	for (cgltf_size j = 0; j < out_data->samplers_count; ++j)
   2735 	{
   2736 		i = cgltf_parse_json_sampler(options, tokens, i, json_chunk, &out_data->samplers[j]);
   2737 		if (i < 0)
   2738 		{
   2739 			return i;
   2740 		}
   2741 	}
   2742 	return i;
   2743 }
   2744 
   2745 static int cgltf_parse_json_buffer_view(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_buffer_view* out_buffer_view)
   2746 {
   2747 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2748 
   2749 	int size = tokens[i].size;
   2750 	++i;
   2751 
   2752 	for (int j = 0; j < size; ++j)
   2753 	{
   2754 		CGLTF_CHECK_KEY(tokens[i]);
   2755 
   2756 		if (cgltf_json_strcmp(tokens+i, json_chunk, "buffer") == 0)
   2757 		{
   2758 			++i;
   2759 			out_buffer_view->buffer = CGLTF_PTRINDEX(cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
   2760 			++i;
   2761 		}
   2762 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
   2763 		{
   2764 			++i;
   2765 			out_buffer_view->offset =
   2766 					cgltf_json_to_int(tokens+i, json_chunk);
   2767 			++i;
   2768 		}
   2769 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
   2770 		{
   2771 			++i;
   2772 			out_buffer_view->size =
   2773 					cgltf_json_to_int(tokens+i, json_chunk);
   2774 			++i;
   2775 		}
   2776 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteStride") == 0)
   2777 		{
   2778 			++i;
   2779 			out_buffer_view->stride =
   2780 					cgltf_json_to_int(tokens+i, json_chunk);
   2781 			++i;
   2782 		}
   2783 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "target") == 0)
   2784 		{
   2785 			++i;
   2786 			int type = cgltf_json_to_int(tokens+i, json_chunk);
   2787 			switch (type)
   2788 			{
   2789 			case 34962:
   2790 				type = cgltf_buffer_view_type_vertices;
   2791 				break;
   2792 			case 34963:
   2793 				type = cgltf_buffer_view_type_indices;
   2794 				break;
   2795 			default:
   2796 				type = cgltf_buffer_view_type_invalid;
   2797 				break;
   2798 			}
   2799 			out_buffer_view->type = (cgltf_buffer_view_type)type;
   2800 			++i;
   2801 		}
   2802 		else
   2803 		{
   2804 			i = cgltf_skip_json(tokens, i+1);
   2805 		}
   2806 
   2807 		if (i < 0)
   2808 		{
   2809 			return i;
   2810 		}
   2811 	}
   2812 
   2813 	return i;
   2814 }
   2815 
   2816 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)
   2817 {
   2818 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_buffer_view), (void**)&out_data->buffer_views, &out_data->buffer_views_count);
   2819 	if (i < 0)
   2820 	{
   2821 		return i;
   2822 	}
   2823 
   2824 	for (cgltf_size j = 0; j < out_data->buffer_views_count; ++j)
   2825 	{
   2826 		i = cgltf_parse_json_buffer_view(tokens, i, json_chunk, &out_data->buffer_views[j]);
   2827 		if (i < 0)
   2828 		{
   2829 			return i;
   2830 		}
   2831 	}
   2832 	return i;
   2833 }
   2834 
   2835 static int cgltf_parse_json_buffer(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_buffer* out_buffer)
   2836 {
   2837 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2838 
   2839 	int size = tokens[i].size;
   2840 	++i;
   2841 
   2842 	for (int j = 0; j < size; ++j)
   2843 	{
   2844 		CGLTF_CHECK_KEY(tokens[i]);
   2845 
   2846 		if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
   2847 		{
   2848 			++i;
   2849 			out_buffer->size =
   2850 					cgltf_json_to_int(tokens+i, json_chunk);
   2851 			++i;
   2852 		}
   2853 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "uri") == 0)
   2854 		{
   2855 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->uri);
   2856 		}
   2857 		else
   2858 		{
   2859 			i = cgltf_skip_json(tokens, i+1);
   2860 		}
   2861 
   2862 		if (i < 0)
   2863 		{
   2864 			return i;
   2865 		}
   2866 	}
   2867 
   2868 	return i;
   2869 }
   2870 
   2871 static int cgltf_parse_json_buffers(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   2872 {
   2873 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_buffer), (void**)&out_data->buffers, &out_data->buffers_count);
   2874 	if (i < 0)
   2875 	{
   2876 		return i;
   2877 	}
   2878 
   2879 	for (cgltf_size j = 0; j < out_data->buffers_count; ++j)
   2880 	{
   2881 		i = cgltf_parse_json_buffer(options, tokens, i, json_chunk, &out_data->buffers[j]);
   2882 		if (i < 0)
   2883 		{
   2884 			return i;
   2885 		}
   2886 	}
   2887 	return i;
   2888 }
   2889 
   2890 static int cgltf_parse_json_skin(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_skin* out_skin)
   2891 {
   2892 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2893 
   2894 	int size = tokens[i].size;
   2895 	++i;
   2896 
   2897 	for (int j = 0; j < size; ++j)
   2898 	{
   2899 		CGLTF_CHECK_KEY(tokens[i]);
   2900 
   2901 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   2902 		{
   2903 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_skin->name);
   2904 		}
   2905 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "joints") == 0)
   2906 		{
   2907 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_node*), (void**)&out_skin->joints, &out_skin->joints_count);
   2908 			if (i < 0)
   2909 			{
   2910 				return i;
   2911 			}
   2912 
   2913 			for (cgltf_size k = 0; k < out_skin->joints_count; ++k)
   2914 			{
   2915 				out_skin->joints[k] = CGLTF_PTRINDEX(cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
   2916 				++i;
   2917 			}
   2918 		}
   2919 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "skeleton") == 0)
   2920 		{
   2921 			++i;
   2922 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   2923 			out_skin->skeleton = CGLTF_PTRINDEX(cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
   2924 			++i;
   2925 		}
   2926 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "inverseBindMatrices") == 0)
   2927 		{
   2928 			++i;
   2929 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   2930 			out_skin->inverse_bind_matrices = CGLTF_PTRINDEX(cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
   2931 			++i;
   2932 		}
   2933 		else
   2934 		{
   2935 			i = cgltf_skip_json(tokens, i+1);
   2936 		}
   2937 
   2938 		if (i < 0)
   2939 		{
   2940 			return i;
   2941 		}
   2942 	}
   2943 
   2944 	return i;
   2945 }
   2946 
   2947 static int cgltf_parse_json_skins(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   2948 {
   2949 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_skin), (void**)&out_data->skins, &out_data->skins_count);
   2950 	if (i < 0)
   2951 	{
   2952 		return i;
   2953 	}
   2954 
   2955 	for (cgltf_size j = 0; j < out_data->skins_count; ++j)
   2956 	{
   2957 		i = cgltf_parse_json_skin(options, tokens, i, json_chunk, &out_data->skins[j]);
   2958 		if (i < 0)
   2959 		{
   2960 			return i;
   2961 		}
   2962 	}
   2963 	return i;
   2964 }
   2965 
   2966 static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_camera* out_camera)
   2967 {
   2968 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2969 
   2970 	int size = tokens[i].size;
   2971 	++i;
   2972 
   2973 	for (int j = 0; j < size; ++j)
   2974 	{
   2975 		CGLTF_CHECK_KEY(tokens[i]);
   2976 
   2977 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   2978 		{
   2979 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_camera->name);
   2980 		}
   2981 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "type") == 0)
   2982 		{
   2983 			++i;
   2984 			if (cgltf_json_strcmp(tokens + i, json_chunk, "perspective") == 0)
   2985 			{
   2986 				out_camera->type = cgltf_camera_type_perspective;
   2987 			}
   2988 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "orthographic") == 0)
   2989 			{
   2990 				out_camera->type = cgltf_camera_type_orthographic;
   2991 			}
   2992 			++i;
   2993 		}
   2994 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "perspective") == 0)
   2995 		{
   2996 			++i;
   2997 
   2998 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   2999 
   3000 			int data_size = tokens[i].size;
   3001 			++i;
   3002 
   3003 			out_camera->type = cgltf_camera_type_perspective;
   3004 
   3005 			for (int k = 0; k < data_size; ++k)
   3006 			{
   3007 				CGLTF_CHECK_KEY(tokens[i]);
   3008 
   3009 				if (cgltf_json_strcmp(tokens+i, json_chunk, "aspectRatio") == 0)
   3010 				{
   3011 					++i;
   3012 					out_camera->perspective.aspect_ratio = cgltf_json_to_float(tokens + i, json_chunk);
   3013 					++i;
   3014 				}
   3015 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "yfov") == 0)
   3016 				{
   3017 					++i;
   3018 					out_camera->perspective.yfov = cgltf_json_to_float(tokens + i, json_chunk);
   3019 					++i;
   3020 				}
   3021 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "zfar") == 0)
   3022 				{
   3023 					++i;
   3024 					out_camera->perspective.zfar = cgltf_json_to_float(tokens + i, json_chunk);
   3025 					++i;
   3026 				}
   3027 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "znear") == 0)
   3028 				{
   3029 					++i;
   3030 					out_camera->perspective.znear = cgltf_json_to_float(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 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "orthographic") == 0)
   3045 		{
   3046 			++i;
   3047 
   3048 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3049 
   3050 			int data_size = tokens[i].size;
   3051 			++i;
   3052 
   3053 			out_camera->type = cgltf_camera_type_orthographic;
   3054 
   3055 			for (int k = 0; k < data_size; ++k)
   3056 			{
   3057 				CGLTF_CHECK_KEY(tokens[i]);
   3058 
   3059 				if (cgltf_json_strcmp(tokens+i, json_chunk, "xmag") == 0)
   3060 				{
   3061 					++i;
   3062 					out_camera->orthographic.xmag = cgltf_json_to_float(tokens + i, json_chunk);
   3063 					++i;
   3064 				}
   3065 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "ymag") == 0)
   3066 				{
   3067 					++i;
   3068 					out_camera->orthographic.ymag = cgltf_json_to_float(tokens + i, json_chunk);
   3069 					++i;
   3070 				}
   3071 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "zfar") == 0)
   3072 				{
   3073 					++i;
   3074 					out_camera->orthographic.zfar = cgltf_json_to_float(tokens + i, json_chunk);
   3075 					++i;
   3076 				}
   3077 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "znear") == 0)
   3078 				{
   3079 					++i;
   3080 					out_camera->orthographic.znear = cgltf_json_to_float(tokens + i, json_chunk);
   3081 					++i;
   3082 				}
   3083 				else
   3084 				{
   3085 					i = cgltf_skip_json(tokens, i+1);
   3086 				}
   3087 
   3088 				if (i < 0)
   3089 				{
   3090 					return i;
   3091 				}
   3092 			}
   3093 		}
   3094 		else
   3095 		{
   3096 			i = cgltf_skip_json(tokens, i+1);
   3097 		}
   3098 
   3099 		if (i < 0)
   3100 		{
   3101 			return i;
   3102 		}
   3103 	}
   3104 
   3105 	return i;
   3106 }
   3107 
   3108 static int cgltf_parse_json_cameras(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   3109 {
   3110 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_camera), (void**)&out_data->cameras, &out_data->cameras_count);
   3111 	if (i < 0)
   3112 	{
   3113 		return i;
   3114 	}
   3115 
   3116 	for (cgltf_size j = 0; j < out_data->cameras_count; ++j)
   3117 	{
   3118 		i = cgltf_parse_json_camera(options, tokens, i, json_chunk, &out_data->cameras[j]);
   3119 		if (i < 0)
   3120 		{
   3121 			return i;
   3122 		}
   3123 	}
   3124 	return i;
   3125 }
   3126 
   3127 static int cgltf_parse_json_light(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_light* out_light)
   3128 {
   3129 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3130 
   3131 	int size = tokens[i].size;
   3132 	++i;
   3133 
   3134 	for (int j = 0; j < size; ++j)
   3135 	{
   3136 		CGLTF_CHECK_KEY(tokens[i]);
   3137 
   3138 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   3139 		{
   3140 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_light->name);
   3141 		}
   3142 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "color") == 0)
   3143 		{
   3144 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_light->color, 3);
   3145 		}
   3146 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "intensity") == 0)
   3147 		{
   3148 			++i;
   3149 			out_light->intensity = cgltf_json_to_float(tokens + i, json_chunk);
   3150 			++i;
   3151 		}
   3152 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "type") == 0)
   3153 		{
   3154 			++i;
   3155 			if (cgltf_json_strcmp(tokens + i, json_chunk, "directional") == 0)
   3156 			{
   3157 				out_light->type = cgltf_light_type_directional;
   3158 			}
   3159 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "point") == 0)
   3160 			{
   3161 				out_light->type = cgltf_light_type_point;
   3162 			}
   3163 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "spot") == 0)
   3164 			{
   3165 				out_light->type = cgltf_light_type_spot;
   3166 			}
   3167 			++i;
   3168 		}
   3169 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "range") == 0)
   3170 		{
   3171 			++i;
   3172 			out_light->range = cgltf_json_to_float(tokens + i, json_chunk);
   3173 			++i;
   3174 		}
   3175 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "spot") == 0)
   3176 		{
   3177 			++i;
   3178 
   3179 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3180 
   3181 			int data_size = tokens[i].size;
   3182 			++i;
   3183 
   3184 			for (int k = 0; k < data_size; ++k)
   3185 			{
   3186 				CGLTF_CHECK_KEY(tokens[i]);
   3187 
   3188 				if (cgltf_json_strcmp(tokens+i, json_chunk, "innerConeAngle") == 0)
   3189 				{
   3190 					++i;
   3191 					out_light->spot_inner_cone_angle = cgltf_json_to_float(tokens + i, json_chunk);
   3192 					++i;
   3193 				}
   3194 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "outerConeAngle") == 0)
   3195 				{
   3196 					++i;
   3197 					out_light->spot_outer_cone_angle = cgltf_json_to_float(tokens + i, json_chunk);
   3198 					++i;
   3199 				}
   3200 				else
   3201 				{
   3202 					i = cgltf_skip_json(tokens, i+1);
   3203 				}
   3204 
   3205 				if (i < 0)
   3206 				{
   3207 					return i;
   3208 				}
   3209 			}
   3210 		}
   3211 		else
   3212 		{
   3213 			i = cgltf_skip_json(tokens, i+1);
   3214 		}
   3215 
   3216 		if (i < 0)
   3217 		{
   3218 			return i;
   3219 		}
   3220 	}
   3221 
   3222 	return i;
   3223 }
   3224 
   3225 static int cgltf_parse_json_lights(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   3226 {
   3227 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_light), (void**)&out_data->lights, &out_data->lights_count);
   3228 	if (i < 0)
   3229 	{
   3230 		return i;
   3231 	}
   3232 
   3233 	for (cgltf_size j = 0; j < out_data->lights_count; ++j)
   3234 	{
   3235 		i = cgltf_parse_json_light(options, tokens, i, json_chunk, &out_data->lights[j]);
   3236 		if (i < 0)
   3237 		{
   3238 			return i;
   3239 		}
   3240 	}
   3241 	return i;
   3242 }
   3243 
   3244 static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_node* out_node)
   3245 {
   3246 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3247 
   3248 	out_node->rotation[3] = 1.0f;
   3249 	out_node->scale[0] = 1.0f;
   3250 	out_node->scale[1] = 1.0f;
   3251 	out_node->scale[2] = 1.0f;
   3252 	out_node->matrix[0] = 1.0f;
   3253 	out_node->matrix[5] = 1.0f;
   3254 	out_node->matrix[10] = 1.0f;
   3255 	out_node->matrix[15] = 1.0f;
   3256 
   3257 	int size = tokens[i].size;
   3258 	++i;
   3259 
   3260 	for (int j = 0; j < size; ++j)
   3261 	{
   3262 		CGLTF_CHECK_KEY(tokens[i]);
   3263 
   3264 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   3265 		{
   3266 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_node->name);
   3267 		}
   3268 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "children") == 0)
   3269 		{
   3270 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_node*), (void**)&out_node->children, &out_node->children_count);
   3271 			if (i < 0)
   3272 			{
   3273 				return i;
   3274 			}
   3275 
   3276 			for (cgltf_size k = 0; k < out_node->children_count; ++k)
   3277 			{
   3278 				out_node->children[k] = CGLTF_PTRINDEX(cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
   3279 				++i;
   3280 			}
   3281 		}
   3282 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "mesh") == 0)
   3283 		{
   3284 			++i;
   3285 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   3286 			out_node->mesh = CGLTF_PTRINDEX(cgltf_mesh, cgltf_json_to_int(tokens + i, json_chunk));
   3287 			++i;
   3288 		}
   3289 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "skin") == 0)
   3290 		{
   3291 			++i;
   3292 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   3293 			out_node->skin = CGLTF_PTRINDEX(cgltf_skin, cgltf_json_to_int(tokens + i, json_chunk));
   3294 			++i;
   3295 		}
   3296 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "camera") == 0)
   3297 		{
   3298 			++i;
   3299 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   3300 			out_node->camera = CGLTF_PTRINDEX(cgltf_camera, cgltf_json_to_int(tokens + i, json_chunk));
   3301 			++i;
   3302 		}
   3303 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "translation") == 0)
   3304 		{
   3305 			out_node->has_translation = 1;
   3306 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->translation, 3);
   3307 		}
   3308 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "rotation") == 0)
   3309 		{
   3310 			out_node->has_rotation = 1;
   3311 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->rotation, 4);
   3312 		}
   3313 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "scale") == 0)
   3314 		{
   3315 			out_node->has_scale = 1;
   3316 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->scale, 3);
   3317 		}
   3318 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "matrix") == 0)
   3319 		{
   3320 			out_node->has_matrix = 1;
   3321 			i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_node->matrix, 16);
   3322 		}
   3323 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "weights") == 0)
   3324 		{
   3325 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_float), (void**)&out_node->weights, &out_node->weights_count);
   3326 			if (i < 0)
   3327 			{
   3328 				return i;
   3329 			}
   3330 
   3331 			i = cgltf_parse_json_float_array(tokens, i - 1, json_chunk, out_node->weights, (int)out_node->weights_count);
   3332 		}
   3333 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   3334 		{
   3335 			++i;
   3336 
   3337 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3338 
   3339 			int extensions_size = tokens[i].size;
   3340 			++i;
   3341 
   3342 			for (int k = 0; k < extensions_size; ++k)
   3343 			{
   3344 				CGLTF_CHECK_KEY(tokens[i]);
   3345 
   3346 				if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_lights_punctual") == 0)
   3347 				{
   3348 					++i;
   3349 
   3350 					CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3351 
   3352 					int data_size = tokens[i].size;
   3353 					++i;
   3354 
   3355 					for (int m = 0; m < data_size; ++m)
   3356 					{
   3357 						CGLTF_CHECK_KEY(tokens[i]);
   3358 
   3359 						if (cgltf_json_strcmp(tokens + i, json_chunk, "light") == 0)
   3360 						{
   3361 							++i;
   3362 							CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE);
   3363 							out_node->light = CGLTF_PTRINDEX(cgltf_light, cgltf_json_to_int(tokens + i, json_chunk));
   3364 							++i;
   3365 						}
   3366 						else
   3367 						{
   3368 							i = cgltf_skip_json(tokens, i + 1);
   3369 						}
   3370 
   3371 						if (i < 0)
   3372 						{
   3373 							return i;
   3374 						}
   3375 					}
   3376 				}
   3377 				else
   3378 				{
   3379 					i = cgltf_skip_json(tokens, i+1);
   3380 				}
   3381 
   3382 				if (i < 0)
   3383 				{
   3384 					return i;
   3385 				}
   3386 			}
   3387 		}
   3388 		else
   3389 		{
   3390 			i = cgltf_skip_json(tokens, i+1);
   3391 		}
   3392 
   3393 		if (i < 0)
   3394 		{
   3395 			return i;
   3396 		}
   3397 	}
   3398 
   3399 	return i;
   3400 }
   3401 
   3402 static int cgltf_parse_json_nodes(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   3403 {
   3404 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_node), (void**)&out_data->nodes, &out_data->nodes_count);
   3405 	if (i < 0)
   3406 	{
   3407 		return i;
   3408 	}
   3409 
   3410 	for (cgltf_size j = 0; j < out_data->nodes_count; ++j)
   3411 	{
   3412 		i = cgltf_parse_json_node(options, tokens, i, json_chunk, &out_data->nodes[j]);
   3413 		if (i < 0)
   3414 		{
   3415 			return i;
   3416 		}
   3417 	}
   3418 	return i;
   3419 }
   3420 
   3421 static int cgltf_parse_json_scene(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_scene* out_scene)
   3422 {
   3423 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3424 
   3425 	int size = tokens[i].size;
   3426 	++i;
   3427 
   3428 	for (int j = 0; j < size; ++j)
   3429 	{
   3430 		CGLTF_CHECK_KEY(tokens[i]);
   3431 
   3432 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   3433 		{
   3434 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_scene->name);
   3435 		}
   3436 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "nodes") == 0)
   3437 		{
   3438 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_node*), (void**)&out_scene->nodes, &out_scene->nodes_count);
   3439 			if (i < 0)
   3440 			{
   3441 				return i;
   3442 			}
   3443 
   3444 			for (cgltf_size k = 0; k < out_scene->nodes_count; ++k)
   3445 			{
   3446 				out_scene->nodes[k] = CGLTF_PTRINDEX(cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
   3447 				++i;
   3448 			}
   3449 		}
   3450 		else
   3451 		{
   3452 			i = cgltf_skip_json(tokens, i+1);
   3453 		}
   3454 
   3455 		if (i < 0)
   3456 		{
   3457 			return i;
   3458 		}
   3459 	}
   3460 
   3461 	return i;
   3462 }
   3463 
   3464 static int cgltf_parse_json_scenes(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   3465 {
   3466 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_scene), (void**)&out_data->scenes, &out_data->scenes_count);
   3467 	if (i < 0)
   3468 	{
   3469 		return i;
   3470 	}
   3471 
   3472 	for (cgltf_size j = 0; j < out_data->scenes_count; ++j)
   3473 	{
   3474 		i = cgltf_parse_json_scene(options, tokens, i, json_chunk, &out_data->scenes[j]);
   3475 		if (i < 0)
   3476 		{
   3477 			return i;
   3478 		}
   3479 	}
   3480 	return i;
   3481 }
   3482 
   3483 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)
   3484 {
   3485 	(void)options;
   3486 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3487 
   3488 	int size = tokens[i].size;
   3489 	++i;
   3490 
   3491 	for (int j = 0; j < size; ++j)
   3492 	{
   3493 		CGLTF_CHECK_KEY(tokens[i]);
   3494 
   3495 		if (cgltf_json_strcmp(tokens+i, json_chunk, "input") == 0)
   3496 		{
   3497 			++i;
   3498 			out_sampler->input = CGLTF_PTRINDEX(cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
   3499 			++i;
   3500 		}
   3501 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "output") == 0)
   3502 		{
   3503 			++i;
   3504 			out_sampler->output = CGLTF_PTRINDEX(cgltf_accessor, cgltf_json_to_int(tokens + i, json_chunk));
   3505 			++i;
   3506 		}
   3507 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "interpolation") == 0)
   3508 		{
   3509 			++i;
   3510 			if (cgltf_json_strcmp(tokens + i, json_chunk, "LINEAR") == 0)
   3511 			{
   3512 				out_sampler->interpolation = cgltf_interpolation_type_linear;
   3513 			}
   3514 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "STEP") == 0)
   3515 			{
   3516 				out_sampler->interpolation = cgltf_interpolation_type_step;
   3517 			}
   3518 			else if (cgltf_json_strcmp(tokens + i, json_chunk, "CUBICSPLINE") == 0)
   3519 			{
   3520 				out_sampler->interpolation = cgltf_interpolation_type_cubic_spline;
   3521 			}
   3522 			++i;
   3523 		}
   3524 		else
   3525 		{
   3526 			i = cgltf_skip_json(tokens, i+1);
   3527 		}
   3528 
   3529 		if (i < 0)
   3530 		{
   3531 			return i;
   3532 		}
   3533 	}
   3534 
   3535 	return i;
   3536 }
   3537 
   3538 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)
   3539 {
   3540 	(void)options;
   3541 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3542 
   3543 	int size = tokens[i].size;
   3544 	++i;
   3545 
   3546 	for (int j = 0; j < size; ++j)
   3547 	{
   3548 		CGLTF_CHECK_KEY(tokens[i]);
   3549 
   3550 		if (cgltf_json_strcmp(tokens+i, json_chunk, "sampler") == 0)
   3551 		{
   3552 			++i;
   3553 			out_channel->sampler = CGLTF_PTRINDEX(cgltf_animation_sampler, cgltf_json_to_int(tokens + i, json_chunk));
   3554 			++i;
   3555 		}
   3556 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "target") == 0)
   3557 		{
   3558 			++i;
   3559 
   3560 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3561 
   3562 			int target_size = tokens[i].size;
   3563 			++i;
   3564 
   3565 			for (int k = 0; k < target_size; ++k)
   3566 			{
   3567 				CGLTF_CHECK_KEY(tokens[i]);
   3568 
   3569 				if (cgltf_json_strcmp(tokens+i, json_chunk, "node") == 0)
   3570 				{
   3571 					++i;
   3572 					out_channel->target_node = CGLTF_PTRINDEX(cgltf_node, cgltf_json_to_int(tokens + i, json_chunk));
   3573 					++i;
   3574 				}
   3575 				else if (cgltf_json_strcmp(tokens+i, json_chunk, "path") == 0)
   3576 				{
   3577 					++i;
   3578 					if (cgltf_json_strcmp(tokens+i, json_chunk, "translation") == 0)
   3579 					{
   3580 						out_channel->target_path = cgltf_animation_path_type_translation;
   3581 					}
   3582 					else if (cgltf_json_strcmp(tokens+i, json_chunk, "rotation") == 0)
   3583 					{
   3584 						out_channel->target_path = cgltf_animation_path_type_rotation;
   3585 					}
   3586 					else if (cgltf_json_strcmp(tokens+i, json_chunk, "scale") == 0)
   3587 					{
   3588 						out_channel->target_path = cgltf_animation_path_type_scale;
   3589 					}
   3590 					else if (cgltf_json_strcmp(tokens+i, json_chunk, "weights") == 0)
   3591 					{
   3592 						out_channel->target_path = cgltf_animation_path_type_weights;
   3593 					}
   3594 					++i;
   3595 				}
   3596 				else
   3597 				{
   3598 					i = cgltf_skip_json(tokens, i+1);
   3599 				}
   3600 
   3601 				if (i < 0)
   3602 				{
   3603 					return i;
   3604 				}
   3605 			}
   3606 		}
   3607 		else
   3608 		{
   3609 			i = cgltf_skip_json(tokens, i+1);
   3610 		}
   3611 
   3612 		if (i < 0)
   3613 		{
   3614 			return i;
   3615 		}
   3616 	}
   3617 
   3618 	return i;
   3619 }
   3620 
   3621 static int cgltf_parse_json_animation(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_animation* out_animation)
   3622 {
   3623 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3624 
   3625 	int size = tokens[i].size;
   3626 	++i;
   3627 
   3628 	for (int j = 0; j < size; ++j)
   3629 	{
   3630 		CGLTF_CHECK_KEY(tokens[i]);
   3631 
   3632 		if (cgltf_json_strcmp(tokens+i, json_chunk, "name") == 0)
   3633 		{
   3634 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_animation->name);
   3635 		}
   3636 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "samplers") == 0)
   3637 		{
   3638 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_animation_sampler), (void**)&out_animation->samplers, &out_animation->samplers_count);
   3639 			if (i < 0)
   3640 			{
   3641 				return i;
   3642 			}
   3643 
   3644 			for (cgltf_size k = 0; k < out_animation->samplers_count; ++k)
   3645 			{
   3646 				i = cgltf_parse_json_animation_sampler(options, tokens, i, json_chunk, &out_animation->samplers[k]);
   3647 				if (i < 0)
   3648 				{
   3649 					return i;
   3650 				}
   3651 			}
   3652 		}
   3653 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "channels") == 0)
   3654 		{
   3655 			i = cgltf_parse_json_array(options, tokens, i + 1, json_chunk, sizeof(cgltf_animation_channel), (void**)&out_animation->channels, &out_animation->channels_count);
   3656 			if (i < 0)
   3657 			{
   3658 				return i;
   3659 			}
   3660 
   3661 			for (cgltf_size k = 0; k < out_animation->channels_count; ++k)
   3662 			{
   3663 				i = cgltf_parse_json_animation_channel(options, tokens, i, json_chunk, &out_animation->channels[k]);
   3664 				if (i < 0)
   3665 				{
   3666 					return i;
   3667 				}
   3668 			}
   3669 		}
   3670 		else
   3671 		{
   3672 			i = cgltf_skip_json(tokens, i+1);
   3673 		}
   3674 
   3675 		if (i < 0)
   3676 		{
   3677 			return i;
   3678 		}
   3679 	}
   3680 
   3681 	return i;
   3682 }
   3683 
   3684 static int cgltf_parse_json_animations(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   3685 {
   3686 	i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_animation), (void**)&out_data->animations, &out_data->animations_count);
   3687 	if (i < 0)
   3688 	{
   3689 		return i;
   3690 	}
   3691 
   3692 	for (cgltf_size j = 0; j < out_data->animations_count; ++j)
   3693 	{
   3694 		i = cgltf_parse_json_animation(options, tokens, i, json_chunk, &out_data->animations[j]);
   3695 		if (i < 0)
   3696 		{
   3697 			return i;
   3698 		}
   3699 	}
   3700 	return i;
   3701 }
   3702 
   3703 static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_asset* out_asset)
   3704 {
   3705 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3706 
   3707 	int size = tokens[i].size;
   3708 	++i;
   3709 
   3710 	for (int j = 0; j < size; ++j)
   3711 	{
   3712 		CGLTF_CHECK_KEY(tokens[i]);
   3713 
   3714 		if (cgltf_json_strcmp(tokens+i, json_chunk, "copyright") == 0)
   3715 		{
   3716 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->copyright);
   3717 		}
   3718 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "generator") == 0)
   3719 		{
   3720 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->generator);
   3721 		}
   3722 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "version") == 0)
   3723 		{
   3724 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->version);
   3725 		}
   3726 		else if (cgltf_json_strcmp(tokens+i, json_chunk, "minVersion") == 0)
   3727 		{
   3728 			i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_asset->min_version);
   3729 		}
   3730 		else
   3731 		{
   3732 			i = cgltf_skip_json(tokens, i+1);
   3733 		}
   3734 
   3735 		if (i < 0)
   3736 		{
   3737 			return i;
   3738 		}
   3739 	}
   3740 
   3741 	return i;
   3742 }
   3743 
   3744 static cgltf_size cgltf_num_components(cgltf_type type) {
   3745 	switch (type)
   3746 	{
   3747 	case cgltf_type_vec2:
   3748 		return 2;
   3749 	case cgltf_type_vec3:
   3750 		return 3;
   3751 	case cgltf_type_vec4:
   3752 		return 4;
   3753 	case cgltf_type_mat2:
   3754 		return 4;
   3755 	case cgltf_type_mat3:
   3756 		return 9;
   3757 	case cgltf_type_mat4:
   3758 		return 16;
   3759 	case cgltf_type_invalid:
   3760 	case cgltf_type_scalar:
   3761 	default:
   3762 		return 1;
   3763 	}
   3764 }
   3765 
   3766 static cgltf_size cgltf_component_size(cgltf_component_type component_type) {
   3767 	switch (component_type)
   3768 	{
   3769 	case cgltf_component_type_r_8:
   3770 	case cgltf_component_type_r_8u:
   3771 		return 1;
   3772 	case cgltf_component_type_r_16:
   3773 	case cgltf_component_type_r_16u:
   3774 		return 2;
   3775 	case cgltf_component_type_r_32u:
   3776 	case cgltf_component_type_r_32f:
   3777 		return 4;
   3778 	case cgltf_component_type_invalid:
   3779 	default:
   3780 		return 0;
   3781 	}
   3782 }
   3783 
   3784 static cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type)
   3785 {
   3786 	cgltf_size component_size = cgltf_component_size(component_type);
   3787 	if (type == cgltf_type_mat2 && component_size == 1)
   3788 	{
   3789 		return 8 * component_size;
   3790 	}
   3791 	else if (type == cgltf_type_mat3 && (component_size == 1 || component_size == 2))
   3792 	{
   3793 		return 12 * component_size;
   3794 	}
   3795 	return component_size * cgltf_num_components(type);
   3796 }
   3797 
   3798 static int cgltf_fixup_pointers(cgltf_data* out_data);
   3799 
   3800 static int cgltf_parse_json_root(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
   3801 {
   3802 	CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3803 
   3804 	int size = tokens[i].size;
   3805 	++i;
   3806 
   3807 	for (int j = 0; j < size; ++j)
   3808 	{
   3809 		CGLTF_CHECK_KEY(tokens[i]);
   3810 
   3811 		if (cgltf_json_strcmp(tokens + i, json_chunk, "asset") == 0)
   3812 		{
   3813 			i = cgltf_parse_json_asset(options, tokens, i + 1, json_chunk, &out_data->asset);
   3814 		}
   3815 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "meshes") == 0)
   3816 		{
   3817 			i = cgltf_parse_json_meshes(options, tokens, i + 1, json_chunk, out_data);
   3818 		}
   3819 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "accessors") == 0)
   3820 		{
   3821 			i = cgltf_parse_json_accessors(options, tokens, i + 1, json_chunk, out_data);
   3822 		}
   3823 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "bufferViews") == 0)
   3824 		{
   3825 			i = cgltf_parse_json_buffer_views(options, tokens, i + 1, json_chunk, out_data);
   3826 		}
   3827 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "buffers") == 0)
   3828 		{
   3829 			i = cgltf_parse_json_buffers(options, tokens, i + 1, json_chunk, out_data);
   3830 		}
   3831 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "materials") == 0)
   3832 		{
   3833 			i = cgltf_parse_json_materials(options, tokens, i + 1, json_chunk, out_data);
   3834 		}
   3835 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "images") == 0)
   3836 		{
   3837 			i = cgltf_parse_json_images(options, tokens, i + 1, json_chunk, out_data);
   3838 		}
   3839 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "textures") == 0)
   3840 		{
   3841 			i = cgltf_parse_json_textures(options, tokens, i + 1, json_chunk, out_data);
   3842 		}
   3843 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "samplers") == 0)
   3844 		{
   3845 			i = cgltf_parse_json_samplers(options, tokens, i + 1, json_chunk, out_data);
   3846 		}
   3847 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "skins") == 0)
   3848 		{
   3849 			i = cgltf_parse_json_skins(options, tokens, i + 1, json_chunk, out_data);
   3850 		}
   3851 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "cameras") == 0)
   3852 		{
   3853 			i = cgltf_parse_json_cameras(options, tokens, i + 1, json_chunk, out_data);
   3854 		}
   3855 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "nodes") == 0)
   3856 		{
   3857 			i = cgltf_parse_json_nodes(options, tokens, i + 1, json_chunk, out_data);
   3858 		}
   3859 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "scenes") == 0)
   3860 		{
   3861 			i = cgltf_parse_json_scenes(options, tokens, i + 1, json_chunk, out_data);
   3862 		}
   3863 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "scene") == 0)
   3864 		{
   3865 			++i;
   3866 			out_data->scene = CGLTF_PTRINDEX(cgltf_scene, cgltf_json_to_int(tokens + i, json_chunk));
   3867 			++i;
   3868 		}
   3869 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "animations") == 0)
   3870 		{
   3871 			i = cgltf_parse_json_animations(options, tokens, i + 1, json_chunk, out_data);
   3872 		}
   3873 		else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
   3874 		{
   3875 			++i;
   3876 
   3877 			CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3878 
   3879 			int extensions_size = tokens[i].size;
   3880 			++i;
   3881 
   3882 			for (int k = 0; k < extensions_size; ++k)
   3883 			{
   3884 				CGLTF_CHECK_KEY(tokens[i]);
   3885 
   3886 				if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_lights_punctual") == 0)
   3887 				{
   3888 					++i;
   3889 
   3890 					CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
   3891 
   3892 					int data_size = tokens[i].size;
   3893 					++i;
   3894 
   3895 					for (int m = 0; m < data_size; ++m)
   3896 					{
   3897 						CGLTF_CHECK_KEY(tokens[i]);
   3898 
   3899 						if (cgltf_json_strcmp(tokens + i, json_chunk, "lights") == 0)
   3900 						{
   3901 							i = cgltf_parse_json_lights(options, tokens, i + 1, json_chunk, out_data);
   3902 						}
   3903 						else
   3904 						{
   3905 							i = cgltf_skip_json(tokens, i + 1);
   3906 						}
   3907 
   3908 						if (i < 0)
   3909 						{
   3910 							return i;
   3911 						}
   3912 					}
   3913 				}
   3914 				else
   3915 				{
   3916 					i = cgltf_skip_json(tokens, i+1);
   3917 				}
   3918 
   3919 				if (i < 0)
   3920 				{
   3921 					return i;
   3922 				}
   3923 			}
   3924 		}
   3925 		else
   3926 		{
   3927 			i = cgltf_skip_json(tokens, i + 1);
   3928 		}
   3929 
   3930 		if (i < 0)
   3931 		{
   3932 			return i;
   3933 		}
   3934 	}
   3935 
   3936 	return i;
   3937 }
   3938 
   3939 cgltf_result cgltf_parse_json(cgltf_options* options, const uint8_t* json_chunk, cgltf_size size, cgltf_data** out_data)
   3940 {
   3941 	jsmn_parser parser = { 0, 0, 0 };
   3942 
   3943 	if (options->json_token_count == 0)
   3944 	{
   3945 		int token_count = jsmn_parse(&parser, (const char*)json_chunk, size, NULL, 0);
   3946 
   3947 		if (token_count <= 0)
   3948 		{
   3949 			return cgltf_result_invalid_json;
   3950 		}
   3951 
   3952 		options->json_token_count = token_count;
   3953 	}
   3954 
   3955 	jsmntok_t* tokens = (jsmntok_t*)options->memory_alloc(options->memory_user_data, sizeof(jsmntok_t) * options->json_token_count);
   3956 
   3957 	if (!tokens)
   3958 	{
   3959 		return cgltf_result_out_of_memory;
   3960 	}
   3961 
   3962 	jsmn_init(&parser);
   3963 
   3964 	int token_count = jsmn_parse(&parser, (const char*)json_chunk, size, tokens, options->json_token_count);
   3965 
   3966 	if (token_count <= 0)
   3967 	{
   3968 		options->memory_free(options->memory_user_data, tokens);
   3969 		return cgltf_result_invalid_json;
   3970 	}
   3971 
   3972 	cgltf_data* data = (cgltf_data*)options->memory_alloc(options->memory_user_data, sizeof(cgltf_data));
   3973 
   3974 	if (!data)
   3975 	{
   3976 		options->memory_free(options->memory_user_data, tokens);
   3977 		return cgltf_result_out_of_memory;
   3978 	}
   3979 
   3980 	memset(data, 0, sizeof(cgltf_data));
   3981 	data->memory_free = options->memory_free;
   3982 	data->memory_user_data = options->memory_user_data;
   3983 
   3984 	int i = cgltf_parse_json_root(options, tokens, 0, json_chunk, data);
   3985 
   3986 	options->memory_free(options->memory_user_data, tokens);
   3987 
   3988 	if (i < 0)
   3989 	{
   3990 		cgltf_free(data);
   3991 		return (i == CGLTF_ERROR_NOMEM) ? cgltf_result_out_of_memory : cgltf_result_invalid_gltf;
   3992 	}
   3993 
   3994 	if (cgltf_fixup_pointers(data) < 0)
   3995 	{
   3996 		cgltf_free(data);
   3997 		return cgltf_result_invalid_gltf;
   3998 	}
   3999 
   4000 	*out_data = data;
   4001 
   4002 	return cgltf_result_success;
   4003 }
   4004 
   4005 static int cgltf_fixup_pointers(cgltf_data* data)
   4006 {
   4007 	for (cgltf_size i = 0; i < data->meshes_count; ++i)
   4008 	{
   4009 		for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
   4010 		{
   4011 			CGLTF_PTRFIXUP(data->meshes[i].primitives[j].indices, data->accessors, data->accessors_count);
   4012 			CGLTF_PTRFIXUP(data->meshes[i].primitives[j].material, data->materials, data->materials_count);
   4013 
   4014 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
   4015 			{
   4016 				CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].attributes[k].data, data->accessors, data->accessors_count);
   4017 			}
   4018 
   4019 			for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
   4020 			{
   4021 				for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
   4022 				{
   4023 					CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].targets[k].attributes[m].data, data->accessors, data->accessors_count);
   4024 				}
   4025 			}
   4026 		}
   4027 	}
   4028 
   4029 	for (cgltf_size i = 0; i < data->accessors_count; ++i)
   4030 	{
   4031 		CGLTF_PTRFIXUP(data->accessors[i].buffer_view, data->buffer_views, data->buffer_views_count);
   4032 
   4033 		if (data->accessors[i].is_sparse)
   4034 		{
   4035 			CGLTF_PTRFIXUP_REQ(data->accessors[i].sparse.indices_buffer_view, data->buffer_views, data->buffer_views_count);
   4036 			CGLTF_PTRFIXUP_REQ(data->accessors[i].sparse.values_buffer_view, data->buffer_views, data->buffer_views_count);
   4037 		}
   4038 
   4039 		if (data->accessors[i].buffer_view)
   4040 		{
   4041 			data->accessors[i].stride = data->accessors[i].buffer_view->stride;
   4042 		}
   4043 
   4044 		if (data->accessors[i].stride == 0)
   4045 		{
   4046 			data->accessors[i].stride = cgltf_calc_size(data->accessors[i].type, data->accessors[i].component_type);
   4047 		}
   4048 	}
   4049 
   4050 	for (cgltf_size i = 0; i < data->textures_count; ++i)
   4051 	{
   4052 		CGLTF_PTRFIXUP(data->textures[i].image, data->images, data->images_count);
   4053 		CGLTF_PTRFIXUP(data->textures[i].sampler, data->samplers, data->samplers_count);
   4054 	}
   4055 
   4056 	for (cgltf_size i = 0; i < data->images_count; ++i)
   4057 	{
   4058 		CGLTF_PTRFIXUP(data->images[i].buffer_view, data->buffer_views, data->buffer_views_count);
   4059 	}
   4060 
   4061 	for (cgltf_size i = 0; i < data->materials_count; ++i)
   4062 	{
   4063 		CGLTF_PTRFIXUP(data->materials[i].normal_texture.texture, data->textures, data->textures_count);
   4064 		CGLTF_PTRFIXUP(data->materials[i].emissive_texture.texture, data->textures, data->textures_count);
   4065 		CGLTF_PTRFIXUP(data->materials[i].occlusion_texture.texture, data->textures, data->textures_count);
   4066 
   4067 		CGLTF_PTRFIXUP(data->materials[i].pbr_metallic_roughness.base_color_texture.texture, data->textures, data->textures_count);
   4068 		CGLTF_PTRFIXUP(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture, data->textures, data->textures_count);
   4069 
   4070 		CGLTF_PTRFIXUP(data->materials[i].pbr_specular_glossiness.diffuse_texture.texture, data->textures, data->textures_count);
   4071 		CGLTF_PTRFIXUP(data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.texture, data->textures, data->textures_count);
   4072 	}
   4073 
   4074 	for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
   4075 	{
   4076 		CGLTF_PTRFIXUP_REQ(data->buffer_views[i].buffer, data->buffers, data->buffers_count);
   4077 	}
   4078 
   4079 	for (cgltf_size i = 0; i < data->skins_count; ++i)
   4080 	{
   4081 		for (cgltf_size j = 0; j < data->skins[i].joints_count; ++j)
   4082 		{
   4083 			CGLTF_PTRFIXUP_REQ(data->skins[i].joints[j], data->nodes, data->nodes_count);
   4084 		}
   4085 
   4086 		CGLTF_PTRFIXUP(data->skins[i].skeleton, data->nodes, data->nodes_count);
   4087 		CGLTF_PTRFIXUP(data->skins[i].inverse_bind_matrices, data->accessors, data->accessors_count);
   4088 	}
   4089 
   4090 	for (cgltf_size i = 0; i < data->nodes_count; ++i)
   4091 	{
   4092 		for (cgltf_size j = 0; j < data->nodes[i].children_count; ++j)
   4093 		{
   4094 			CGLTF_PTRFIXUP_REQ(data->nodes[i].children[j], data->nodes, data->nodes_count);
   4095 
   4096 			if (data->nodes[i].children[j]->parent)
   4097 			{
   4098 				return CGLTF_ERROR_JSON;
   4099 			}
   4100 
   4101 			data->nodes[i].children[j]->parent = &data->nodes[i];
   4102 		}
   4103 
   4104 		CGLTF_PTRFIXUP(data->nodes[i].mesh, data->meshes, data->meshes_count);
   4105 		CGLTF_PTRFIXUP(data->nodes[i].skin, data->skins, data->skins_count);
   4106 		CGLTF_PTRFIXUP(data->nodes[i].camera, data->cameras, data->cameras_count);
   4107 		CGLTF_PTRFIXUP(data->nodes[i].light, data->lights, data->lights_count);
   4108 	}
   4109 
   4110 	for (cgltf_size i = 0; i < data->scenes_count; ++i)
   4111 	{
   4112 		for (cgltf_size j = 0; j < data->scenes[i].nodes_count; ++j)
   4113 		{
   4114 			CGLTF_PTRFIXUP_REQ(data->scenes[i].nodes[j], data->nodes, data->nodes_count);
   4115 
   4116 			if (data->scenes[i].nodes[j]->parent)
   4117 			{
   4118 				return CGLTF_ERROR_JSON;
   4119 			}
   4120 		}
   4121 	}
   4122 
   4123 	CGLTF_PTRFIXUP(data->scene, data->scenes, data->scenes_count);
   4124 
   4125 	for (cgltf_size i = 0; i < data->animations_count; ++i)
   4126 	{
   4127 		for (cgltf_size j = 0; j < data->animations[i].samplers_count; ++j)
   4128 		{
   4129 			CGLTF_PTRFIXUP_REQ(data->animations[i].samplers[j].input, data->accessors, data->accessors_count);
   4130 			CGLTF_PTRFIXUP_REQ(data->animations[i].samplers[j].output, data->accessors, data->accessors_count);
   4131 		}
   4132 
   4133 		for (cgltf_size j = 0; j < data->animations[i].channels_count; ++j)
   4134 		{
   4135 			CGLTF_PTRFIXUP_REQ(data->animations[i].channels[j].sampler, data->animations[i].samplers, data->animations[i].samplers_count);
   4136 			CGLTF_PTRFIXUP(data->animations[i].channels[j].target_node, data->nodes, data->nodes_count);
   4137 		}
   4138 	}
   4139 
   4140 	return 0;
   4141 }
   4142 
   4143 /*
   4144  * -- jsmn.c start --
   4145  * Source: https://github.com/zserge/jsmn
   4146  * License: MIT
   4147  *
   4148  * Copyright (c) 2010 Serge A. Zaitsev
   4149 
   4150  * Permission is hereby granted, free of charge, to any person obtaining a copy
   4151  * of this software and associated documentation files (the "Software"), to deal
   4152  * in the Software without restriction, including without limitation the rights
   4153  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   4154  * copies of the Software, and to permit persons to whom the Software is
   4155  * furnished to do so, subject to the following conditions:
   4156 
   4157  * The above copyright notice and this permission notice shall be included in
   4158  * all copies or substantial portions of the Software.
   4159 
   4160  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   4161  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   4162  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   4163  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   4164  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   4165  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   4166  * THE SOFTWARE.
   4167  */
   4168 
   4169 /**
   4170  * Allocates a fresh unused token from the token pull.
   4171  */
   4172 static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
   4173 				   jsmntok_t *tokens, size_t num_tokens) {
   4174 	jsmntok_t *tok;
   4175 	if (parser->toknext >= num_tokens) {
   4176 		return NULL;
   4177 	}
   4178 	tok = &tokens[parser->toknext++];
   4179 	tok->start = tok->end = -1;
   4180 	tok->size = 0;
   4181 #ifdef JSMN_PARENT_LINKS
   4182 	tok->parent = -1;
   4183 #endif
   4184 	return tok;
   4185 }
   4186 
   4187 /**
   4188  * Fills token type and boundaries.
   4189  */
   4190 static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
   4191 			    int start, int end) {
   4192 	token->type = type;
   4193 	token->start = start;
   4194 	token->end = end;
   4195 	token->size = 0;
   4196 }
   4197 
   4198 /**
   4199  * Fills next available token with JSON primitive.
   4200  */
   4201 static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
   4202 				size_t len, jsmntok_t *tokens, size_t num_tokens) {
   4203 	jsmntok_t *token;
   4204 	int start;
   4205 
   4206 	start = parser->pos;
   4207 
   4208 	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
   4209 		switch (js[parser->pos]) {
   4210 #ifndef JSMN_STRICT
   4211 		/* In strict mode primitive must be followed by "," or "}" or "]" */
   4212 		case ':':
   4213 #endif
   4214 		case '\t' : case '\r' : case '\n' : case ' ' :
   4215 		case ','  : case ']'  : case '}' :
   4216 			goto found;
   4217 		}
   4218 		if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
   4219 			parser->pos = start;
   4220 			return JSMN_ERROR_INVAL;
   4221 		}
   4222 	}
   4223 #ifdef JSMN_STRICT
   4224 	/* In strict mode primitive must be followed by a comma/object/array */
   4225 	parser->pos = start;
   4226 	return JSMN_ERROR_PART;
   4227 #endif
   4228 
   4229 found:
   4230 	if (tokens == NULL) {
   4231 		parser->pos--;
   4232 		return 0;
   4233 	}
   4234 	token = jsmn_alloc_token(parser, tokens, num_tokens);
   4235 	if (token == NULL) {
   4236 		parser->pos = start;
   4237 		return JSMN_ERROR_NOMEM;
   4238 	}
   4239 	jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
   4240 #ifdef JSMN_PARENT_LINKS
   4241 	token->parent = parser->toksuper;
   4242 #endif
   4243 	parser->pos--;
   4244 	return 0;
   4245 }
   4246 
   4247 /**
   4248  * Fills next token with JSON string.
   4249  */
   4250 static int jsmn_parse_string(jsmn_parser *parser, const char *js,
   4251 			     size_t len, jsmntok_t *tokens, size_t num_tokens) {
   4252 	jsmntok_t *token;
   4253 
   4254 	int start = parser->pos;
   4255 
   4256 	parser->pos++;
   4257 
   4258 	/* Skip starting quote */
   4259 	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
   4260 		char c = js[parser->pos];
   4261 
   4262 		/* Quote: end of string */
   4263 		if (c == '\"') {
   4264 			if (tokens == NULL) {
   4265 				return 0;
   4266 			}
   4267 			token = jsmn_alloc_token(parser, tokens, num_tokens);
   4268 			if (token == NULL) {
   4269 				parser->pos = start;
   4270 				return JSMN_ERROR_NOMEM;
   4271 			}
   4272 			jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
   4273 #ifdef JSMN_PARENT_LINKS
   4274 			token->parent = parser->toksuper;
   4275 #endif
   4276 			return 0;
   4277 		}
   4278 
   4279 		/* Backslash: Quoted symbol expected */
   4280 		if (c == '\\' && parser->pos + 1 < len) {
   4281 			int i;
   4282 			parser->pos++;
   4283 			switch (js[parser->pos]) {
   4284 			/* Allowed escaped symbols */
   4285 			case '\"': case '/' : case '\\' : case 'b' :
   4286 			case 'f' : case 'r' : case 'n'  : case 't' :
   4287 				break;
   4288 				/* Allows escaped symbol \uXXXX */
   4289 			case 'u':
   4290 				parser->pos++;
   4291 				for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) {
   4292 					/* If it isn't a hex character we have an error */
   4293 					if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
   4294 					     (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
   4295 					     (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
   4296 						parser->pos = start;
   4297 						return JSMN_ERROR_INVAL;
   4298 					}
   4299 					parser->pos++;
   4300 				}
   4301 				parser->pos--;
   4302 				break;
   4303 				/* Unexpected symbol */
   4304 			default:
   4305 				parser->pos = start;
   4306 				return JSMN_ERROR_INVAL;
   4307 			}
   4308 		}
   4309 	}
   4310 	parser->pos = start;
   4311 	return JSMN_ERROR_PART;
   4312 }
   4313 
   4314 /**
   4315  * Parse JSON string and fill tokens.
   4316  */
   4317 static int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
   4318 	       jsmntok_t *tokens, size_t num_tokens) {
   4319 	int r;
   4320 	int i;
   4321 	jsmntok_t *token;
   4322 	int count = parser->toknext;
   4323 
   4324 	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
   4325 		char c;
   4326 		jsmntype_t type;
   4327 
   4328 		c = js[parser->pos];
   4329 		switch (c) {
   4330 		case '{': case '[':
   4331 			count++;
   4332 			if (tokens == NULL) {
   4333 				break;
   4334 			}
   4335 			token = jsmn_alloc_token(parser, tokens, num_tokens);
   4336 			if (token == NULL)
   4337 				return JSMN_ERROR_NOMEM;
   4338 			if (parser->toksuper != -1) {
   4339 				tokens[parser->toksuper].size++;
   4340 #ifdef JSMN_PARENT_LINKS
   4341 				token->parent = parser->toksuper;
   4342 #endif
   4343 			}
   4344 			token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
   4345 			token->start = parser->pos;
   4346 			parser->toksuper = parser->toknext - 1;
   4347 			break;
   4348 		case '}': case ']':
   4349 			if (tokens == NULL)
   4350 				break;
   4351 			type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
   4352 #ifdef JSMN_PARENT_LINKS
   4353 			if (parser->toknext < 1) {
   4354 				return JSMN_ERROR_INVAL;
   4355 			}
   4356 			token = &tokens[parser->toknext - 1];
   4357 			for (;;) {
   4358 				if (token->start != -1 && token->end == -1) {
   4359 					if (token->type != type) {
   4360 						return JSMN_ERROR_INVAL;
   4361 					}
   4362 					token->end = parser->pos + 1;
   4363 					parser->toksuper = token->parent;
   4364 					break;
   4365 				}
   4366 				if (token->parent == -1) {
   4367 					if(token->type != type || parser->toksuper == -1) {
   4368 						return JSMN_ERROR_INVAL;
   4369 					}
   4370 					break;
   4371 				}
   4372 				token = &tokens[token->parent];
   4373 			}
   4374 #else
   4375 			for (i = parser->toknext - 1; i >= 0; i--) {
   4376 				token = &tokens[i];
   4377 				if (token->start != -1 && token->end == -1) {
   4378 					if (token->type != type) {
   4379 						return JSMN_ERROR_INVAL;
   4380 					}
   4381 					parser->toksuper = -1;
   4382 					token->end = parser->pos + 1;
   4383 					break;
   4384 				}
   4385 			}
   4386 			/* Error if unmatched closing bracket */
   4387 			if (i == -1) return JSMN_ERROR_INVAL;
   4388 			for (; i >= 0; i--) {
   4389 				token = &tokens[i];
   4390 				if (token->start != -1 && token->end == -1) {
   4391 					parser->toksuper = i;
   4392 					break;
   4393 				}
   4394 			}
   4395 #endif
   4396 			break;
   4397 		case '\"':
   4398 			r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
   4399 			if (r < 0) return r;
   4400 			count++;
   4401 			if (parser->toksuper != -1 && tokens != NULL)
   4402 				tokens[parser->toksuper].size++;
   4403 			break;
   4404 		case '\t' : case '\r' : case '\n' : case ' ':
   4405 			break;
   4406 		case ':':
   4407 			parser->toksuper = parser->toknext - 1;
   4408 			break;
   4409 		case ',':
   4410 			if (tokens != NULL && parser->toksuper != -1 &&
   4411 					tokens[parser->toksuper].type != JSMN_ARRAY &&
   4412 					tokens[parser->toksuper].type != JSMN_OBJECT) {
   4413 #ifdef JSMN_PARENT_LINKS
   4414 				parser->toksuper = tokens[parser->toksuper].parent;
   4415 #else
   4416 				for (i = parser->toknext - 1; i >= 0; i--) {
   4417 					if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
   4418 						if (tokens[i].start != -1 && tokens[i].end == -1) {
   4419 							parser->toksuper = i;
   4420 							break;
   4421 						}
   4422 					}
   4423 				}
   4424 #endif
   4425 			}
   4426 			break;
   4427 #ifdef JSMN_STRICT
   4428 			/* In strict mode primitives are: numbers and booleans */
   4429 		case '-': case '0': case '1' : case '2': case '3' : case '4':
   4430 		case '5': case '6': case '7' : case '8': case '9':
   4431 		case 't': case 'f': case 'n' :
   4432 			/* And they must not be keys of the object */
   4433 			if (tokens != NULL && parser->toksuper != -1) {
   4434 				jsmntok_t *t = &tokens[parser->toksuper];
   4435 				if (t->type == JSMN_OBJECT ||
   4436 						(t->type == JSMN_STRING && t->size != 0)) {
   4437 					return JSMN_ERROR_INVAL;
   4438 				}
   4439 			}
   4440 #else
   4441 			/* In non-strict mode every unquoted value is a primitive */
   4442 		default:
   4443 #endif
   4444 			r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
   4445 			if (r < 0) return r;
   4446 			count++;
   4447 			if (parser->toksuper != -1 && tokens != NULL)
   4448 				tokens[parser->toksuper].size++;
   4449 			break;
   4450 
   4451 #ifdef JSMN_STRICT
   4452 			/* Unexpected char in strict mode */
   4453 		default:
   4454 			return JSMN_ERROR_INVAL;
   4455 #endif
   4456 		}
   4457 	}
   4458 
   4459 	if (tokens != NULL) {
   4460 		for (i = parser->toknext - 1; i >= 0; i--) {
   4461 			/* Unmatched opened object or array */
   4462 			if (tokens[i].start != -1 && tokens[i].end == -1) {
   4463 				return JSMN_ERROR_PART;
   4464 			}
   4465 		}
   4466 	}
   4467 
   4468 	return count;
   4469 }
   4470 
   4471 /**
   4472  * Creates a new parser based over a given  buffer with an array of tokens
   4473  * available.
   4474  */
   4475 static void jsmn_init(jsmn_parser *parser) {
   4476 	parser->pos = 0;
   4477 	parser->toknext = 0;
   4478 	parser->toksuper = -1;
   4479 }
   4480 /*
   4481  * -- jsmn.c end --
   4482  */
   4483 
   4484 #endif /* #ifdef CGLTF_IMPLEMENTATION */
   4485 
   4486 /* cgltf is distributed under MIT license:
   4487  *
   4488  * Copyright (c) 2018 Johannes Kuhlmann
   4489 
   4490  * Permission is hereby granted, free of charge, to any person obtaining a copy
   4491  * of this software and associated documentation files (the "Software"), to deal
   4492  * in the Software without restriction, including without limitation the rights
   4493  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   4494  * copies of the Software, and to permit persons to whom the Software is
   4495  * furnished to do so, subject to the following conditions:
   4496 
   4497  * The above copyright notice and this permission notice shall be included in all
   4498  * copies or substantial portions of the Software.
   4499 
   4500  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   4501  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   4502  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   4503  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   4504  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   4505  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   4506  * SOFTWARE.
   4507  */