From dace2172d194c057359ccc101278d38cf2f75649 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 13 Sep 2020 15:55:48 +0200 Subject: [PATCH] Update cgltf library to v1.7 --- src/external/cgltf.h | 686 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 649 insertions(+), 37 deletions(-) diff --git a/src/external/cgltf.h b/src/external/cgltf.h index bbc641cf..ec1c5557 100644 --- a/src/external/cgltf.h +++ b/src/external/cgltf.h @@ -1,7 +1,7 @@ /** * cgltf - a single-file glTF 2.0 parser written in C99. * - * Version: 1.5 + * Version: 1.7 * * Website: https://github.com/jkuhlmann/cgltf * @@ -239,12 +239,19 @@ typedef struct cgltf_extras { cgltf_size end_offset; } cgltf_extras; +typedef struct cgltf_extension { + char* name; + char* data; +} cgltf_extension; + typedef struct cgltf_buffer { cgltf_size size; char* uri; void* data; /* loaded by cgltf_load_buffers */ cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_buffer; typedef struct cgltf_buffer_view @@ -255,6 +262,8 @@ typedef struct cgltf_buffer_view cgltf_size stride; /* 0 == automatically determined by accessor */ cgltf_buffer_view_type type; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_buffer_view; typedef struct cgltf_accessor_sparse @@ -268,6 +277,12 @@ typedef struct cgltf_accessor_sparse cgltf_extras extras; cgltf_extras indices_extras; cgltf_extras values_extras; + cgltf_size extensions_count; + cgltf_extension* extensions; + cgltf_size indices_extensions_count; + cgltf_extension* indices_extensions; + cgltf_size values_extensions_count; + cgltf_extension* values_extensions; } cgltf_accessor_sparse; typedef struct cgltf_accessor @@ -286,6 +301,8 @@ typedef struct cgltf_accessor cgltf_bool is_sparse; cgltf_accessor_sparse sparse; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_accessor; typedef struct cgltf_attribute @@ -303,6 +320,8 @@ typedef struct cgltf_image cgltf_buffer_view* buffer_view; char* mime_type; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_image; typedef struct cgltf_sampler @@ -312,6 +331,8 @@ typedef struct cgltf_sampler cgltf_int wrap_s; cgltf_int wrap_t; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_sampler; typedef struct cgltf_texture @@ -320,6 +341,8 @@ typedef struct cgltf_texture cgltf_image* image; cgltf_sampler* sampler; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_texture; typedef struct cgltf_texture_transform @@ -338,6 +361,8 @@ typedef struct cgltf_texture_view cgltf_bool has_transform; cgltf_texture_transform transform; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_texture_view; typedef struct cgltf_pbr_metallic_roughness @@ -362,13 +387,40 @@ typedef struct cgltf_pbr_specular_glossiness cgltf_float glossiness_factor; } cgltf_pbr_specular_glossiness; +typedef struct cgltf_clearcoat +{ + cgltf_texture_view clearcoat_texture; + cgltf_texture_view clearcoat_roughness_texture; + cgltf_texture_view clearcoat_normal_texture; + + cgltf_float clearcoat_factor; + cgltf_float clearcoat_roughness_factor; +} cgltf_clearcoat; + +typedef struct cgltf_transmission +{ + cgltf_texture_view transmission_texture; + cgltf_float transmission_factor; +} cgltf_transmission; + +typedef struct cgltf_ior +{ + cgltf_float ior; +} cgltf_ior; + typedef struct cgltf_material { char* name; cgltf_bool has_pbr_metallic_roughness; cgltf_bool has_pbr_specular_glossiness; + cgltf_bool has_clearcoat; + cgltf_bool has_transmission; + cgltf_bool has_ior; cgltf_pbr_metallic_roughness pbr_metallic_roughness; cgltf_pbr_specular_glossiness pbr_specular_glossiness; + cgltf_clearcoat clearcoat; + cgltf_ior ior; + cgltf_transmission transmission; cgltf_texture_view normal_texture; cgltf_texture_view occlusion_texture; cgltf_texture_view emissive_texture; @@ -378,6 +430,8 @@ typedef struct cgltf_material cgltf_bool double_sided; cgltf_bool unlit; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_material; typedef struct cgltf_morph_target { @@ -385,6 +439,12 @@ typedef struct cgltf_morph_target { cgltf_size attributes_count; } cgltf_morph_target; +typedef struct cgltf_draco_mesh_compression { + cgltf_buffer_view* buffer_view; + cgltf_attribute* attributes; + cgltf_size attributes_count; +} cgltf_draco_mesh_compression; + typedef struct cgltf_primitive { cgltf_primitive_type type; cgltf_accessor* indices; @@ -394,6 +454,10 @@ typedef struct cgltf_primitive { cgltf_morph_target* targets; cgltf_size targets_count; cgltf_extras extras; + cgltf_bool has_draco_mesh_compression; + cgltf_draco_mesh_compression draco_mesh_compression; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_primitive; typedef struct cgltf_mesh { @@ -405,6 +469,8 @@ typedef struct cgltf_mesh { char** target_names; cgltf_size target_names_count; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_mesh; typedef struct cgltf_node cgltf_node; @@ -416,6 +482,8 @@ typedef struct cgltf_skin { cgltf_node* skeleton; cgltf_accessor* inverse_bind_matrices; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_skin; typedef struct cgltf_camera_perspective { @@ -442,6 +510,8 @@ typedef struct cgltf_camera { cgltf_camera_orthographic orthographic; } data; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_camera; typedef struct cgltf_light { @@ -474,6 +544,8 @@ struct cgltf_node { cgltf_float scale[3]; cgltf_float matrix[16]; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; }; typedef struct cgltf_scene { @@ -481,6 +553,8 @@ typedef struct cgltf_scene { cgltf_node** nodes; cgltf_size nodes_count; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_scene; typedef struct cgltf_animation_sampler { @@ -488,6 +562,8 @@ typedef struct cgltf_animation_sampler { cgltf_accessor* output; cgltf_interpolation_type interpolation; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_animation_sampler; typedef struct cgltf_animation_channel { @@ -495,6 +571,8 @@ typedef struct cgltf_animation_channel { cgltf_node* target_node; cgltf_animation_path_type target_path; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_animation_channel; typedef struct cgltf_animation { @@ -504,6 +582,8 @@ typedef struct cgltf_animation { cgltf_animation_channel* channels; cgltf_size channels_count; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_animation; typedef struct cgltf_asset { @@ -512,6 +592,8 @@ typedef struct cgltf_asset { char* version; char* min_version; cgltf_extras extras; + cgltf_size extensions_count; + cgltf_extension* extensions; } cgltf_asset; typedef struct cgltf_data @@ -567,6 +649,9 @@ typedef struct cgltf_data cgltf_extras extras; + cgltf_size data_extensions_count; + cgltf_extension* data_extensions; + char** extensions_used; cgltf_size extensions_used_count; @@ -599,9 +684,10 @@ cgltf_result cgltf_load_buffers( cgltf_data* data, const char* gltf_path); - cgltf_result cgltf_load_buffer_base64(const cgltf_options* options, cgltf_size size, const char* base64, void** out_data); +void cgltf_decode_uri(char* uri); + cgltf_result cgltf_validate(cgltf_data* data); void cgltf_free(cgltf_data* data); @@ -632,8 +718,8 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* * */ -#ifdef __INTELLISENSE__ -/* This makes MSVC intellisense work. */ +#if defined(__INTELLISENSE__) || defined(__JETBRAINS_IDE__) +/* This makes MSVC/CLion intellisense work. */ #define CGLTF_IMPLEMENTATION #endif @@ -948,7 +1034,6 @@ cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cg return cgltf_result_invalid_options; } - void* (*memory_alloc)(void*, cgltf_size) = options->memory.alloc ? options->memory.alloc : &cgltf_default_alloc; void (*memory_free)(void*, void*) = options->memory.free ? options->memory.free : &cgltf_default_free; cgltf_result (*file_read)(const struct cgltf_memory_options*, const struct cgltf_file_options*, const char*, cgltf_size*, void**) = options->file.read ? options->file.read : &cgltf_default_file_read; @@ -1006,16 +1091,17 @@ static cgltf_result cgltf_load_buffer_file(const cgltf_options* options, cgltf_s cgltf_combine_paths(path, gltf_path, uri); + // after combining, the tail of the resulting path is a uri; decode_uri converts it into path + cgltf_decode_uri(path + strlen(path) - strlen(uri)); + void* file_data = NULL; cgltf_result result = file_read(&options->memory, &options->file, path, &size, &file_data); - if (result != cgltf_result_success) - { - return result; - } - *out_data = file_data; + memory_free(options->memory.user_data, path); - return cgltf_result_success; + *out_data = (result == cgltf_result_success) ? file_data : NULL; + + return result; } cgltf_result cgltf_load_buffer_base64(const cgltf_options* options, cgltf_size size, const char* base64, void** out_data) @@ -1065,6 +1151,45 @@ cgltf_result cgltf_load_buffer_base64(const cgltf_options* options, cgltf_size s return cgltf_result_success; } +static int cgltf_unhex(char ch) +{ + return + (unsigned)(ch - '0') < 10 ? (ch - '0') : + (unsigned)(ch - 'A') < 6 ? (ch - 'A') + 10 : + (unsigned)(ch - 'a') < 6 ? (ch - 'a') + 10 : + -1; +} + +void cgltf_decode_uri(char* uri) +{ + char* write = uri; + char* i = uri; + + while (*i) + { + if (*i == '%') + { + int ch1 = cgltf_unhex(i[1]); + + if (ch1 >= 0) + { + int ch2 = cgltf_unhex(i[2]); + + if (ch2 >= 0) + { + *write++ = (char)(ch1 * 16 + ch2); + i += 3; + continue; + } + } + } + + *write++ = *i++; + } + + *write = 0; +} + cgltf_result cgltf_load_buffers(const cgltf_options* options, cgltf_data* data, const char* gltf_path) { if (options == NULL) @@ -1406,6 +1531,16 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* return cgltf_result_success; } +void cgltf_free_extensions(cgltf_data* data, cgltf_extension* extensions, cgltf_size extensions_count) +{ + for (cgltf_size i = 0; i < extensions_count; ++i) + { + data->memory.free(data->memory.user_data, extensions[i].name); + data->memory.free(data->memory.user_data, extensions[i].data); + } + data->memory.free(data->memory.user_data, extensions); +} + void cgltf_free(cgltf_data* data) { if (!data) @@ -1420,7 +1555,24 @@ void cgltf_free(cgltf_data* data) data->memory.free(data->memory.user_data, data->asset.version); data->memory.free(data->memory.user_data, data->asset.min_version); + cgltf_free_extensions(data, data->asset.extensions, data->asset.extensions_count); + + for (cgltf_size i = 0; i < data->accessors_count; ++i) + { + if(data->accessors[i].is_sparse) + { + cgltf_free_extensions(data, data->accessors[i].sparse.extensions, data->accessors[i].sparse.extensions_count); + cgltf_free_extensions(data, data->accessors[i].sparse.indices_extensions, data->accessors[i].sparse.indices_extensions_count); + cgltf_free_extensions(data, data->accessors[i].sparse.values_extensions, data->accessors[i].sparse.values_extensions_count); + } + cgltf_free_extensions(data, data->accessors[i].extensions, data->accessors[i].extensions_count); + } data->memory.free(data->memory.user_data, data->accessors); + + for (cgltf_size i = 0; i < data->buffer_views_count; ++i) + { + cgltf_free_extensions(data, data->buffer_views[i].extensions, data->buffer_views[i].extensions_count); + } data->memory.free(data->memory.user_data, data->buffer_views); for (cgltf_size i = 0; i < data->buffers_count; ++i) @@ -1429,8 +1581,9 @@ void cgltf_free(cgltf_data* data) { file_release(&data->memory, &data->file, data->buffers[i].data); } - data->memory.free(data->memory.user_data, data->buffers[i].uri); + + cgltf_free_extensions(data, data->buffers[i].extensions, data->buffers[i].extensions_count); } data->memory.free(data->memory.user_data, data->buffers); @@ -1459,6 +1612,18 @@ void cgltf_free(cgltf_data* data) } data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].targets); + + if (data->meshes[i].primitives[j].has_draco_mesh_compression) + { + for (cgltf_size k = 0; k < data->meshes[i].primitives[j].draco_mesh_compression.attributes_count; ++k) + { + data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes[k].name); + } + + data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes); + } + + cgltf_free_extensions(data, data->meshes[i].primitives[j].extensions, data->meshes[i].primitives[j].extensions_count); } data->memory.free(data->memory.user_data, data->meshes[i].primitives); @@ -1469,6 +1634,8 @@ void cgltf_free(cgltf_data* data) data->memory.free(data->memory.user_data, data->meshes[i].target_names[j]); } + cgltf_free_extensions(data, data->meshes[i].extensions, data->meshes[i].extensions_count); + data->memory.free(data->memory.user_data, data->meshes[i].target_names); } @@ -1477,6 +1644,33 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->materials_count; ++i) { data->memory.free(data->memory.user_data, data->materials[i].name); + + if(data->materials[i].has_pbr_metallic_roughness) + { + cgltf_free_extensions(data, data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.extensions, data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.extensions_count); + cgltf_free_extensions(data, data->materials[i].pbr_metallic_roughness.base_color_texture.extensions, data->materials[i].pbr_metallic_roughness.base_color_texture.extensions_count); + } + if(data->materials[i].has_pbr_specular_glossiness) + { + cgltf_free_extensions(data, data->materials[i].pbr_specular_glossiness.diffuse_texture.extensions, data->materials[i].pbr_specular_glossiness.diffuse_texture.extensions_count); + cgltf_free_extensions(data, data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.extensions, data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.extensions_count); + } + if(data->materials[i].has_clearcoat) + { + cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_texture.extensions, data->materials[i].clearcoat.clearcoat_texture.extensions_count); + cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_roughness_texture.extensions, data->materials[i].clearcoat.clearcoat_roughness_texture.extensions_count); + cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_normal_texture.extensions, data->materials[i].clearcoat.clearcoat_normal_texture.extensions_count); + } + if(data->materials[i].has_transmission) + { + cgltf_free_extensions(data, data->materials[i].transmission.transmission_texture.extensions, data->materials[i].transmission.transmission_texture.extensions_count); + } + + cgltf_free_extensions(data, data->materials[i].normal_texture.extensions, data->materials[i].normal_texture.extensions_count); + cgltf_free_extensions(data, data->materials[i].occlusion_texture.extensions, data->materials[i].occlusion_texture.extensions_count); + cgltf_free_extensions(data, data->materials[i].emissive_texture.extensions, data->materials[i].emissive_texture.extensions_count); + + cgltf_free_extensions(data, data->materials[i].extensions, data->materials[i].extensions_count); } data->memory.free(data->memory.user_data, data->materials); @@ -1486,6 +1680,8 @@ void cgltf_free(cgltf_data* data) data->memory.free(data->memory.user_data, data->images[i].name); data->memory.free(data->memory.user_data, data->images[i].uri); data->memory.free(data->memory.user_data, data->images[i].mime_type); + + cgltf_free_extensions(data, data->images[i].extensions, data->images[i].extensions_count); } data->memory.free(data->memory.user_data, data->images); @@ -1493,16 +1689,24 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->textures_count; ++i) { data->memory.free(data->memory.user_data, data->textures[i].name); + cgltf_free_extensions(data, data->textures[i].extensions, data->textures[i].extensions_count); } data->memory.free(data->memory.user_data, data->textures); + for (cgltf_size i = 0; i < data->samplers_count; ++i) + { + cgltf_free_extensions(data, data->samplers[i].extensions, data->samplers[i].extensions_count); + } + data->memory.free(data->memory.user_data, data->samplers); for (cgltf_size i = 0; i < data->skins_count; ++i) { data->memory.free(data->memory.user_data, data->skins[i].name); data->memory.free(data->memory.user_data, data->skins[i].joints); + + cgltf_free_extensions(data, data->skins[i].extensions, data->skins[i].extensions_count); } data->memory.free(data->memory.user_data, data->skins); @@ -1510,6 +1714,7 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->cameras_count; ++i) { data->memory.free(data->memory.user_data, data->cameras[i].name); + cgltf_free_extensions(data, data->cameras[i].extensions, data->cameras[i].extensions_count); } data->memory.free(data->memory.user_data, data->cameras); @@ -1526,6 +1731,7 @@ void cgltf_free(cgltf_data* data) data->memory.free(data->memory.user_data, data->nodes[i].name); data->memory.free(data->memory.user_data, data->nodes[i].children); data->memory.free(data->memory.user_data, data->nodes[i].weights); + cgltf_free_extensions(data, data->nodes[i].extensions, data->nodes[i].extensions_count); } data->memory.free(data->memory.user_data, data->nodes); @@ -1534,6 +1740,8 @@ void cgltf_free(cgltf_data* data) { data->memory.free(data->memory.user_data, data->scenes[i].name); data->memory.free(data->memory.user_data, data->scenes[i].nodes); + + cgltf_free_extensions(data, data->scenes[i].extensions, data->scenes[i].extensions_count); } data->memory.free(data->memory.user_data, data->scenes); @@ -1541,12 +1749,25 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->animations_count; ++i) { data->memory.free(data->memory.user_data, data->animations[i].name); + for (cgltf_size j = 0; j < data->animations[i].samplers_count; ++j) + { + cgltf_free_extensions(data, data->animations[i].samplers[j].extensions, data->animations[i].samplers[j].extensions_count); + } data->memory.free(data->memory.user_data, data->animations[i].samplers); + + for (cgltf_size j = 0; j < data->animations[i].channels_count; ++j) + { + cgltf_free_extensions(data, data->animations[i].channels[j].extensions, data->animations[i].channels[j].extensions_count); + } data->memory.free(data->memory.user_data, data->animations[i].channels); + + cgltf_free_extensions(data, data->animations[i].extensions, data->animations[i].extensions_count); } data->memory.free(data->memory.user_data, data->animations); + cgltf_free_extensions(data, data->data_extensions, data->data_extensions_count); + for (cgltf_size i = 0; i < data->extensions_used_count; ++i) { data->memory.free(data->memory.user_data, data->extensions_used[i]); @@ -1852,8 +2073,6 @@ static cgltf_uint cgltf_component_read_uint(const void* in, cgltf_component_type default: return 0; } - - return 0; } static cgltf_bool cgltf_element_read_uint(const uint8_t* element, cgltf_type type, cgltf_component_type component_type, cgltf_uint* out, cgltf_size element_size) @@ -2173,6 +2392,103 @@ static int cgltf_parse_json_extras(jsmntok_t const* tokens, int i, const uint8_t return i; } +static int cgltf_parse_json_unprocessed_extension(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_extension* out_extension) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_STRING); + CGLTF_CHECK_TOKTYPE(tokens[i+1], JSMN_OBJECT); + if (out_extension->name) + { + return CGLTF_ERROR_JSON; + } + + cgltf_size name_length = tokens[i].end - tokens[i].start; + out_extension->name = (char*)options->memory.alloc(options->memory.user_data, name_length + 1); + if (!out_extension->name) + { + return CGLTF_ERROR_NOMEM; + } + strncpy(out_extension->name, (const char*)json_chunk + tokens[i].start, name_length); + out_extension->name[name_length] = 0; + i++; + + size_t start = tokens[i].start; + size_t size = tokens[i].end - start; + out_extension->data = (char*)options->memory.alloc(options->memory.user_data, size + 1); + if (!out_extension->data) + { + return CGLTF_ERROR_NOMEM; + } + strncpy(out_extension->data, (const char*)json_chunk + start, size); + out_extension->data[size] = '\0'; + + i = cgltf_skip_json(tokens, i); + + return i; +} + +static int cgltf_parse_json_unprocessed_extensions(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_size* out_extensions_count, cgltf_extension** out_extensions) +{ + ++i; + + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(*out_extensions) + { + return CGLTF_ERROR_JSON; + } + + int extensions_size = tokens[i].size; + *out_extensions_count = 0; + *out_extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); + + if (!*out_extensions) + { + return CGLTF_ERROR_NOMEM; + } + + ++i; + + for (int j = 0; j < extensions_size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + cgltf_size extension_index = (*out_extensions_count)++; + cgltf_extension* extension = &((*out_extensions)[extension_index]); + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, extension); + + if (i < 0) + { + return i; + } + } + return i; +} + +static int cgltf_parse_json_draco_mesh_compression(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_draco_mesh_compression* out_draco_mesh_compression) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + + int size = tokens[i].size; + ++i; + + for (int j = 0; j < size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens + i, json_chunk, "attributes") == 0) + { + i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_draco_mesh_compression->attributes, &out_draco_mesh_compression->attributes_count); + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "bufferView") == 0) + { + ++i; + out_draco_mesh_compression->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk)); + ++i; + } + } + + return i; +} + static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_primitive* out_prim) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -2231,6 +2547,46 @@ static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* t { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_prim->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + ++i; + + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(out_prim->extensions) + { + return CGLTF_ERROR_JSON; + } + + int extensions_size = tokens[i].size; + out_prim->extensions_count = 0; + out_prim->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); + + if (!out_prim->extensions) + { + return CGLTF_ERROR_NOMEM; + } + + ++i; + for (int k = 0; k < extensions_size; ++k) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_draco_mesh_compression") == 0) + { + out_prim->has_draco_mesh_compression = 1; + i = cgltf_parse_json_draco_mesh_compression(options, tokens, i + 1, json_chunk, &out_prim->draco_mesh_compression); + } + else + { + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_prim->extensions[out_prim->extensions_count++])); + } + + if (i < 0) + { + return i; + } + } + } else { i = cgltf_skip_json(tokens, i+1); @@ -2323,6 +2679,10 @@ static int cgltf_parse_json_mesh(cgltf_options* options, jsmntok_t const* tokens i = cgltf_skip_json(tokens, i); } } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_mesh->extensions_count, &out_mesh->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -2379,7 +2739,7 @@ static cgltf_component_type cgltf_json_to_component_type(jsmntok_t const* tok, c } } -static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor_sparse* out_sparse) +static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor_sparse* out_sparse) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -2430,6 +2790,10 @@ static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, cons { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->indices_extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->indices_extensions_count, &out_sparse->indices_extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -2469,6 +2833,10 @@ static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, cons { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->values_extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->values_extensions_count, &out_sparse->values_extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -2484,6 +2852,10 @@ static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, cons { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->extensions_count, &out_sparse->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -2498,7 +2870,7 @@ static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, cons return i; } -static int cgltf_parse_json_accessor(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor* out_accessor) +static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor* out_accessor) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -2593,12 +2965,16 @@ static int cgltf_parse_json_accessor(jsmntok_t const* tokens, int i, const uint8 else if (cgltf_json_strcmp(tokens + i, json_chunk, "sparse") == 0) { out_accessor->is_sparse = 1; - i = cgltf_parse_json_accessor_sparse(tokens, i + 1, json_chunk, &out_accessor->sparse); + i = cgltf_parse_json_accessor_sparse(options, tokens, i + 1, json_chunk, &out_accessor->sparse); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_accessor->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_accessor->extensions_count, &out_accessor->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -2658,7 +3034,7 @@ static int cgltf_parse_json_texture_transform(jsmntok_t const* tokens, int i, co return i; } -static int cgltf_parse_json_texture_view(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture_view* out_texture_view) +static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture_view* out_texture_view) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -2705,8 +3081,20 @@ static int cgltf_parse_json_texture_view(jsmntok_t const* tokens, int i, const u ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(out_texture_view->extensions) + { + return CGLTF_ERROR_JSON; + } int extensions_size = tokens[i].size; + out_texture_view->extensions_count = 0; + out_texture_view->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); + + if (!out_texture_view->extensions) + { + return CGLTF_ERROR_NOMEM; + } + ++i; for (int k = 0; k < extensions_size; ++k) @@ -2720,7 +3108,7 @@ static int cgltf_parse_json_texture_view(jsmntok_t const* tokens, int i, const u } else { - i = cgltf_skip_json(tokens, i+1); + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture_view->extensions[out_texture_view->extensions_count++])); } if (i < 0) @@ -2743,7 +3131,7 @@ static int cgltf_parse_json_texture_view(jsmntok_t const* tokens, int i, const u return i; } -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) +static int cgltf_parse_json_pbr_metallic_roughness(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_pbr_metallic_roughness* out_pbr) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -2774,12 +3162,12 @@ static int cgltf_parse_json_pbr_metallic_roughness(jsmntok_t const* tokens, int } else if (cgltf_json_strcmp(tokens+i, json_chunk, "baseColorTexture") == 0) { - i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk, + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->base_color_texture); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "metallicRoughnessTexture") == 0) { - i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk, + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->metallic_roughness_texture); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) @@ -2800,7 +3188,7 @@ static int cgltf_parse_json_pbr_metallic_roughness(jsmntok_t const* tokens, int return i; } -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) +static int cgltf_parse_json_pbr_specular_glossiness(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_pbr_specular_glossiness* out_pbr) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); int size = tokens[i].size; @@ -2826,11 +3214,123 @@ static int cgltf_parse_json_pbr_specular_glossiness(jsmntok_t const* tokens, int } else if (cgltf_json_strcmp(tokens+i, json_chunk, "diffuseTexture") == 0) { - i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk, &out_pbr->diffuse_texture); + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->diffuse_texture); } else if (cgltf_json_strcmp(tokens+i, json_chunk, "specularGlossinessTexture") == 0) { - i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk, &out_pbr->specular_glossiness_texture); + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->specular_glossiness_texture); + } + else + { + i = cgltf_skip_json(tokens, i+1); + } + + if (i < 0) + { + return i; + } + } + + return i; +} + +static int cgltf_parse_json_clearcoat(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_clearcoat* out_clearcoat) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i].size; + ++i; + + for (int j = 0; j < size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens+i, json_chunk, "clearcoatFactor") == 0) + { + ++i; + out_clearcoat->clearcoat_factor = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else if (cgltf_json_strcmp(tokens+i, json_chunk, "clearcoatRoughnessFactor") == 0) + { + ++i; + out_clearcoat->clearcoat_roughness_factor = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else if (cgltf_json_strcmp(tokens+i, json_chunk, "clearcoatTexture") == 0) + { + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_texture); + } + else if (cgltf_json_strcmp(tokens+i, json_chunk, "clearcoatRoughnessTexture") == 0) + { + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_roughness_texture); + } + else if (cgltf_json_strcmp(tokens+i, json_chunk, "clearcoatNormalTexture") == 0) + { + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_clearcoat->clearcoat_normal_texture); + } + else + { + i = cgltf_skip_json(tokens, i+1); + } + + if (i < 0) + { + return i; + } + } + + return i; +} + +static int cgltf_parse_json_ior(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_ior* out_ior) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i].size; + ++i; + + for (int j = 0; j < size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens+i, json_chunk, "ior") == 0) + { + ++i; + out_ior->ior = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else + { + i = cgltf_skip_json(tokens, i+1); + } + + if (i < 0) + { + return i; + } + } + + return i; +} + +static int cgltf_parse_json_transmission(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_transmission* out_transmission) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i].size; + ++i; + + for (int j = 0; j < size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens+i, json_chunk, "transmissionFactor") == 0) + { + ++i; + out_transmission->transmission_factor = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else if (cgltf_json_strcmp(tokens+i, json_chunk, "transmissionTexture") == 0) + { + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_transmission->transmission_texture); } else { @@ -2879,6 +3379,10 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_image->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_image->extensions_count, &out_image->extensions); + } else { i = cgltf_skip_json(tokens, i + 1); @@ -2940,6 +3444,10 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sampler->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->extensions_count, &out_sampler->extensions); + } else { i = cgltf_skip_json(tokens, i + 1); @@ -2954,7 +3462,6 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok return i; } - static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture* out_texture) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -2986,6 +3493,10 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_texture->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_texture->extensions_count, &out_texture->extensions); + } else { i = cgltf_skip_json(tokens, i + 1); @@ -3028,7 +3539,7 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to else if (cgltf_json_strcmp(tokens+i, json_chunk, "pbrMetallicRoughness") == 0) { out_material->has_pbr_metallic_roughness = 1; - i = cgltf_parse_json_pbr_metallic_roughness(tokens, i + 1, json_chunk, &out_material->pbr_metallic_roughness); + i = cgltf_parse_json_pbr_metallic_roughness(options, tokens, i + 1, json_chunk, &out_material->pbr_metallic_roughness); } else if (cgltf_json_strcmp(tokens+i, json_chunk, "emissiveFactor") == 0) { @@ -3036,17 +3547,17 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to } else if (cgltf_json_strcmp(tokens + i, json_chunk, "normalTexture") == 0) { - i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk, + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_material->normal_texture); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "occlusionTexture") == 0) { - i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk, + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_material->occlusion_texture); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "emissiveTexture") == 0) { - i = cgltf_parse_json_texture_view(tokens, i + 1, json_chunk, + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_material->emissive_texture); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "alphaMode") == 0) @@ -3088,9 +3599,20 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(out_material->extensions) + { + return CGLTF_ERROR_JSON; + } int extensions_size = tokens[i].size; ++i; + out_material->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); + out_material->extensions_count= 0; + + if (!out_material->extensions) + { + return CGLTF_ERROR_NOMEM; + } for (int k = 0; k < extensions_size; ++k) { @@ -3099,16 +3621,31 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_pbrSpecularGlossiness") == 0) { out_material->has_pbr_specular_glossiness = 1; - i = cgltf_parse_json_pbr_specular_glossiness(tokens, i + 1, json_chunk, &out_material->pbr_specular_glossiness); + i = cgltf_parse_json_pbr_specular_glossiness(options, tokens, i + 1, json_chunk, &out_material->pbr_specular_glossiness); } else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_unlit") == 0) { out_material->unlit = 1; i = cgltf_skip_json(tokens, i+1); } + else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_clearcoat") == 0) + { + out_material->has_clearcoat = 1; + i = cgltf_parse_json_clearcoat(options, tokens, i + 1, json_chunk, &out_material->clearcoat); + } + else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_ior") == 0) + { + out_material->has_ior = 1; + i = cgltf_parse_json_ior(tokens, i + 1, json_chunk, &out_material->ior); + } + else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_transmission") == 0) + { + out_material->has_transmission = 1; + i = cgltf_parse_json_transmission(options, tokens, i + 1, json_chunk, &out_material->transmission); + } else { - i = cgltf_skip_json(tokens, i+1); + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++])); } if (i < 0) @@ -3141,7 +3678,7 @@ static int cgltf_parse_json_accessors(cgltf_options* options, jsmntok_t const* t for (cgltf_size j = 0; j < out_data->accessors_count; ++j) { - i = cgltf_parse_json_accessor(tokens, i, json_chunk, &out_data->accessors[j]); + i = cgltf_parse_json_accessor(options, tokens, i, json_chunk, &out_data->accessors[j]); if (i < 0) { return i; @@ -3226,7 +3763,7 @@ static int cgltf_parse_json_samplers(cgltf_options* options, jsmntok_t const* to return i; } -static int cgltf_parse_json_buffer_view(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_buffer_view* out_buffer_view) +static int cgltf_parse_json_buffer_view(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_buffer_view* out_buffer_view) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -3287,6 +3824,10 @@ static int cgltf_parse_json_buffer_view(jsmntok_t const* tokens, int i, const ui { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_buffer_view->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_buffer_view->extensions_count, &out_buffer_view->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -3311,7 +3852,7 @@ static int cgltf_parse_json_buffer_views(cgltf_options* options, jsmntok_t const for (cgltf_size j = 0; j < out_data->buffer_views_count; ++j) { - i = cgltf_parse_json_buffer_view(tokens, i, json_chunk, &out_data->buffer_views[j]); + i = cgltf_parse_json_buffer_view(options, tokens, i, json_chunk, &out_data->buffer_views[j]); if (i < 0) { return i; @@ -3346,6 +3887,10 @@ static int cgltf_parse_json_buffer(cgltf_options* options, jsmntok_t const* toke { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_buffer->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_buffer->extensions_count, &out_buffer->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -3426,6 +3971,10 @@ static int cgltf_parse_json_skin(cgltf_options* options, jsmntok_t const* tokens { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_skin->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_skin->extensions_count, &out_skin->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -3599,6 +4148,10 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_camera->extensions_count, &out_camera->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -3847,8 +4400,20 @@ static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(out_node->extensions) + { + return CGLTF_ERROR_JSON; + } int extensions_size = tokens[i].size; + out_node->extensions_count= 0; + out_node->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); + + if (!out_node->extensions) + { + return CGLTF_ERROR_NOMEM; + } + ++i; for (int k = 0; k < extensions_size; ++k) @@ -3888,7 +4453,7 @@ static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens } else { - i = cgltf_skip_json(tokens, i+1); + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_node->extensions[out_node->extensions_count++])); } if (i < 0) @@ -3963,6 +4528,10 @@ static int cgltf_parse_json_scene(cgltf_options* options, jsmntok_t const* token { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_scene->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_scene->extensions_count, &out_scene->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -4041,6 +4610,10 @@ static int cgltf_parse_json_animation_sampler(cgltf_options* options, jsmntok_t { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sampler->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sampler->extensions_count, &out_sampler->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -4117,6 +4690,10 @@ static int cgltf_parse_json_animation_channel(cgltf_options* options, jsmntok_t { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_channel->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_channel->extensions_count, &out_channel->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -4195,6 +4772,10 @@ static int cgltf_parse_json_animation(cgltf_options* options, jsmntok_t const* t { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_animation->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_animation->extensions_count, &out_animation->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -4259,6 +4840,10 @@ static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* token { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_asset->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_asset->extensions_count, &out_asset->extensions); + } else { i = cgltf_skip_json(tokens, i+1); @@ -4416,8 +5001,20 @@ static int cgltf_parse_json_root(cgltf_options* options, jsmntok_t const* tokens ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(out_data->data_extensions) + { + return CGLTF_ERROR_JSON; + } int extensions_size = tokens[i].size; + out_data->data_extensions_count = 0; + out_data->data_extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); + + if (!out_data->data_extensions) + { + return CGLTF_ERROR_NOMEM; + } + ++i; for (int k = 0; k < extensions_size; ++k) @@ -4454,7 +5051,7 @@ static int cgltf_parse_json_root(cgltf_options* options, jsmntok_t const* tokens } else { - i = cgltf_skip_json(tokens, i + 1); + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_data->data_extensions[out_data->data_extensions_count++])); } if (i < 0) @@ -4585,6 +5182,15 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].targets[k].attributes[m].data, data->accessors, data->accessors_count); } } + + if (data->meshes[i].primitives[j].has_draco_mesh_compression) + { + CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.buffer_view, data->buffer_views, data->buffer_views_count); + for (cgltf_size m = 0; m < data->meshes[i].primitives[j].draco_mesh_compression.attributes_count; ++m) + { + CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.attributes[m].data, data->accessors, data->accessors_count); + } + } } } @@ -4631,6 +5237,12 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP(data->materials[i].pbr_specular_glossiness.diffuse_texture.texture, data->textures, data->textures_count); CGLTF_PTRFIXUP(data->materials[i].pbr_specular_glossiness.specular_glossiness_texture.texture, data->textures, data->textures_count); + + CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_texture.texture, data->textures, data->textures_count); + CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_roughness_texture.texture, data->textures, data->textures_count); + CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_normal_texture.texture, data->textures, data->textures_count); + + CGLTF_PTRFIXUP(data->materials[i].transmission.transmission_texture.texture, data->textures, data->textures_count); } for (cgltf_size i = 0; i < data->buffer_views_count; ++i)