From 2d1606b34e8653f4c721d7379093acf78ce70d1b Mon Sep 17 00:00:00 2001 From: Todd Zhang Date: Thu, 2 Nov 2023 10:59:11 -0700 Subject: [PATCH 1/5] support KHR_xmp_json_ld read in cgltf.h --- cgltf.h | 427 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 409 insertions(+), 18 deletions(-) diff --git a/cgltf.h b/cgltf.h index ddec501..82f28bf 100644 --- a/cgltf.h +++ b/cgltf.h @@ -253,6 +253,16 @@ typedef enum cgltf_data_free_method { cgltf_data_free_method_max_enum } cgltf_data_free_method; +typedef struct cgltf_xmp_json_ld_packet +{ + char* data; +} cgltf_xmp_json_ld_packet; + +typedef struct cgltf_xmp_json_ld +{ + unsigned int pos; +} cgltf_xmp_json_ld; + typedef struct cgltf_extras { cgltf_size start_offset; /* this field is deprecated and will be removed in the future; use data instead */ cgltf_size end_offset; /* this field is deprecated and will be removed in the future; use data instead */ @@ -273,6 +283,8 @@ typedef struct cgltf_buffer void* data; /* loaded by cgltf_load_buffers */ cgltf_data_free_method data_free_method; cgltf_extras extras; + cgltf_size xmp_json_ld_count; + cgltf_xmp_json_ld *xmp_json_ld; cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_buffer; @@ -366,7 +378,9 @@ typedef struct cgltf_image cgltf_buffer_view* buffer_view; char* mime_type; cgltf_extras extras; - cgltf_size extensions_count; + cgltf_size xmp_json_ld_count; + cgltf_xmp_json_ld *xmp_json_ld; + cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_image; @@ -533,6 +547,8 @@ typedef struct cgltf_material cgltf_bool double_sided; cgltf_bool unlit; cgltf_extras extras; + cgltf_size xmp_json_ld_count; + cgltf_xmp_json_ld *xmp_json_ld; cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_material; @@ -586,7 +602,9 @@ typedef struct cgltf_mesh { char** target_names; cgltf_size target_names_count; cgltf_extras extras; - cgltf_size extensions_count; + cgltf_size xmp_json_ld_count; + cgltf_xmp_json_ld *xmp_json_ld; + cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_mesh; @@ -664,6 +682,8 @@ struct cgltf_node { cgltf_float scale[3]; cgltf_float matrix[16]; cgltf_extras extras; + cgltf_size xmp_json_ld_count; + cgltf_xmp_json_ld *xmp_json_ld; cgltf_bool has_mesh_gpu_instancing; cgltf_mesh_gpu_instancing mesh_gpu_instancing; cgltf_size extensions_count; @@ -675,6 +695,8 @@ typedef struct cgltf_scene { cgltf_node** nodes; cgltf_size nodes_count; cgltf_extras extras; + cgltf_size xmp_json_ld_count; + cgltf_xmp_json_ld *xmp_json_ld; cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_scene; @@ -704,6 +726,8 @@ typedef struct cgltf_animation { cgltf_animation_channel* channels; cgltf_size channels_count; cgltf_extras extras; + cgltf_size xmp_json_ld_count; + cgltf_xmp_json_ld *xmp_json_ld; cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_animation; @@ -720,6 +744,8 @@ typedef struct cgltf_asset { char* version; char* min_version; cgltf_extras extras; + cgltf_size xmp_json_ld_count; + cgltf_xmp_json_ld *xmp_json_ld; cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_asset; @@ -780,6 +806,9 @@ typedef struct cgltf_data cgltf_extras extras; + cgltf_size xmp_json_ld_packets_count; + cgltf_xmp_json_ld_packet* xmp_json_ld_packets; // just store the packets + cgltf_size data_extensions_count; cgltf_extension* data_extensions; @@ -1787,6 +1816,7 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->asset.generator); data->memory.free_func(data->memory.user_data, data->asset.version); data->memory.free_func(data->memory.user_data, data->asset.min_version); + data->memory.free_func(data->memory.user_data, data->asset.xmp_json_ld); cgltf_free_extensions(data, data->asset.extensions, data->asset.extensions_count); cgltf_free_extras(data, &data->asset.extras); @@ -1833,6 +1863,7 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->meshes_count; ++i) { data->memory.free_func(data->memory.user_data, data->meshes[i].name); + data->memory.free_func(data->memory.user_data, data->meshes[i].xmp_json_ld); for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j) { @@ -1895,6 +1926,7 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->materials_count; ++i) { data->memory.free_func(data->memory.user_data, data->materials[i].name); + data->memory.free_func(data->memory.user_data, data->materials[i].xmp_json_ld); cgltf_free_extensions(data, data->materials[i].extensions, data->materials[i].extensions_count); cgltf_free_extras(data, &data->materials[i].extras); @@ -1907,6 +1939,8 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->images[i].name); data->memory.free_func(data->memory.user_data, data->images[i].uri); data->memory.free_func(data->memory.user_data, data->images[i].mime_type); + data->memory.free_func(data->memory.user_data, data->images[i].xmp_json_ld); + cgltf_free_extensions(data, data->images[i].extensions, data->images[i].extensions_count); cgltf_free_extras(data, &data->images[i].extras); @@ -1978,6 +2012,7 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->nodes[i].name); data->memory.free_func(data->memory.user_data, data->nodes[i].children); data->memory.free_func(data->memory.user_data, data->nodes[i].weights); + data->memory.free_func(data->memory.user_data, data->nodes[i].xmp_json_ld); if (data->nodes[i].has_mesh_gpu_instancing) { @@ -1999,6 +2034,7 @@ void cgltf_free(cgltf_data* data) { data->memory.free_func(data->memory.user_data, data->scenes[i].name); data->memory.free_func(data->memory.user_data, data->scenes[i].nodes); + data->memory.free_func(data->memory.user_data, data->scenes[i].xmp_json_ld); cgltf_free_extensions(data, data->scenes[i].extensions, data->scenes[i].extensions_count); cgltf_free_extras(data, &data->scenes[i].extras); @@ -2022,6 +2058,7 @@ void cgltf_free(cgltf_data* data) cgltf_free_extras(data, &data->animations[i].channels[j].extras); } data->memory.free_func(data->memory.user_data, data->animations[i].channels); + data->memory.free_func(data->memory.user_data, data->animations[i].xmp_json_ld); cgltf_free_extensions(data, data->animations[i].extensions, data->animations[i].extensions_count); cgltf_free_extras(data, &data->animations[i].extras); @@ -2038,6 +2075,8 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->variants); + data->memory.free_func(data->memory.user_data, data->xmp_json_ld_packets); + cgltf_free_extensions(data, data->data_extensions, data->data_extensions_count); cgltf_free_extras(data, &data->extras); @@ -2677,6 +2716,21 @@ static int cgltf_skip_json(jsmntok_t const* tokens, int i) return i; } +static int cgltf_count_json_extension(jsmntok_t const* tokens, const int i, const uint8_t* json_chunk, const int extensions_size, const char* key) +{ + // first, need to get the count correctly. + int temp_i = i; + int ret = 0; + for (int j = 0; j < extensions_size; ++j) { + CGLTF_CHECK_KEY(tokens[temp_i]); + if (cgltf_json_strcmp(tokens + temp_i, json_chunk, key) == 0) { + ret += 1; + } + temp_i = cgltf_skip_json(tokens, temp_i + 1); + } + return ret; +} + static void cgltf_fill_float_array(float* out_array, int size, float value) { for (int j = 0; j < size; ++j) @@ -2875,6 +2929,14 @@ static int cgltf_parse_json_extras(cgltf_options* options, jsmntok_t const* toke return i; } +static int cgltf_parse_xmp_json_ld(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_xmp_json_ld* xmp_json_ld) +{ + i = cgltf_skip_json(tokens, i); // we do not care of the key 'packet' + xmp_json_ld->pos = cgltf_json_to_int(tokens + i, json_chunk); + i = cgltf_skip_json(tokens, i); + 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); @@ -3338,7 +3400,52 @@ static int cgltf_parse_json_mesh(cgltf_options* options, jsmntok_t const* tokens } 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); + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(out_mesh->extensions) + { + return CGLTF_ERROR_JSON; + } + + int extensions_size = tokens[i].size; + ++i; + out_mesh->extensions_count = 0; + + out_mesh->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, + (const char *)"KHR_xmp_json_ld"); + + int unprocessed_extensions_size = extensions_size - (int)out_mesh->xmp_json_ld_count; + if (unprocessed_extensions_size) { + out_mesh->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), + unprocessed_extensions_size); + if (!out_mesh->extensions) { + return CGLTF_ERROR_NOMEM; + } + } + if (out_mesh->xmp_json_ld_count) { + out_mesh->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), + out_mesh->xmp_json_ld_count); + } + out_mesh->xmp_json_ld_count = 0; + for (int j = 0; j < extensions_size; ++j) { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) + { + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_mesh->xmp_json_ld[out_mesh->xmp_json_ld_count++])); + } + else + { + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_mesh->extensions[out_mesh->extensions_count++])); + } + if (i < 0) + { + return i; + } + } + } else { @@ -4269,7 +4376,52 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token } 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); + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(out_image->extensions) + { + return CGLTF_ERROR_JSON; + } + + int extensions_size = tokens[i].size; + ++i; + out_image->extensions_count = 0; + + out_image->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, + (const char *)"KHR_xmp_json_ld"); + + int unprocessed_extensions_size = extensions_size - (int)out_image->xmp_json_ld_count; + if (unprocessed_extensions_size) { + out_image->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), + unprocessed_extensions_size); + if (!out_image->extensions) { + return CGLTF_ERROR_NOMEM; + } + } + if (out_image->xmp_json_ld_count) { + out_image->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), + out_image->xmp_json_ld_count); + } + out_image->xmp_json_ld_count = 0; + for (int j = 0; j < extensions_size; ++j) { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) + { + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_image->xmp_json_ld[out_image->xmp_json_ld_count++])); + } + else + { + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_image->extensions[out_image->extensions_count++])); + } + if (i < 0) + { + return i; + } + } + } else { @@ -4560,13 +4712,34 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to 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; + int to_process_extensions_size = + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_pbrSpecularGlossiness") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_unlit") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_clearcoat") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_ior") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_specular") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_transmission") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_volume") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_sheen") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_emissive_strength") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_iridescence") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_xmp_json_ld"); + + int unprocessed_extensions_size = extensions_size - to_process_extensions_size; + if (unprocessed_extensions_size) { + out_material->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), + unprocessed_extensions_size); + if (!out_material->extensions) { + return CGLTF_ERROR_NOMEM; + } + } - if (!out_material->extensions) - { - return CGLTF_ERROR_NOMEM; + out_material->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_xmp_json_ld"); + if (out_material->xmp_json_ld_count) { + out_material->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), + out_material->xmp_json_ld_count); } + out_material->xmp_json_ld_count = 0; for (int k = 0; k < extensions_size; ++k) { @@ -4627,6 +4800,12 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to out_material->has_anisotropy = 1; i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->anisotropy); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_xmp_json_ld") == 0) + { + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_material->xmp_json_ld[out_material->xmp_json_ld_count++])); + } else { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++])); @@ -5539,15 +5718,31 @@ static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens } int extensions_size = tokens[i].size; - out_node->extensions_count= 0; - out_node->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); + ++i; - if (!out_node->extensions) - { - return CGLTF_ERROR_NOMEM; + out_node->extensions_count= 0; + int to_process_extensions_size = + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size,(const char *)"KHR_lights_punctual") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size,(const char *)"EXT_mesh_gpu_instancing") + + cgltf_count_json_extension(tokens, i, json_chunk, extensions_size,(const char *)"KHR_xmp_json_ld"); + + int unprocessed_extensions_size = extensions_size - to_process_extensions_size; + if (unprocessed_extensions_size) { + out_node->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), + unprocessed_extensions_size); + if (!out_node->extensions) { + return CGLTF_ERROR_NOMEM; + } } - ++i; + out_node->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, + (const char *)"KHR_xmp_json_ld"); + + if (out_node->xmp_json_ld_count) { + out_node->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), + out_node->xmp_json_ld_count); + } + out_node->xmp_json_ld_count = 0; for (int k = 0; k < extensions_size; ++k) { @@ -5589,6 +5784,11 @@ static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens out_node->has_mesh_gpu_instancing = 1; i = cgltf_parse_json_mesh_gpu_instancing(options, tokens, i + 1, json_chunk, &out_node->mesh_gpu_instancing); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_xmp_json_ld") == 0) { + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_node->xmp_json_ld[out_node->xmp_json_ld_count++])); + } else { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_node->extensions[out_node->extensions_count++])); @@ -5668,7 +5868,51 @@ static int cgltf_parse_json_scene(cgltf_options* options, jsmntok_t const* token } 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); + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(out_scene->extensions) + { + return CGLTF_ERROR_JSON; + } + + int extensions_size = tokens[i].size; + ++i; + out_scene->extensions_count = 0; + + out_scene->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, + (const char *)"KHR_xmp_json_ld"); + + int unprocessed_extensions_size = extensions_size - (int)out_scene->xmp_json_ld_count; + if (unprocessed_extensions_size) { + out_scene->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), + unprocessed_extensions_size); + if (!out_scene->extensions) { + return CGLTF_ERROR_NOMEM; + } + } + if (out_scene->xmp_json_ld_count) { + out_scene->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), + out_scene->xmp_json_ld_count); + } + out_scene->xmp_json_ld_count = 0; + for (int j = 0; j < extensions_size; ++j) { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) + { + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_scene->xmp_json_ld[out_scene->xmp_json_ld_count++])); + } + else + { + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_scene->extensions[out_scene->extensions_count++])); + } + if (i < 0) + { + return i; + } + } } else { @@ -5912,7 +6156,51 @@ static int cgltf_parse_json_animation(cgltf_options* options, jsmntok_t const* t } 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); + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(out_animation->extensions) + { + return CGLTF_ERROR_JSON; + } + + int extensions_size = tokens[i].size; + ++i; + out_animation->extensions_count = 0; + + out_animation->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, + (const char *)"KHR_xmp_json_ld"); + + int unprocessed_extensions_size = extensions_size - (int)out_animation->xmp_json_ld_count; + if (unprocessed_extensions_size) { + out_animation->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), + unprocessed_extensions_size); + if (!out_animation->extensions) { + return CGLTF_ERROR_NOMEM; + } + } + if (out_animation->xmp_json_ld_count) { + out_animation->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), + out_animation->xmp_json_ld_count); + } + out_animation->xmp_json_ld_count = 0; + for (int j = 0; j < extensions_size; ++j) { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) + { + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_animation->xmp_json_ld[out_animation->xmp_json_ld_count++])); + } + else + { + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_animation->extensions[out_animation->extensions_count++])); + } + if (i < 0) + { + return i; + } + } } else { @@ -6032,7 +6320,51 @@ static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* token } 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); + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + if(out_asset->extensions) + { + return CGLTF_ERROR_JSON; + } + + int extensions_size = tokens[i].size; + ++i; + out_asset->extensions_count = 0; + + out_asset->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, + (const char *)"KHR_xmp_json_ld"); + + int unprocessed_extensions_size = extensions_size - (int)out_asset->xmp_json_ld_count; + if (unprocessed_extensions_size) { + out_asset->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), + unprocessed_extensions_size); + if (!out_asset->extensions) { + return CGLTF_ERROR_NOMEM; + } + } + if (out_asset->xmp_json_ld_count) { + out_asset->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), + out_asset->xmp_json_ld_count); + } + out_asset->xmp_json_ld_count = 0; + for (int j = 0; j < extensions_size; ++j) { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) + { + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_asset->xmp_json_ld[out_asset->xmp_json_ld_count++])); + } + else + { + i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_asset->extensions[out_asset->extensions_count++])); + } + if (i < 0) + { + return i; + } + } } else { @@ -6053,6 +6385,42 @@ static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* token return i; } +static int cgltf_parse_xmp_json_ld_packet(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_xmp_json_ld_packet* packet) { + size_t start = tokens[i].start; + size_t size = tokens[i].end - start; + packet->data = (char*)options->memory.alloc_func(options->memory.user_data, size + 1); + if (!packet->data) + { + return CGLTF_ERROR_NOMEM; + } + strncpy(packet->data, (const char*)json_chunk + start, size); + packet->data[size] = '\0'; + + i = cgltf_skip_json(tokens, i); + return i; +} + +static int cgltf_parse_xmp_json_ld_packets(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data) { + + i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_material_variant), + (void**)&out_data->xmp_json_ld_packets, &out_data->xmp_json_ld_packets_count); + + if (i < 0) + { + return i; + } + + for (cgltf_size j = 0; j < out_data->xmp_json_ld_packets_count; ++j) + { + i = cgltf_parse_xmp_json_ld_packet(options, tokens, i, json_chunk, &out_data->xmp_json_ld_packets[j]); + if (i < 0) + { + return i; + } + } + return i; +} + cgltf_size cgltf_num_components(cgltf_type type) { switch (type) { @@ -6267,6 +6635,29 @@ static int cgltf_parse_json_root(cgltf_options* options, jsmntok_t const* tokens } } } + else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) + { + ++i; + + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + + int data_size = tokens[i].size; + ++i; + + for (int m = 0; m < data_size; ++m) { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens + i, json_chunk, "packets") == 0) { + i = cgltf_parse_xmp_json_ld_packets(options, tokens, i + 1, json_chunk, out_data); + } else { + i = cgltf_skip_json(tokens, i + 1); + } + + if (i < 0) { + return i; + } + } + } else { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_data->data_extensions[out_data->data_extensions_count++])); From a5702f9a8ff04b0a86b1f77adc47802c7d5fc221 Mon Sep 17 00:00:00 2001 From: Todd Zhang Date: Fri, 8 Dec 2023 17:37:03 -0800 Subject: [PATCH 2/5] refactor to follow node method for the KHR_xmp_json_ld --- cgltf.h | 238 ++++++++++++-------------------------------------------- 1 file changed, 51 insertions(+), 187 deletions(-) diff --git a/cgltf.h b/cgltf.h index 82f28bf..9e2fca6 100644 --- a/cgltf.h +++ b/cgltf.h @@ -123,7 +123,7 @@ typedef enum cgltf_result cgltf_result_io_error, cgltf_result_out_of_memory, cgltf_result_legacy_gltf, - cgltf_result_max_enum + cgltf_result_max_enum } cgltf_result; typedef struct cgltf_memory_options @@ -179,7 +179,7 @@ typedef enum cgltf_component_type cgltf_component_type_r_16u, /* UNSIGNED_SHORT */ cgltf_component_type_r_32u, /* UNSIGNED_INT */ cgltf_component_type_r_32f, /* FLOAT */ - cgltf_component_type_max_enum + cgltf_component_type_max_enum } cgltf_component_type; typedef enum cgltf_type @@ -258,11 +258,6 @@ typedef struct cgltf_xmp_json_ld_packet char* data; } cgltf_xmp_json_ld_packet; -typedef struct cgltf_xmp_json_ld -{ - unsigned int pos; -} cgltf_xmp_json_ld; - typedef struct cgltf_extras { cgltf_size start_offset; /* this field is deprecated and will be removed in the future; use data instead */ cgltf_size end_offset; /* this field is deprecated and will be removed in the future; use data instead */ @@ -283,8 +278,7 @@ typedef struct cgltf_buffer void* data; /* loaded by cgltf_load_buffers */ cgltf_data_free_method data_free_method; cgltf_extras extras; - cgltf_size xmp_json_ld_count; - cgltf_xmp_json_ld *xmp_json_ld; + cgltf_xmp_json_ld_packet *xmp_json_ld; cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_buffer; @@ -378,9 +372,8 @@ typedef struct cgltf_image cgltf_buffer_view* buffer_view; char* mime_type; cgltf_extras extras; - cgltf_size xmp_json_ld_count; - cgltf_xmp_json_ld *xmp_json_ld; - cgltf_size extensions_count; + cgltf_xmp_json_ld_packet *xmp_json_ld; + cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_image; @@ -547,8 +540,7 @@ typedef struct cgltf_material cgltf_bool double_sided; cgltf_bool unlit; cgltf_extras extras; - cgltf_size xmp_json_ld_count; - cgltf_xmp_json_ld *xmp_json_ld; + cgltf_xmp_json_ld_packet *xmp_json_ld; cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_material; @@ -602,9 +594,8 @@ typedef struct cgltf_mesh { char** target_names; cgltf_size target_names_count; cgltf_extras extras; - cgltf_size xmp_json_ld_count; - cgltf_xmp_json_ld *xmp_json_ld; - cgltf_size extensions_count; + cgltf_xmp_json_ld_packet *xmp_json_ld; + cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_mesh; @@ -682,8 +673,7 @@ struct cgltf_node { cgltf_float scale[3]; cgltf_float matrix[16]; cgltf_extras extras; - cgltf_size xmp_json_ld_count; - cgltf_xmp_json_ld *xmp_json_ld; + cgltf_xmp_json_ld_packet *xmp_json_ld; cgltf_bool has_mesh_gpu_instancing; cgltf_mesh_gpu_instancing mesh_gpu_instancing; cgltf_size extensions_count; @@ -695,8 +685,7 @@ typedef struct cgltf_scene { cgltf_node** nodes; cgltf_size nodes_count; cgltf_extras extras; - cgltf_size xmp_json_ld_count; - cgltf_xmp_json_ld *xmp_json_ld; + cgltf_xmp_json_ld_packet *xmp_json_ld; cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_scene; @@ -726,8 +715,7 @@ typedef struct cgltf_animation { cgltf_animation_channel* channels; cgltf_size channels_count; cgltf_extras extras; - cgltf_size xmp_json_ld_count; - cgltf_xmp_json_ld *xmp_json_ld; + cgltf_xmp_json_ld_packet *xmp_json_ld; cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_animation; @@ -744,8 +732,7 @@ typedef struct cgltf_asset { char* version; char* min_version; cgltf_extras extras; - cgltf_size xmp_json_ld_count; - cgltf_xmp_json_ld *xmp_json_ld; + cgltf_xmp_json_ld_packet *xmp_json_ld; cgltf_size extensions_count; cgltf_extension* extensions; } cgltf_asset; @@ -888,6 +875,7 @@ cgltf_size cgltf_scene_index(const cgltf_data* data, const cgltf_scene* object); cgltf_size cgltf_animation_index(const cgltf_data* data, const cgltf_animation* object); cgltf_size cgltf_animation_sampler_index(const cgltf_animation* animation, const cgltf_animation_sampler* object); cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const cgltf_animation_channel* object); +cgltf_size cgltf_xmp_json_ld_packet_index(const cgltf_data* data, const cgltf_xmp_json_ld_packet* object); #ifdef __cplusplus } @@ -1816,7 +1804,6 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->asset.generator); data->memory.free_func(data->memory.user_data, data->asset.version); data->memory.free_func(data->memory.user_data, data->asset.min_version); - data->memory.free_func(data->memory.user_data, data->asset.xmp_json_ld); cgltf_free_extensions(data, data->asset.extensions, data->asset.extensions_count); cgltf_free_extras(data, &data->asset.extras); @@ -1863,7 +1850,6 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->meshes_count; ++i) { data->memory.free_func(data->memory.user_data, data->meshes[i].name); - data->memory.free_func(data->memory.user_data, data->meshes[i].xmp_json_ld); for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j) { @@ -1926,7 +1912,6 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->materials_count; ++i) { data->memory.free_func(data->memory.user_data, data->materials[i].name); - data->memory.free_func(data->memory.user_data, data->materials[i].xmp_json_ld); cgltf_free_extensions(data, data->materials[i].extensions, data->materials[i].extensions_count); cgltf_free_extras(data, &data->materials[i].extras); @@ -1939,8 +1924,6 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->images[i].name); data->memory.free_func(data->memory.user_data, data->images[i].uri); data->memory.free_func(data->memory.user_data, data->images[i].mime_type); - data->memory.free_func(data->memory.user_data, data->images[i].xmp_json_ld); - cgltf_free_extensions(data, data->images[i].extensions, data->images[i].extensions_count); cgltf_free_extras(data, &data->images[i].extras); @@ -2012,7 +1995,6 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->nodes[i].name); data->memory.free_func(data->memory.user_data, data->nodes[i].children); data->memory.free_func(data->memory.user_data, data->nodes[i].weights); - data->memory.free_func(data->memory.user_data, data->nodes[i].xmp_json_ld); if (data->nodes[i].has_mesh_gpu_instancing) { @@ -2034,7 +2016,6 @@ void cgltf_free(cgltf_data* data) { data->memory.free_func(data->memory.user_data, data->scenes[i].name); data->memory.free_func(data->memory.user_data, data->scenes[i].nodes); - data->memory.free_func(data->memory.user_data, data->scenes[i].xmp_json_ld); cgltf_free_extensions(data, data->scenes[i].extensions, data->scenes[i].extensions_count); cgltf_free_extras(data, &data->scenes[i].extras); @@ -2058,7 +2039,6 @@ void cgltf_free(cgltf_data* data) cgltf_free_extras(data, &data->animations[i].channels[j].extras); } data->memory.free_func(data->memory.user_data, data->animations[i].channels); - data->memory.free_func(data->memory.user_data, data->animations[i].xmp_json_ld); cgltf_free_extensions(data, data->animations[i].extensions, data->animations[i].extensions_count); cgltf_free_extras(data, &data->animations[i].extras); @@ -2630,6 +2610,12 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u return index_count; } +cgltf_size cgltf_xmp_json_ld_packet_index(const cgltf_data* data, const cgltf_xmp_json_ld_packet* object) +{ + assert(object && (cgltf_size)(object - data->xmp_json_ld_packets) < data->xmp_json_ld_packets_count); + return (cgltf_size)(object - data->xmp_json_ld_packets); +} + #define CGLTF_ERROR_JSON -1 #define CGLTF_ERROR_NOMEM -2 #define CGLTF_ERROR_LEGACY -3 @@ -2716,21 +2702,6 @@ static int cgltf_skip_json(jsmntok_t const* tokens, int i) return i; } -static int cgltf_count_json_extension(jsmntok_t const* tokens, const int i, const uint8_t* json_chunk, const int extensions_size, const char* key) -{ - // first, need to get the count correctly. - int temp_i = i; - int ret = 0; - for (int j = 0; j < extensions_size; ++j) { - CGLTF_CHECK_KEY(tokens[temp_i]); - if (cgltf_json_strcmp(tokens + temp_i, json_chunk, key) == 0) { - ret += 1; - } - temp_i = cgltf_skip_json(tokens, temp_i + 1); - } - return ret; -} - static void cgltf_fill_float_array(float* out_array, int size, float value) { for (int j = 0; j < size; ++j) @@ -2929,10 +2900,11 @@ static int cgltf_parse_json_extras(cgltf_options* options, jsmntok_t const* toke return i; } -static int cgltf_parse_xmp_json_ld(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_xmp_json_ld* xmp_json_ld) +static int cgltf_parse_xmp_json_lds(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_xmp_json_ld_packet** xmp_json_ld) { i = cgltf_skip_json(tokens, i); // we do not care of the key 'packet' - xmp_json_ld->pos = cgltf_json_to_int(tokens + i, json_chunk); + int index = cgltf_json_to_int(tokens + i, json_chunk); + *xmp_json_ld = CGLTF_PTRINDEX(cgltf_xmp_json_ld_packet, index); i = cgltf_skip_json(tokens, i); return i; } @@ -3411,22 +3383,6 @@ static int cgltf_parse_json_mesh(cgltf_options* options, jsmntok_t const* tokens ++i; out_mesh->extensions_count = 0; - out_mesh->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, - (const char *)"KHR_xmp_json_ld"); - - int unprocessed_extensions_size = extensions_size - (int)out_mesh->xmp_json_ld_count; - if (unprocessed_extensions_size) { - out_mesh->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), - unprocessed_extensions_size); - if (!out_mesh->extensions) { - return CGLTF_ERROR_NOMEM; - } - } - if (out_mesh->xmp_json_ld_count) { - out_mesh->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), - out_mesh->xmp_json_ld_count); - } - out_mesh->xmp_json_ld_count = 0; for (int j = 0; j < extensions_size; ++j) { CGLTF_CHECK_KEY(tokens[i]); @@ -3434,7 +3390,7 @@ static int cgltf_parse_json_mesh(cgltf_options* options, jsmntok_t const* tokens { ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); - i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_mesh->xmp_json_ld[out_mesh->xmp_json_ld_count++])); + i = cgltf_parse_xmp_json_lds(tokens, i + 1, json_chunk, &(out_mesh->xmp_json_ld)); } else { @@ -4385,24 +4341,7 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token int extensions_size = tokens[i].size; ++i; - out_image->extensions_count = 0; - - out_image->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, - (const char *)"KHR_xmp_json_ld"); - int unprocessed_extensions_size = extensions_size - (int)out_image->xmp_json_ld_count; - if (unprocessed_extensions_size) { - out_image->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), - unprocessed_extensions_size); - if (!out_image->extensions) { - return CGLTF_ERROR_NOMEM; - } - } - if (out_image->xmp_json_ld_count) { - out_image->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), - out_image->xmp_json_ld_count); - } - out_image->xmp_json_ld_count = 0; for (int j = 0; j < extensions_size; ++j) { CGLTF_CHECK_KEY(tokens[i]); @@ -4410,7 +4349,7 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token { ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); - i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_image->xmp_json_ld[out_image->xmp_json_ld_count++])); + i = cgltf_parse_xmp_json_lds(tokens, i + 1, json_chunk, &(out_image->xmp_json_ld)); } else { @@ -4712,34 +4651,13 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to int extensions_size = tokens[i].size; ++i; - int to_process_extensions_size = - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_pbrSpecularGlossiness") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_unlit") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_clearcoat") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_ior") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_specular") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_transmission") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_volume") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_sheen") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_emissive_strength") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_materials_iridescence") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_xmp_json_ld"); - - int unprocessed_extensions_size = extensions_size - to_process_extensions_size; - if (unprocessed_extensions_size) { - out_material->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), - unprocessed_extensions_size); - if (!out_material->extensions) { - return CGLTF_ERROR_NOMEM; - } - } + out_material->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); + out_material->extensions_count= 0; - out_material->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, (const char *)"KHR_xmp_json_ld"); - if (out_material->xmp_json_ld_count) { - out_material->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), - out_material->xmp_json_ld_count); + if (!out_material->extensions) + { + return CGLTF_ERROR_NOMEM; } - out_material->xmp_json_ld_count = 0; for (int k = 0; k < extensions_size; ++k) { @@ -4804,7 +4722,7 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to { ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); - i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_material->xmp_json_ld[out_material->xmp_json_ld_count++])); + i = cgltf_parse_xmp_json_lds(tokens, i + 1, json_chunk, &(out_material->xmp_json_ld)); } else { @@ -5718,31 +5636,15 @@ static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens } int extensions_size = tokens[i].size; - ++i; - out_node->extensions_count= 0; - int to_process_extensions_size = - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size,(const char *)"KHR_lights_punctual") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size,(const char *)"EXT_mesh_gpu_instancing") + - cgltf_count_json_extension(tokens, i, json_chunk, extensions_size,(const char *)"KHR_xmp_json_ld"); - - int unprocessed_extensions_size = extensions_size - to_process_extensions_size; - if (unprocessed_extensions_size) { - out_node->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), - unprocessed_extensions_size); - if (!out_node->extensions) { - return CGLTF_ERROR_NOMEM; - } - } + out_node->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); - out_node->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, - (const char *)"KHR_xmp_json_ld"); - - if (out_node->xmp_json_ld_count) { - out_node->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), - out_node->xmp_json_ld_count); + if (!out_node->extensions) + { + return CGLTF_ERROR_NOMEM; } - out_node->xmp_json_ld_count = 0; + + ++i; for (int k = 0; k < extensions_size; ++k) { @@ -5787,7 +5689,7 @@ static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_xmp_json_ld") == 0) { ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); - i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_node->xmp_json_ld[out_node->xmp_json_ld_count++])); + i = cgltf_parse_xmp_json_lds(tokens, i + 1, json_chunk, &(out_node->xmp_json_ld)); } else { @@ -5877,24 +5779,7 @@ static int cgltf_parse_json_scene(cgltf_options* options, jsmntok_t const* token int extensions_size = tokens[i].size; ++i; - out_scene->extensions_count = 0; - - out_scene->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, - (const char *)"KHR_xmp_json_ld"); - int unprocessed_extensions_size = extensions_size - (int)out_scene->xmp_json_ld_count; - if (unprocessed_extensions_size) { - out_scene->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), - unprocessed_extensions_size); - if (!out_scene->extensions) { - return CGLTF_ERROR_NOMEM; - } - } - if (out_scene->xmp_json_ld_count) { - out_scene->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), - out_scene->xmp_json_ld_count); - } - out_scene->xmp_json_ld_count = 0; for (int j = 0; j < extensions_size; ++j) { CGLTF_CHECK_KEY(tokens[i]); @@ -5902,7 +5787,7 @@ static int cgltf_parse_json_scene(cgltf_options* options, jsmntok_t const* token { ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); - i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_scene->xmp_json_ld[out_scene->xmp_json_ld_count++])); + i = cgltf_parse_xmp_json_lds(tokens, i + 1, json_chunk, &(out_scene->xmp_json_ld)); } else { @@ -6167,22 +6052,6 @@ static int cgltf_parse_json_animation(cgltf_options* options, jsmntok_t const* t ++i; out_animation->extensions_count = 0; - out_animation->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, - (const char *)"KHR_xmp_json_ld"); - - int unprocessed_extensions_size = extensions_size - (int)out_animation->xmp_json_ld_count; - if (unprocessed_extensions_size) { - out_animation->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), - unprocessed_extensions_size); - if (!out_animation->extensions) { - return CGLTF_ERROR_NOMEM; - } - } - if (out_animation->xmp_json_ld_count) { - out_animation->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), - out_animation->xmp_json_ld_count); - } - out_animation->xmp_json_ld_count = 0; for (int j = 0; j < extensions_size; ++j) { CGLTF_CHECK_KEY(tokens[i]); @@ -6190,7 +6059,7 @@ static int cgltf_parse_json_animation(cgltf_options* options, jsmntok_t const* t { ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); - i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_animation->xmp_json_ld[out_animation->xmp_json_ld_count++])); + i = cgltf_parse_xmp_json_lds(tokens, i + 1, json_chunk, &(out_animation->xmp_json_ld)); } else { @@ -6331,22 +6200,6 @@ static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* token ++i; out_asset->extensions_count = 0; - out_asset->xmp_json_ld_count = cgltf_count_json_extension(tokens, i, json_chunk, extensions_size, - (const char *)"KHR_xmp_json_ld"); - - int unprocessed_extensions_size = extensions_size - (int)out_asset->xmp_json_ld_count; - if (unprocessed_extensions_size) { - out_asset->extensions = (cgltf_extension *) cgltf_calloc(options, sizeof(cgltf_extension), - unprocessed_extensions_size); - if (!out_asset->extensions) { - return CGLTF_ERROR_NOMEM; - } - } - if (out_asset->xmp_json_ld_count) { - out_asset->xmp_json_ld = (cgltf_xmp_json_ld *) cgltf_calloc(options, sizeof(cgltf_xmp_json_ld), - out_asset->xmp_json_ld_count); - } - out_asset->xmp_json_ld_count = 0; for (int j = 0; j < extensions_size; ++j) { CGLTF_CHECK_KEY(tokens[i]); @@ -6354,7 +6207,7 @@ static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* token { ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); - i = cgltf_parse_xmp_json_ld(tokens, i + 1, json_chunk, &(out_asset->xmp_json_ld[out_asset->xmp_json_ld_count++])); + i = cgltf_parse_xmp_json_lds(tokens, i + 1, json_chunk, &(out_asset->xmp_json_ld)); } else { @@ -6806,6 +6659,7 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].mappings[k].material, data->materials, data->materials_count); } } + CGLTF_PTRFIXUP(data->meshes[i].xmp_json_ld, data->xmp_json_ld_packets, data->xmp_json_ld_packets_count); } for (cgltf_size i = 0; i < data->accessors_count; ++i) @@ -6839,6 +6693,7 @@ static int cgltf_fixup_pointers(cgltf_data* data) for (cgltf_size i = 0; i < data->images_count; ++i) { CGLTF_PTRFIXUP(data->images[i].buffer_view, data->buffer_views, data->buffer_views_count); + CGLTF_PTRFIXUP(data->images[i].xmp_json_ld, data->xmp_json_ld_packets, data->xmp_json_ld_packets_count); } for (cgltf_size i = 0; i < data->materials_count; ++i) @@ -6871,6 +6726,7 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_thickness_texture.texture, data->textures, data->textures_count); CGLTF_PTRFIXUP(data->materials[i].anisotropy.anisotropy_texture.texture, data->textures, data->textures_count); + CGLTF_PTRFIXUP(data->materials[i].xmp_json_ld, data->xmp_json_ld_packets, data->xmp_json_ld_packets_count); } for (cgltf_size i = 0; i < data->buffer_views_count; ++i) @@ -6920,6 +6776,8 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP_REQ(data->nodes[i].mesh_gpu_instancing.attributes[m].data, data->accessors, data->accessors_count); } } + + CGLTF_PTRFIXUP(data->nodes[i].xmp_json_ld, data->xmp_json_ld_packets, data->xmp_json_ld_packets_count); } for (cgltf_size i = 0; i < data->scenes_count; ++i) @@ -6933,6 +6791,8 @@ static int cgltf_fixup_pointers(cgltf_data* data) return CGLTF_ERROR_JSON; } } + + CGLTF_PTRFIXUP(data->scenes[i].xmp_json_ld, data->xmp_json_ld_packets, data->xmp_json_ld_packets_count); } CGLTF_PTRFIXUP(data->scene, data->scenes, data->scenes_count); @@ -6950,8 +6810,12 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP_REQ(data->animations[i].channels[j].sampler, data->animations[i].samplers, data->animations[i].samplers_count); CGLTF_PTRFIXUP(data->animations[i].channels[j].target_node, data->nodes, data->nodes_count); } + + CGLTF_PTRFIXUP(data->animations[i].xmp_json_ld, data->xmp_json_ld_packets, data->xmp_json_ld_packets_count); } + CGLTF_PTRFIXUP(data->asset.xmp_json_ld, data->xmp_json_ld_packets, data->xmp_json_ld_packets_count); + return 0; } From 21be863b9b3833b1f800bedc6bdf263c251697be Mon Sep 17 00:00:00 2001 From: Todd Zhang Date: Tue, 12 Dec 2023 14:30:06 -0800 Subject: [PATCH 3/5] change based on cr feedback. --- cgltf.h | 54 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/cgltf.h b/cgltf.h index 9e2fca6..89f5bde 100644 --- a/cgltf.h +++ b/cgltf.h @@ -2055,7 +2055,11 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->variants); - data->memory.free_func(data->memory.user_data, data->xmp_json_ld_packets); + for (cgltf_size i = 0; i < data->xmp_json_ld_packets_count; ++i) + { + data->memory.free_func(data->memory.user_data, data->xmp_json_ld_packets[i].data); + } + data->memory.free_func(data->memory.user_data, data->xmp_json_ld_packets); cgltf_free_extensions(data, data->data_extensions, data->data_extensions_count); cgltf_free_extras(data, &data->extras); @@ -3381,9 +3385,11 @@ static int cgltf_parse_json_mesh(cgltf_options* options, jsmntok_t const* tokens int extensions_size = tokens[i].size; ++i; - out_mesh->extensions_count = 0; + out_mesh->extensions_count = 0; + out_mesh->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); - for (int j = 0; j < extensions_size; ++j) { + for (int j = 0; j < extensions_size; ++j) + { CGLTF_CHECK_KEY(tokens[i]); if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) @@ -4342,7 +4348,8 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token int extensions_size = tokens[i].size; ++i; - for (int j = 0; j < extensions_size; ++j) { + for (int j = 0; j < extensions_size; ++j) + { CGLTF_CHECK_KEY(tokens[i]); if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) @@ -4488,8 +4495,8 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok int extensions_size = tokens[i].size; ++i; + out_texture->extensions_count = 0; out_texture->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); - out_texture->extensions_count = 0; if (!out_texture->extensions) { @@ -5686,7 +5693,8 @@ static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens out_node->has_mesh_gpu_instancing = 1; i = cgltf_parse_json_mesh_gpu_instancing(options, tokens, i + 1, json_chunk, &out_node->mesh_gpu_instancing); } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_xmp_json_ld") == 0) { + else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_xmp_json_ld") == 0) + { ++i; CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); i = cgltf_parse_xmp_json_lds(tokens, i + 1, json_chunk, &(out_node->xmp_json_ld)); @@ -5780,7 +5788,8 @@ static int cgltf_parse_json_scene(cgltf_options* options, jsmntok_t const* token int extensions_size = tokens[i].size; ++i; - for (int j = 0; j < extensions_size; ++j) { + for (int j = 0; j < extensions_size; ++j) + { CGLTF_CHECK_KEY(tokens[i]); if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) @@ -6050,9 +6059,11 @@ static int cgltf_parse_json_animation(cgltf_options* options, jsmntok_t const* t int extensions_size = tokens[i].size; ++i; - out_animation->extensions_count = 0; + out_animation->extensions_count = 0; + out_animation->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); - for (int j = 0; j < extensions_size; ++j) { + for (int j = 0; j < extensions_size; ++j) + { CGLTF_CHECK_KEY(tokens[i]); if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) @@ -6199,8 +6210,10 @@ static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* token int extensions_size = tokens[i].size; ++i; out_asset->extensions_count = 0; + out_asset->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); - for (int j = 0; j < extensions_size; ++j) { + for (int j = 0; j < extensions_size; ++j) + { CGLTF_CHECK_KEY(tokens[i]); if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_xmp_json_ld") == 0) @@ -6238,7 +6251,8 @@ static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* token return i; } -static int cgltf_parse_xmp_json_ld_packet(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_xmp_json_ld_packet* packet) { +static int cgltf_parse_xmp_json_ld_packet(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_xmp_json_ld_packet* packet) +{ size_t start = tokens[i].start; size_t size = tokens[i].end - start; packet->data = (char*)options->memory.alloc_func(options->memory.user_data, size + 1); @@ -6253,8 +6267,8 @@ static int cgltf_parse_xmp_json_ld_packet(cgltf_options* options, jsmntok_t cons return i; } -static int cgltf_parse_xmp_json_ld_packets(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data) { - +static int cgltf_parse_xmp_json_ld_packets(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data) +{ i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_material_variant), (void**)&out_data->xmp_json_ld_packets, &out_data->xmp_json_ld_packets_count); @@ -6497,16 +6511,20 @@ static int cgltf_parse_json_root(cgltf_options* options, jsmntok_t const* tokens int data_size = tokens[i].size; ++i; - for (int m = 0; m < data_size; ++m) { + for (int m = 0; m < data_size; ++m) + { CGLTF_CHECK_KEY(tokens[i]); - if (cgltf_json_strcmp(tokens + i, json_chunk, "packets") == 0) { + if (cgltf_json_strcmp(tokens + i, json_chunk, "packets") == 0) + { i = cgltf_parse_xmp_json_ld_packets(options, tokens, i + 1, json_chunk, out_data); - } else { + } + else + { i = cgltf_skip_json(tokens, i + 1); } - - if (i < 0) { + if (i < 0) + { return i; } } From 6bc422e6f426eb15923026e52be9b76d58f0912d Mon Sep 17 00:00:00 2001 From: Todd Zhang Date: Mon, 18 Dec 2023 15:01:37 -0800 Subject: [PATCH 4/5] enable gltf write to support the extensions. --- cgltf_write.h | 152 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 6 deletions(-) diff --git a/cgltf_write.h b/cgltf_write.h index 7f9ea69..34988e0 100644 --- a/cgltf_write.h +++ b/cgltf_write.h @@ -86,6 +86,7 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si #define CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING (1 << 14) #define CGLTF_EXTENSION_FLAG_MATERIALS_IRIDESCENCE (1 << 15) #define CGLTF_EXTENSION_FLAG_MATERIALS_ANISOTROPY (1 << 16) +#define CGLTF_EXTENSION_FLAG_XMP_JSON_LD (1 << 17) typedef struct { char* buffer; @@ -447,7 +448,26 @@ static void cgltf_write_asset(cgltf_write_context* context, const cgltf_asset* a cgltf_write_strprop(context, "generator", asset->generator); cgltf_write_strprop(context, "version", asset->version); cgltf_write_strprop(context, "min_version", asset->min_version); - cgltf_write_extras(context, &asset->extras); + + bool has_extension = (asset->xmp_json_ld != nullptr); + + if(has_extension) + { + cgltf_write_line(context, "\"extensions\": {"); + } + + if (asset->xmp_json_ld) + { + cgltf_write_line(context, "\"KHR_xmp_json_ld\": {"); + CGLTF_WRITE_IDXPROP("packet", asset->xmp_json_ld, context->data->xmp_json_ld_packets); + cgltf_write_line(context, "}"); + } + + if (has_extension) + cgltf_write_line(context, "}"); + + + cgltf_write_extras(context, &asset->extras); cgltf_write_line(context, "}"); } @@ -550,6 +570,23 @@ static void cgltf_write_mesh(cgltf_write_context* context, const cgltf_mesh* mes cgltf_write_floatarrayprop(context, "weights", mesh->weights, mesh->weights_count); } + bool has_extension = (mesh->xmp_json_ld != nullptr); + if (has_extension) + { + cgltf_write_line(context, "\"extensions\": {"); + } + + if(mesh->xmp_json_ld) { + cgltf_write_line(context, "\"KHR_xmp_json_ld\": {"); + CGLTF_WRITE_IDXPROP("packet", mesh->xmp_json_ld, context->data->xmp_json_ld_packets); + cgltf_write_line(context, "}"); + } + + if (has_extension) + { + cgltf_write_line(context, "}"); + } + cgltf_write_extras(context, &mesh->extras); cgltf_write_line(context, "}"); } @@ -644,6 +681,11 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater context->extension_flags |= CGLTF_EXTENSION_FLAG_MATERIALS_ANISOTROPY; } + if (material->xmp_json_ld) + { + context->extension_flags |= CGLTF_EXTENSION_FLAG_XMP_JSON_LD; + } + if (material->has_pbr_metallic_roughness) { const cgltf_pbr_metallic_roughness* params = &material->pbr_metallic_roughness; @@ -659,7 +701,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater cgltf_write_line(context, "}"); } - if (material->unlit || material->has_pbr_specular_glossiness || material->has_clearcoat || material->has_ior || material->has_specular || material->has_transmission || material->has_sheen || material->has_volume || material->has_emissive_strength || material->has_iridescence || material->has_anisotropy) + if (material->unlit || material->has_pbr_specular_glossiness || material->has_clearcoat || material->has_ior || material->has_specular || material->has_transmission || material->has_sheen || material->has_volume || material->has_emissive_strength || material->has_iridescence || material->has_anisotropy || material->xmp_json_ld) { cgltf_write_line(context, "\"extensions\": {"); if (material->has_clearcoat) @@ -779,6 +821,12 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater CGLTF_WRITE_TEXTURE_INFO("anisotropyTexture", params->anisotropy_texture); cgltf_write_line(context, "}"); } + if (material->xmp_json_ld) + { + cgltf_write_line(context, "\"KHR_xmp_json_ld\": {"); + CGLTF_WRITE_IDXPROP("packet", material->xmp_json_ld, context->data->xmp_json_ld_packets); + cgltf_write_line(context, "}"); + } cgltf_write_line(context, "}"); } @@ -801,7 +849,25 @@ static void cgltf_write_image(cgltf_write_context* context, const cgltf_image* i cgltf_write_strprop(context, "uri", image->uri); CGLTF_WRITE_IDXPROP("bufferView", image->buffer_view, context->data->buffer_views); cgltf_write_strprop(context, "mimeType", image->mime_type); - cgltf_write_extras(context, &image->extras); + + bool has_extension = (image->xmp_json_ld != nullptr); + + if(has_extension) + { + cgltf_write_line(context, "\"extensions\": {"); + } + + if (image->xmp_json_ld) + { + cgltf_write_line(context, "\"KHR_xmp_json_ld\": {"); + CGLTF_WRITE_IDXPROP("packet", image->xmp_json_ld, context->data->xmp_json_ld_packets); + cgltf_write_line(context, "}"); + } + + if (has_extension) + cgltf_write_line(context, "}"); + + cgltf_write_extras(context, &image->extras); cgltf_write_line(context, "}"); } @@ -927,7 +993,25 @@ static void cgltf_write_animation(cgltf_write_context* context, const cgltf_anim } cgltf_write_line(context, "]"); } - cgltf_write_extras(context, &animation->extras); + + bool has_extension = (animation->xmp_json_ld != nullptr); + + if(has_extension) + { + cgltf_write_line(context, "\"extensions\": {"); + } + + if (animation->xmp_json_ld) + { + cgltf_write_line(context, "\"KHR_xmp_json_ld\": {"); + CGLTF_WRITE_IDXPROP("packet", animation->xmp_json_ld, context->data->xmp_json_ld_packets); + cgltf_write_line(context, "}"); + } + + if (has_extension) + cgltf_write_line(context, "}"); + + cgltf_write_extras(context, &animation->extras); cgltf_write_line(context, "}"); } @@ -970,7 +1054,7 @@ static void cgltf_write_node(cgltf_write_context* context, const cgltf_node* nod CGLTF_WRITE_IDXPROP("skin", node->skin, context->data->skins); } - bool has_extension = node->light || (node->has_mesh_gpu_instancing && node->mesh_gpu_instancing.attributes_count > 0); + bool has_extension = node->light || (node->has_mesh_gpu_instancing && node->mesh_gpu_instancing.attributes_count > 0) || node->xmp_json_ld; if(has_extension) cgltf_write_line(context, "\"extensions\": {"); @@ -1002,6 +1086,13 @@ static void cgltf_write_node(cgltf_write_context* context, const cgltf_node* nod cgltf_write_line(context, "}"); } + if (node->xmp_json_ld) + { + cgltf_write_line(context, "\"KHR_xmp_json_ld\": {"); + CGLTF_WRITE_IDXPROP("packet", node->xmp_json_ld, context->data->xmp_json_ld_packets); + cgltf_write_line(context, "}"); + } + if (has_extension) cgltf_write_line(context, "}"); @@ -1024,6 +1115,24 @@ static void cgltf_write_scene(cgltf_write_context* context, const cgltf_scene* s cgltf_write_line(context, "{"); cgltf_write_strprop(context, "name", scene->name); CGLTF_WRITE_IDXARRPROP("nodes", scene->nodes_count, scene->nodes, context->data->nodes); + + bool has_extension = (scene->xmp_json_ld != nullptr); + + if(has_extension) + { + cgltf_write_line(context, "\"extensions\": {"); + } + + if (scene->xmp_json_ld) + { + cgltf_write_line(context, "\"KHR_xmp_json_ld\": {"); + CGLTF_WRITE_IDXPROP("packet", scene->xmp_json_ld, context->data->xmp_json_ld_packets); + cgltf_write_line(context, "}"); + } + + if (has_extension) + cgltf_write_line(context, "}"); + cgltf_write_extras(context, &scene->extras); cgltf_write_line(context, "}"); } @@ -1145,6 +1254,20 @@ static void cgltf_write_variant(cgltf_write_context* context, const cgltf_materi cgltf_write_line(context, "}"); } +static void cgltf_write_xmp_json_ld(cgltf_write_context* context, const cgltf_xmp_json_ld_packet* xmp_json_ld_packet) +{ + if (xmp_json_ld_packet == nullptr) + { + return; + } + + context->extension_flags |= CGLTF_EXTENSION_FLAG_XMP_JSON_LD; + + cgltf_write_indent(context); + CGLTF_SPRINTF("%s", xmp_json_ld_packet->data); + context->needs_comma = 1; +} + static void cgltf_write_glb(FILE* file, const void* json_buf, const cgltf_size json_size, const void* bin_buf, const cgltf_size bin_size) { char header[GlbHeaderSize]; @@ -1264,6 +1387,9 @@ static void cgltf_write_extensions(cgltf_write_context* context, uint32_t extens if (extension_flags & CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING) { cgltf_write_stritem(context, "EXT_mesh_gpu_instancing"); } + if (extension_flags & CGLTF_EXTENSION_FLAG_XMP_JSON_LD) { + cgltf_write_stritem(context, "KHR_xmp_json_ld"); + } } cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size size, const cgltf_data* data) @@ -1420,7 +1546,9 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si cgltf_write_line(context, "]"); } - if (data->lights_count > 0 || data->variants_count > 0) + if (data->lights_count > 0 || + data->variants_count > 0 || + data->xmp_json_ld_packets_count > 0) { cgltf_write_line(context, "\"extensions\": {"); @@ -1448,6 +1576,18 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si cgltf_write_line(context, "}"); } + if (data->xmp_json_ld_packets_count) + { + cgltf_write_line(context, "\"KHR_xmp_json_ld\": {"); + cgltf_write_line(context, "\"packets\": ["); + for (cgltf_size i = 0; i < data->xmp_json_ld_packets_count; ++i) + { + cgltf_write_xmp_json_ld(context, data->xmp_json_ld_packets + i); + } + cgltf_write_line(context, "]"); + cgltf_write_line(context, "}"); + } + cgltf_write_line(context, "}"); } From c40c5e400e1495fb17e1dfbf9ca3092e0488b4a8 Mon Sep 17 00:00:00 2001 From: Todd Zhang Date: Fri, 8 Mar 2024 11:10:22 -0800 Subject: [PATCH 5/5] add missing constructor for scene/image extenions. --- cgltf.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cgltf.h b/cgltf.h index 89f5bde..a8fc780 100644 --- a/cgltf.h +++ b/cgltf.h @@ -4347,6 +4347,9 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token int extensions_size = tokens[i].size; ++i; + out_image->extensions_count = 0; + out_image->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); + for (int j = 0; j < extensions_size; ++j) { @@ -5787,6 +5790,8 @@ static int cgltf_parse_json_scene(cgltf_options* options, jsmntok_t const* token int extensions_size = tokens[i].size; ++i; + out_scene->extensions_count = 0; + out_scene->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); for (int j = 0; j < extensions_size; ++j) {