diff --git a/third_party/cgltf/cgltf.h b/third_party/cgltf/cgltf.h index a534cefb4f..95b56ceda5 100644 --- a/third_party/cgltf/cgltf.h +++ b/third_party/cgltf/cgltf.h @@ -80,9 +80,13 @@ * `cgltf_accessor_read_index` is similar to its floating-point counterpart, but it returns size_t * and only works with single-component data types. * - * `cgltf_copy_extras_json` allows users to retrieve the "extras" data that can be attached to many - * glTF objects (which can be arbitrary JSON data). This is a legacy function, consider using - * cgltf_extras::data directly instead. You can parse this data using your own JSON parser + * `cgltf_result cgltf_copy_extras_json(const cgltf_data*, const cgltf_extras*, + * char* dest, cgltf_size* dest_size)` allows users to retrieve the "extras" data that + * can be attached to many glTF objects (which can be arbitrary JSON data). The + * `cgltf_extras` struct stores the offsets of the start and end of the extras JSON data + * as it appears in the complete glTF JSON data. This function copies the extras data + * into the provided buffer. If `dest` is NULL, the length of the data is written into + * `dest_size`. You can then parse this data using your own JSON parser * or, if you've included the cgltf implementation using the integrated JSMN JSON parser. */ #ifndef CGLTF_H_INCLUDED__ @@ -252,10 +256,8 @@ typedef enum cgltf_data_free_method { } cgltf_data_free_method; 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 */ - - char* data; + cgltf_size start_offset; + cgltf_size end_offset; } cgltf_extras; typedef struct cgltf_extension { @@ -430,6 +432,8 @@ typedef struct cgltf_pbr_metallic_roughness cgltf_float base_color_factor[4]; cgltf_float metallic_factor; cgltf_float roughness_factor; + + cgltf_extras extras; } cgltf_pbr_metallic_roughness; typedef struct cgltf_pbr_specular_glossiness @@ -837,7 +841,6 @@ cgltf_size cgltf_num_components(cgltf_type type); cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count); -/* this function is deprecated and will be removed in the future; use cgltf_extras::data instead */ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* extras, char* dest, cgltf_size* dest_size); #ifdef __cplusplus @@ -921,15 +924,12 @@ static int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, jsmntok_t */ -#ifndef CGLTF_CONSTS static const cgltf_size GlbHeaderSize = 12; static const cgltf_size GlbChunkHeaderSize = 8; static const uint32_t GlbVersion = 2; static const uint32_t GlbMagic = 0x46546C67; static const uint32_t GlbMagicJsonChunk = 0x4E4F534A; static const uint32_t GlbMagicBinChunk = 0x004E4942; -#define CGLTF_CONSTS -#endif #ifndef CGLTF_MALLOC #define CGLTF_MALLOC(size) malloc(size) @@ -1745,12 +1745,7 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* return cgltf_result_success; } -static void cgltf_free_extras(cgltf_data* data, cgltf_extras* extras) -{ - data->memory.free_func(data->memory.user_data, extras->data); -} - -static void cgltf_free_extensions(cgltf_data* data, cgltf_extension* extensions, cgltf_size extensions_count) +void cgltf_free_extensions(cgltf_data* data, cgltf_extension* extensions, cgltf_size extensions_count) { for (cgltf_size i = 0; i < extensions_count; ++i) { @@ -1760,12 +1755,6 @@ static void cgltf_free_extensions(cgltf_data* data, cgltf_extension* extensions, data->memory.free_func(data->memory.user_data, extensions); } -static void cgltf_free_texture_view(cgltf_data* data, cgltf_texture_view* view) -{ - cgltf_free_extensions(data, view->extensions, view->extensions_count); - cgltf_free_extras(data, &view->extras); -} - void cgltf_free(cgltf_data* data) { if (!data) @@ -1781,7 +1770,6 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->asset.min_version); cgltf_free_extensions(data, data->asset.extensions, data->asset.extensions_count); - cgltf_free_extras(data, &data->asset.extras); for (cgltf_size i = 0; i < data->accessors_count; ++i) { @@ -1792,12 +1780,8 @@ void cgltf_free(cgltf_data* data) 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_extras(data, &data->accessors[i].sparse.extras); - cgltf_free_extras(data, &data->accessors[i].sparse.indices_extras); - cgltf_free_extras(data, &data->accessors[i].sparse.values_extras); } cgltf_free_extensions(data, data->accessors[i].extensions, data->accessors[i].extensions_count); - cgltf_free_extras(data, &data->accessors[i].extras); } data->memory.free_func(data->memory.user_data, data->accessors); @@ -1807,7 +1791,6 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->buffer_views[i].data); cgltf_free_extensions(data, data->buffer_views[i].extensions, data->buffer_views[i].extensions_count); - cgltf_free_extras(data, &data->buffer_views[i].extras); } data->memory.free_func(data->memory.user_data, data->buffer_views); @@ -1827,8 +1810,8 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->buffers[i].uri); cgltf_free_extensions(data, data->buffers[i].extensions, data->buffers[i].extensions_count); - cgltf_free_extras(data, &data->buffers[i].extras); } + data->memory.free_func(data->memory.user_data, data->buffers); for (cgltf_size i = 0; i < data->meshes_count; ++i) @@ -1866,15 +1849,9 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes); } - for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k) - { - cgltf_free_extras(data, &data->meshes[i].primitives[j].mappings[k].extras); - } - data->memory.free_func(data->memory.user_data, data->meshes[i].primitives[j].mappings); cgltf_free_extensions(data, data->meshes[i].primitives[j].extensions, data->meshes[i].primitives[j].extensions_count); - cgltf_free_extras(data, &data->meshes[i].primitives[j].extras); } data->memory.free_func(data->memory.user_data, data->meshes[i].primitives); @@ -1886,7 +1863,6 @@ void cgltf_free(cgltf_data* data) } cgltf_free_extensions(data, data->meshes[i].extensions, data->meshes[i].extensions_count); - cgltf_free_extras(data, &data->meshes[i].extras); data->memory.free_func(data->memory.user_data, data->meshes[i].target_names); } @@ -1899,50 +1875,49 @@ void cgltf_free(cgltf_data* data) if(data->materials[i].has_pbr_metallic_roughness) { - cgltf_free_texture_view(data, &data->materials[i].pbr_metallic_roughness.metallic_roughness_texture); - cgltf_free_texture_view(data, &data->materials[i].pbr_metallic_roughness.base_color_texture); + 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_texture_view(data, &data->materials[i].pbr_specular_glossiness.diffuse_texture); - cgltf_free_texture_view(data, &data->materials[i].pbr_specular_glossiness.specular_glossiness_texture); + 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_texture_view(data, &data->materials[i].clearcoat.clearcoat_texture); - cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_roughness_texture); - cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_normal_texture); + 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_specular) { - cgltf_free_texture_view(data, &data->materials[i].specular.specular_texture); - cgltf_free_texture_view(data, &data->materials[i].specular.specular_color_texture); + cgltf_free_extensions(data, data->materials[i].specular.specular_texture.extensions, data->materials[i].specular.specular_texture.extensions_count); + cgltf_free_extensions(data, data->materials[i].specular.specular_color_texture.extensions, data->materials[i].specular.specular_color_texture.extensions_count); } if(data->materials[i].has_transmission) { - cgltf_free_texture_view(data, &data->materials[i].transmission.transmission_texture); + cgltf_free_extensions(data, data->materials[i].transmission.transmission_texture.extensions, data->materials[i].transmission.transmission_texture.extensions_count); } if (data->materials[i].has_volume) { - cgltf_free_texture_view(data, &data->materials[i].volume.thickness_texture); + cgltf_free_extensions(data, data->materials[i].volume.thickness_texture.extensions, data->materials[i].volume.thickness_texture.extensions_count); } if(data->materials[i].has_sheen) { - cgltf_free_texture_view(data, &data->materials[i].sheen.sheen_color_texture); - cgltf_free_texture_view(data, &data->materials[i].sheen.sheen_roughness_texture); + cgltf_free_extensions(data, data->materials[i].sheen.sheen_color_texture.extensions, data->materials[i].sheen.sheen_color_texture.extensions_count); + cgltf_free_extensions(data, data->materials[i].sheen.sheen_roughness_texture.extensions, data->materials[i].sheen.sheen_roughness_texture.extensions_count); } if(data->materials[i].has_iridescence) { - cgltf_free_texture_view(data, &data->materials[i].iridescence.iridescence_texture); - cgltf_free_texture_view(data, &data->materials[i].iridescence.iridescence_thickness_texture); + cgltf_free_extensions(data, data->materials[i].iridescence.iridescence_texture.extensions, data->materials[i].iridescence.iridescence_texture.extensions_count); + cgltf_free_extensions(data, data->materials[i].iridescence.iridescence_thickness_texture.extensions, data->materials[i].iridescence.iridescence_thickness_texture.extensions_count); } - cgltf_free_texture_view(data, &data->materials[i].normal_texture); - cgltf_free_texture_view(data, &data->materials[i].occlusion_texture); - cgltf_free_texture_view(data, &data->materials[i].emissive_texture); + 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); - cgltf_free_extras(data, &data->materials[i].extras); } data->memory.free_func(data->memory.user_data, data->materials); @@ -1954,7 +1929,6 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->images[i].mime_type); cgltf_free_extensions(data, data->images[i].extensions, data->images[i].extensions_count); - cgltf_free_extras(data, &data->images[i].extras); } data->memory.free_func(data->memory.user_data, data->images); @@ -1962,9 +1936,7 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->textures_count; ++i) { data->memory.free_func(data->memory.user_data, data->textures[i].name); - cgltf_free_extensions(data, data->textures[i].extensions, data->textures[i].extensions_count); - cgltf_free_extras(data, &data->textures[i].extras); } data->memory.free_func(data->memory.user_data, data->textures); @@ -1972,9 +1944,7 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->samplers_count; ++i) { data->memory.free_func(data->memory.user_data, data->samplers[i].name); - cgltf_free_extensions(data, data->samplers[i].extensions, data->samplers[i].extensions_count); - cgltf_free_extras(data, &data->samplers[i].extras); } data->memory.free_func(data->memory.user_data, data->samplers); @@ -1985,7 +1955,6 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->skins[i].joints); cgltf_free_extensions(data, data->skins[i].extensions, data->skins[i].extensions_count); - cgltf_free_extras(data, &data->skins[i].extras); } data->memory.free_func(data->memory.user_data, data->skins); @@ -1993,18 +1962,7 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->cameras_count; ++i) { data->memory.free_func(data->memory.user_data, data->cameras[i].name); - - if (data->cameras[i].type == cgltf_camera_type_perspective) - { - cgltf_free_extras(data, &data->cameras[i].data.perspective.extras); - } - else if (data->cameras[i].type == cgltf_camera_type_orthographic) - { - cgltf_free_extras(data, &data->cameras[i].data.orthographic.extras); - } - cgltf_free_extensions(data, data->cameras[i].extensions, data->cameras[i].extensions_count); - cgltf_free_extras(data, &data->cameras[i].extras); } data->memory.free_func(data->memory.user_data, data->cameras); @@ -2012,8 +1970,6 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->lights_count; ++i) { data->memory.free_func(data->memory.user_data, data->lights[i].name); - - cgltf_free_extras(data, &data->lights[i].extras); } data->memory.free_func(data->memory.user_data, data->lights); @@ -2023,19 +1979,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); - - if (data->nodes[i].has_mesh_gpu_instancing) - { - for (cgltf_size j = 0; j < data->nodes[i].mesh_gpu_instancing.attributes_count; ++j) - { - data->memory.free_func(data->memory.user_data, data->nodes[i].mesh_gpu_instancing.attributes[j].name); - } - - data->memory.free_func(data->memory.user_data, data->nodes[i].mesh_gpu_instancing.attributes); - } - cgltf_free_extensions(data, data->nodes[i].extensions, data->nodes[i].extensions_count); - cgltf_free_extras(data, &data->nodes[i].extras); } data->memory.free_func(data->memory.user_data, data->nodes); @@ -2046,7 +1990,6 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->scenes[i].nodes); cgltf_free_extensions(data, data->scenes[i].extensions, data->scenes[i].extensions_count); - cgltf_free_extras(data, &data->scenes[i].extras); } data->memory.free_func(data->memory.user_data, data->scenes); @@ -2057,19 +2000,16 @@ void cgltf_free(cgltf_data* data) 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); - cgltf_free_extras(data, &data->animations[i].samplers[j].extras); } data->memory.free_func(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); - cgltf_free_extras(data, &data->animations[i].channels[j].extras); } data->memory.free_func(data->memory.user_data, data->animations[i].channels); cgltf_free_extensions(data, data->animations[i].extensions, data->animations[i].extensions_count); - cgltf_free_extras(data, &data->animations[i].extras); } data->memory.free_func(data->memory.user_data, data->animations); @@ -2077,14 +2017,11 @@ void cgltf_free(cgltf_data* data) for (cgltf_size i = 0; i < data->variants_count; ++i) { data->memory.free_func(data->memory.user_data, data->variants[i].name); - - cgltf_free_extras(data, &data->variants[i].extras); } data->memory.free_func(data->memory.user_data, data->variants); cgltf_free_extensions(data, data->data_extensions, data->data_extensions_count); - cgltf_free_extras(data, &data->extras); for (cgltf_size i = 0; i < data->extensions_used_count; ++i) { @@ -2746,27 +2683,11 @@ static int cgltf_parse_json_attribute_list(cgltf_options* options, jsmntok_t con return i; } -static int cgltf_parse_json_extras(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_extras* out_extras) +static int cgltf_parse_json_extras(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_extras* out_extras) { - if (out_extras->data) - { - return CGLTF_ERROR_JSON; - } - - /* fill deprecated fields for now, this will be removed in the future */ + (void)json_chunk; out_extras->start_offset = tokens[i].start; out_extras->end_offset = tokens[i].end; - - size_t start = tokens[i].start; - size_t size = tokens[i].end - start; - out_extras->data = (char*)options->memory.alloc_func(options->memory.user_data, size + 1); - if (!out_extras->data) - { - return CGLTF_ERROR_NOMEM; - } - strncpy(out_extras->data, (const char*)json_chunk + start, size); - out_extras->data[size] = '\0'; - i = cgltf_skip_json(tokens, i); return i; } @@ -2921,7 +2842,7 @@ static int cgltf_parse_json_material_mapping_data(cgltf_options* options, jsmnto int material = -1; int variants_tok = -1; - int extras_tok = -1; + cgltf_extras extras = {0, 0}; for (int k = 0; k < obj_size; ++k) { @@ -2942,8 +2863,7 @@ static int cgltf_parse_json_material_mapping_data(cgltf_options* options, jsmnto } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - extras_tok = i + 1; - i = cgltf_skip_json(tokens, extras_tok); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &extras); } else { @@ -2971,13 +2891,7 @@ static int cgltf_parse_json_material_mapping_data(cgltf_options* options, jsmnto out_mappings[*offset].material = CGLTF_PTRINDEX(cgltf_material, material); out_mappings[*offset].variant = variant; - - if (extras_tok >= 0) - { - int e = cgltf_parse_json_extras(options, tokens, extras_tok, json_chunk, &out_mappings[*offset].extras); - if (e < 0) - return e; - } + out_mappings[*offset].extras = extras; (*offset)++; } @@ -3092,7 +3006,7 @@ static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* t } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_prim->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_prim->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -3339,7 +3253,7 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->indices_extras); + 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) { @@ -3382,7 +3296,7 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->values_extras); + 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) { @@ -3401,7 +3315,7 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sparse->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -3524,7 +3438,7 @@ static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* to } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_accessor->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_accessor->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -3630,7 +3544,7 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_texture_view->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_texture_view->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -3726,6 +3640,10 @@ static int cgltf_parse_json_pbr_metallic_roughness(cgltf_options* options, jsmnt 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) + { + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_pbr->extras); + } else { i = cgltf_skip_json(tokens, i+1); @@ -4158,7 +4076,7 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_image->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_image->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -4227,7 +4145,7 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sampler->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sampler->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -4276,7 +4194,7 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_texture->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_texture->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -4439,7 +4357,7 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_material->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_material->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -4792,7 +4710,7 @@ static int cgltf_parse_json_buffer_view(cgltf_options* options, jsmntok_t const* } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_buffer_view->extras); + 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) { @@ -4895,7 +4813,7 @@ static int cgltf_parse_json_buffer(cgltf_options* options, jsmntok_t const* toke } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_buffer->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_buffer->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -4979,7 +4897,7 @@ static int cgltf_parse_json_skin(cgltf_options* options, jsmntok_t const* tokens } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_skin->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_skin->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -5033,6 +4951,19 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke { i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_camera->name); } + else if (cgltf_json_strcmp(tokens+i, json_chunk, "type") == 0) + { + ++i; + if (cgltf_json_strcmp(tokens + i, json_chunk, "perspective") == 0) + { + out_camera->type = cgltf_camera_type_perspective; + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "orthographic") == 0) + { + out_camera->type = cgltf_camera_type_orthographic; + } + ++i; + } else if (cgltf_json_strcmp(tokens+i, json_chunk, "perspective") == 0) { ++i; @@ -5042,11 +4973,6 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke int data_size = tokens[i].size; ++i; - if (out_camera->type != cgltf_camera_type_invalid) - { - return CGLTF_ERROR_JSON; - } - out_camera->type = cgltf_camera_type_perspective; for (int k = 0; k < data_size; ++k) @@ -5081,7 +5007,7 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_camera->data.perspective.extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->data.perspective.extras); } else { @@ -5103,11 +5029,6 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke int data_size = tokens[i].size; ++i; - if (out_camera->type != cgltf_camera_type_invalid) - { - return CGLTF_ERROR_JSON; - } - out_camera->type = cgltf_camera_type_orthographic; for (int k = 0; k < data_size; ++k) @@ -5140,7 +5061,7 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_camera->data.orthographic.extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->data.orthographic.extras); } else { @@ -5155,7 +5076,7 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_camera->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_camera->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -5288,7 +5209,7 @@ static int cgltf_parse_json_light(cgltf_options* options, jsmntok_t const* token } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_light->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_light->extras); } else { @@ -5414,7 +5335,7 @@ static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_node->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_node->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -5552,7 +5473,7 @@ static int cgltf_parse_json_scene(cgltf_options* options, jsmntok_t const* token } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_scene->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_scene->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -5634,7 +5555,7 @@ static int cgltf_parse_json_animation_sampler(cgltf_options* options, jsmntok_t } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sampler->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_sampler->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -5714,7 +5635,7 @@ static int cgltf_parse_json_animation_channel(cgltf_options* options, jsmntok_t } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_channel->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_channel->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -5796,7 +5717,7 @@ static int cgltf_parse_json_animation(cgltf_options* options, jsmntok_t const* t } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_animation->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_animation->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -5852,7 +5773,7 @@ static int cgltf_parse_json_variant(cgltf_options* options, jsmntok_t const* tok } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_variant->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_variant->extras); } else { @@ -5916,7 +5837,7 @@ static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* token } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_asset->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_asset->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { @@ -6072,7 +5993,7 @@ static int cgltf_parse_json_root(cgltf_options* options, jsmntok_t const* tokens } else if (cgltf_json_strcmp(tokens+i, json_chunk, "extras") == 0) { - i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_data->extras); + i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_data->extras); } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) { diff --git a/third_party/cgltf/cgltf_write.h b/third_party/cgltf/cgltf_write.h index 033b0d1cca..5c4edaf72d 100644 --- a/third_party/cgltf/cgltf_write.h +++ b/third_party/cgltf/cgltf_write.h @@ -15,17 +15,19 @@ * * Reference: * `cgltf_result cgltf_write_file(const cgltf_options* options, const char* - * path, const cgltf_data* data)` writes a glTF data to the given file path. - * If `options->type` is `cgltf_file_type_glb`, both JSON content and binary - * buffer of the given glTF data will be written in a GLB format. - * Otherwise, only the JSON part will be written. - * External buffers and images are not written out. `data` is not deallocated. + * path, const cgltf_data* data)` writes JSON to the given file path. Buffer + * files and external images are not written out. `data` is not deallocated. * * `cgltf_size cgltf_write(const cgltf_options* options, char* buffer, * cgltf_size size, const cgltf_data* data)` writes JSON into the given memory * buffer. Returns the number of bytes written to `buffer`, including a null * terminator. If buffer is null, returns the number of bytes that would have * been written. `data` is not deallocated. + * + * To write custom JSON into the `extras` field, aggregate all the custom JSON + * into a single buffer, then set `file_data` to this buffer. By supplying + * start_offset and end_offset values for various objects, you can select a + * range of characters within the aggregated buffer. */ #ifndef CGLTF_WRITE_H_INCLUDED__ #define CGLTF_WRITE_H_INCLUDED__ @@ -145,17 +147,6 @@ typedef struct { context->needs_comma = 1; } #define CGLTF_WRITE_TEXTURE_INFO(label, info) if (info.texture) { \ - cgltf_write_line(context, "\"" label "\": {"); \ - CGLTF_WRITE_IDXPROP("index", info.texture, context->data->textures); \ - cgltf_write_intprop(context, "texCoord", info.texcoord, 0); \ - if (info.has_transform) { \ - context->extension_flags |= CGLTF_EXTENSION_FLAG_TEXTURE_TRANSFORM; \ - cgltf_write_texture_transform(context, &info.transform); \ - } \ - cgltf_write_extras(context, &info.extras); \ - cgltf_write_line(context, "}"); } - -#define CGLTF_WRITE_NORMAL_TEXTURE_INFO(label, info) if (info.texture) { \ cgltf_write_line(context, "\"" label "\": {"); \ CGLTF_WRITE_IDXPROP("index", info.texture, context->data->textures); \ cgltf_write_intprop(context, "texCoord", info.texcoord, 0); \ @@ -167,28 +158,6 @@ typedef struct { cgltf_write_extras(context, &info.extras); \ cgltf_write_line(context, "}"); } -#define CGLTF_WRITE_OCCLUSION_TEXTURE_INFO(label, info) if (info.texture) { \ - cgltf_write_line(context, "\"" label "\": {"); \ - CGLTF_WRITE_IDXPROP("index", info.texture, context->data->textures); \ - cgltf_write_intprop(context, "texCoord", info.texcoord, 0); \ - cgltf_write_floatprop(context, "strength", info.scale, 1.0f); \ - if (info.has_transform) { \ - context->extension_flags |= CGLTF_EXTENSION_FLAG_TEXTURE_TRANSFORM; \ - cgltf_write_texture_transform(context, &info.transform); \ - } \ - cgltf_write_extras(context, &info.extras); \ - cgltf_write_line(context, "}"); } - -#ifndef CGLTF_CONSTS -static const cgltf_size GlbHeaderSize = 12; -static const cgltf_size GlbChunkHeaderSize = 8; -static const uint32_t GlbVersion = 2; -static const uint32_t GlbMagic = 0x46546C67; -static const uint32_t GlbMagicJsonChunk = 0x4E4F534A; -static const uint32_t GlbMagicBinChunk = 0x004E4942; -#define CGLTF_CONSTS -#endif - static void cgltf_write_indent(cgltf_write_context* context) { if (context->needs_comma) @@ -239,24 +208,15 @@ static void cgltf_write_strprop(cgltf_write_context* context, const char* label, static void cgltf_write_extras(cgltf_write_context* context, const cgltf_extras* extras) { - if (extras->data) + cgltf_size length = extras->end_offset - extras->start_offset; + if (length > 0 && context->data->file_data) { + char* json_string = ((char*) context->data->file_data) + extras->start_offset; cgltf_write_indent(context); - CGLTF_SPRINTF("\"extras\": %s", extras->data); + CGLTF_SPRINTF("%s", "\"extras\": "); + CGLTF_SNPRINTF(length, "%.*s", (int)(extras->end_offset - extras->start_offset), json_string); context->needs_comma = 1; } - else - { - cgltf_size length = extras->end_offset - extras->start_offset; - if (length > 0 && context->data->json) - { - char* json_string = ((char*) context->data->json) + extras->start_offset; - cgltf_write_indent(context); - CGLTF_SPRINTF("%s", "\"extras\": "); - CGLTF_SNPRINTF(length, "%.*s", (int)(extras->end_offset - extras->start_offset), json_string); - context->needs_comma = 1; - } - } } static void cgltf_write_stritem(cgltf_write_context* context, const char* item) @@ -653,6 +613,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater { cgltf_write_floatarrayprop(context, "baseColorFactor", params->base_color_factor, 4); } + cgltf_write_extras(context, ¶ms->extras); cgltf_write_line(context, "}"); } @@ -665,7 +626,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater cgltf_write_line(context, "\"KHR_materials_clearcoat\": {"); CGLTF_WRITE_TEXTURE_INFO("clearcoatTexture", params->clearcoat_texture); CGLTF_WRITE_TEXTURE_INFO("clearcoatRoughnessTexture", params->clearcoat_roughness_texture); - CGLTF_WRITE_NORMAL_TEXTURE_INFO("clearcoatNormalTexture", params->clearcoat_normal_texture); + CGLTF_WRITE_TEXTURE_INFO("clearcoatNormalTexture", params->clearcoat_normal_texture); cgltf_write_floatprop(context, "clearcoatFactor", params->clearcoat_factor, 0.0f); cgltf_write_floatprop(context, "clearcoatRoughnessFactor", params->clearcoat_roughness_factor, 0.0f); cgltf_write_line(context, "}"); @@ -770,8 +731,8 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater cgltf_write_line(context, "}"); } - CGLTF_WRITE_NORMAL_TEXTURE_INFO("normalTexture", material->normal_texture); - CGLTF_WRITE_OCCLUSION_TEXTURE_INFO("occlusionTexture", material->occlusion_texture); + CGLTF_WRITE_TEXTURE_INFO("normalTexture", material->normal_texture); + CGLTF_WRITE_TEXTURE_INFO("occlusionTexture", material->occlusion_texture); CGLTF_WRITE_TEXTURE_INFO("emissiveTexture", material->emissive_texture); if (cgltf_check_floatarray(material->emissive_factor, 3, 0.0f)) { @@ -1136,47 +1097,6 @@ static void cgltf_write_variant(cgltf_write_context* context, const cgltf_materi cgltf_write_line(context, "}"); } -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]; - char chunk_header[GlbChunkHeaderSize]; - char json_pad[3] = { 0x20, 0x20, 0x20 }; - char bin_pad[3] = { 0, 0, 0 }; - - cgltf_size json_padsize = (json_size % 4 != 0) ? 4 - json_size % 4 : 0; - cgltf_size bin_padsize = (bin_size % 4 != 0) ? 4 - bin_size % 4 : 0; - cgltf_size total_size = GlbHeaderSize + GlbChunkHeaderSize + json_size + json_padsize; - if (bin_buf != NULL && bin_size > 0) { - total_size += GlbChunkHeaderSize + bin_size + bin_padsize; - } - - // Write a GLB header - memcpy(header, &GlbMagic, 4); - memcpy(header + 4, &GlbVersion, 4); - memcpy(header + 8, &total_size, 4); - fwrite(header, 1, GlbHeaderSize, file); - - // Write a JSON chunk (header & data) - uint32_t json_chunk_size = (uint32_t)(json_size + json_padsize); - memcpy(chunk_header, &json_chunk_size, 4); - memcpy(chunk_header + 4, &GlbMagicJsonChunk, 4); - fwrite(chunk_header, 1, GlbChunkHeaderSize, file); - - fwrite(json_buf, 1, json_size, file); - fwrite(json_pad, 1, json_padsize, file); - - if (bin_buf != NULL && bin_size > 0) { - // Write a binary chunk (header & data) - uint32_t bin_chunk_size = (uint32_t)(bin_size + bin_padsize); - memcpy(chunk_header, &bin_chunk_size, 4); - memcpy(chunk_header + 4, &GlbMagicBinChunk, 4); - fwrite(chunk_header, 1, GlbChunkHeaderSize, file); - - fwrite(bin_buf, 1, bin_size, file); - fwrite(bin_pad, 1, bin_padsize, file); - } -} - cgltf_result cgltf_write_file(const cgltf_options* options, const char* path, const cgltf_data* data) { cgltf_size expected = cgltf_write(options, NULL, 0, data); @@ -1185,18 +1105,13 @@ cgltf_result cgltf_write_file(const cgltf_options* options, const char* path, co if (expected != actual) { fprintf(stderr, "Error: expected %zu bytes but wrote %zu bytes.\n", expected, actual); } - FILE* file = fopen(path, "wb"); + FILE* file = fopen(path, "wt"); if (!file) { return cgltf_result_file_not_found; } // Note that cgltf_write() includes a null terminator, which we omit from the file content. - if (options->type == cgltf_file_type_glb) { - cgltf_write_glb(file, buffer, actual - 1, data->bin, data->bin_size); - } else { - // Write a plain JSON file. - fwrite(buffer, actual - 1, 1, file); - } + fwrite(buffer, actual - 1, 1, file); fclose(file); free(buffer); return cgltf_result_success; diff --git a/third_party/cgltf/test/CMakeLists.txt b/third_party/cgltf/test/CMakeLists.txt index d62d01d6cc..aa31730524 100644 --- a/third_party/cgltf/test/CMakeLists.txt +++ b/third_party/cgltf/test/CMakeLists.txt @@ -41,19 +41,6 @@ else() endif() install( TARGETS ${EXE_NAME} RUNTIME DESTINATION bin ) -set( EXE_NAME test_write_glb ) -add_executable( ${EXE_NAME} test_write_glb.cpp ) -set_property( TARGET ${EXE_NAME} PROPERTY CXX_STANDARD 11 ) -if(MSVC) - target_compile_options(${EXE_NAME} PRIVATE /W4 /WX) - add_definitions( -D_CRT_SECURE_NO_WARNINGS) -else() - target_compile_options(${EXE_NAME} PRIVATE -Wall -Wextra -pedantic -Werror) - target_compile_options(${EXE_NAME} PUBLIC -fsanitize=address) - target_link_options(${EXE_NAME} PUBLIC -fsanitize=address) -endif() -install( TARGETS ${EXE_NAME} RUNTIME DESTINATION bin ) - set( EXE_NAME test_math ) add_executable( ${EXE_NAME} test_math.cpp ) set_property( TARGET ${EXE_NAME} PROPERTY CXX_STANDARD 11 ) diff --git a/third_party/cgltf/test/test_all.py b/third_party/cgltf/test/test_all.py index ac0882f5d8..ec9b9f0164 100755 --- a/third_party/cgltf/test/test_all.py +++ b/third_party/cgltf/test/test_all.py @@ -59,7 +59,6 @@ if __name__ == "__main__": collect_files("glTF-Sample-Models/2.0/", ".glb", "test_conversion") collect_files("glTF-Sample-Models/2.0/", ".gltf", "test_conversion") collect_files("glTF-Sample-Models/2.0/", ".gltf", "test_write") - collect_files("glTF-Sample-Models/2.0/", ".glb", "test_write_glb") result = os.system(get_executable_path("test_math")) if result != 0: diff --git a/third_party/cgltf/test/test_write_glb.cpp b/third_party/cgltf/test/test_write_glb.cpp deleted file mode 100644 index c3c5b4430e..0000000000 --- a/third_party/cgltf/test/test_write_glb.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#define CGLTF_IMPLEMENTATION -#define CGLTF_WRITE_IMPLEMENTATION -#include "../cgltf_write.h" - -#include -#include -#include -#include -#include - -int main(int argc, char** argv) -{ - if (argc < 2) - { - printf("err\n"); - return -1; - } - - cgltf_options options = {}; - cgltf_data* data0 = NULL; - cgltf_result result = cgltf_parse_file(&options, argv[1], &data0); - - // Silently skip over files that are unreadable since this is a writing test. - if (result != cgltf_result_success) - { - return cgltf_result_success; - } - - options.type = cgltf_file_type_glb; // Write back in a GLB format - result = cgltf_write_file(&options, "out.glb", data0); - if (result != cgltf_result_success) - { - return result; - } - - cgltf_data* data1 = NULL; - result = cgltf_parse_file(&options, "out.glb", &data1); - if (result != cgltf_result_success) - { - return result; - } - - if (data0->meshes_count != data1->meshes_count) { - return -1; - } - - // Compare binary buffers - if (data0->bin_size != data1->bin_size) { - return -1; - } - if (memcmp(data0->bin, data1->bin, data0->bin_size) != 0) { - return -1; - } - - cgltf_free(data1); - cgltf_free(data0); - return cgltf_result_success; -} diff --git a/third_party/cgltf/tnt/README b/third_party/cgltf/tnt/README index 1e992ce14c..fbfc97e770 100644 --- a/third_party/cgltf/tnt/README +++ b/third_party/cgltf/tnt/README @@ -1,10 +1,10 @@ This folder was last updated as follows: - export sha=280ab89 + export tag=v1.13 cd third_party - curl -L -O https://github.com/jkuhlmann/cgltf/archive/${sha}.zip - unzip ${sha}.zip + curl -L -O https://github.com/jkuhlmann/cgltf/archive/refs/tags/${tag}.zip + unzip ${tag}.zip mv cgltf-* cgltf_new rsync -r cgltf_new/ cgltf/ --delete --exclude tnt - rm -rf ${sha}.zip cgltf_new + rm -rf ${tag}.zip cgltf_new git add cgltf ; git status