From 7559cb20bf5db7da057eb5dd87e98a048fed0f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Mon, 13 Sep 2021 19:32:22 -0700 Subject: [PATCH] Updated cgltf. --- 3rdparty/cgltf/cgltf.h | 68 +++++++++++++++++++++++++++--------- 3rdparty/cgltf/cgltf_write.h | 43 ++++++++++++++++------- 2 files changed, 83 insertions(+), 28 deletions(-) diff --git a/3rdparty/cgltf/cgltf.h b/3rdparty/cgltf/cgltf.h index 300a1466f..785869749 100644 --- a/3rdparty/cgltf/cgltf.h +++ b/3rdparty/cgltf/cgltf.h @@ -1,7 +1,7 @@ /** * cgltf - a single-file glTF 2.0 parser written in C99. * - * Version: 1.10 + * Version: 1.11 * * Website: https://github.com/jkuhlmann/cgltf * @@ -234,6 +234,12 @@ typedef enum cgltf_light_type { cgltf_light_type_spot, } cgltf_light_type; +typedef enum cgltf_data_free_method { + cgltf_data_free_method_none, + cgltf_data_free_method_file_release, + cgltf_data_free_method_memory_free, +} cgltf_data_free_method; + typedef struct cgltf_extras { cgltf_size start_offset; cgltf_size end_offset; @@ -250,6 +256,7 @@ typedef struct cgltf_buffer cgltf_size size; char* uri; void* data; /* loaded by cgltf_load_buffers */ + cgltf_data_free_method data_free_method; cgltf_extras extras; cgltf_size extensions_count; cgltf_extension* extensions; @@ -384,6 +391,7 @@ typedef struct cgltf_texture_transform cgltf_float offset[2]; cgltf_float rotation; cgltf_float scale[2]; + cgltf_bool has_texcoord; cgltf_int texcoord; } cgltf_texture_transform; @@ -816,7 +824,7 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* #include /* For UINT_MAX etc */ #include /* For FLT_MAX */ -#if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF) +#if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF) || !defined(CGLTF_ATOLL) #include /* For malloc, free, atoi, atof */ #endif @@ -886,6 +894,9 @@ static const uint32_t GlbMagicBinChunk = 0x004E4942; #ifndef CGLTF_ATOF #define CGLTF_ATOF(str) atof(str) #endif +#ifndef CGLTF_ATOLL +#define CGLTF_ATOLL(str) atoll(str) +#endif #ifndef CGLTF_VALIDATE_ENABLE_ASSERTS #define CGLTF_VALIDATE_ENABLE_ASSERTS 0 #endif @@ -935,7 +946,12 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m { fseek(file, 0, SEEK_END); +#ifdef _WIN32 + __int64 length = _ftelli64(file); +#else long length = ftell(file); +#endif + if (length < 0) { fclose(file); @@ -1123,8 +1139,8 @@ cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cg return cgltf_result_invalid_options; } - void (*memory_free)(void*, void*) = options->memory.free ? options->memory.free : &cgltf_default_free; cgltf_result (*file_read)(const struct cgltf_memory_options*, const struct cgltf_file_options*, const char*, cgltf_size*, void**) = options->file.read ? options->file.read : &cgltf_default_file_read; + void (*file_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data) = options->file.release ? options->file.release : cgltf_default_file_release; void* file_data = NULL; cgltf_size file_size = 0; @@ -1138,7 +1154,7 @@ cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cg if (result != cgltf_result_success) { - memory_free(options->memory.user_data, file_data); + file_release(&options->memory, &options->file, file_data); return result; } @@ -1294,6 +1310,7 @@ cgltf_result cgltf_load_buffers(const cgltf_options* options, cgltf_data* data, } data->buffers[0].data = (void*)data->bin; + data->buffers[0].data_free_method = cgltf_data_free_method_none; } for (cgltf_size i = 0; i < data->buffers_count; ++i) @@ -1317,6 +1334,7 @@ cgltf_result cgltf_load_buffers(const cgltf_options* options, cgltf_data* data, if (comma && comma - uri >= 7 && strncmp(comma - 7, ";base64", 7) == 0) { cgltf_result res = cgltf_load_buffer_base64(options, data->buffers[i].size, comma + 1, &data->buffers[i].data); + data->buffers[i].data_free_method = cgltf_data_free_method_memory_free; if (res != cgltf_result_success) { @@ -1331,6 +1349,7 @@ cgltf_result cgltf_load_buffers(const cgltf_options* options, cgltf_data* data, else if (strstr(uri, "://") == NULL && gltf_path) { cgltf_result res = cgltf_load_buffer_file(options, data->buffers[i].size, uri, gltf_path, &data->buffers[i].data); + data->buffers[i].data_free_method = cgltf_data_free_method_file_release; if (res != cgltf_result_success) { @@ -1658,10 +1677,15 @@ void cgltf_free(cgltf_data* data) { data->memory.free(data->memory.user_data, data->buffers[i].name); - if (data->buffers[i].data != data->bin) + if (data->buffers[i].data_free_method == cgltf_data_free_method_file_release) { file_release(&data->memory, &data->file, data->buffers[i].data); } + else if (data->buffers[i].data_free_method == cgltf_data_free_method_memory_free) + { + data->memory.free(data->memory.user_data, data->buffers[i].data); + } + data->memory.free(data->memory.user_data, data->buffers[i].uri); cgltf_free_extensions(data, data->buffers[i].extensions, data->buffers[i].extensions_count); @@ -2262,6 +2286,7 @@ cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size #define CGLTF_ERROR_LEGACY -3 #define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; } +#define CGLTF_CHECK_TOKTYPE_RETTYPE(tok_, type_, ret_) if ((tok_).type != (type_)) { return (ret_)CGLTF_ERROR_JSON; } #define CGLTF_CHECK_KEY(tok_) if ((tok_).type != JSMN_STRING || (tok_).size == 0) { return CGLTF_ERROR_JSON; } /* checking size for 0 verifies that a value follows the key */ #define CGLTF_PTRINDEX(type, idx) (type*)((cgltf_size)idx + 1) @@ -2286,6 +2311,16 @@ static int cgltf_json_to_int(jsmntok_t const* tok, const uint8_t* json_chunk) return CGLTF_ATOI(tmp); } +static cgltf_size cgltf_json_to_size(jsmntok_t const* tok, const uint8_t* json_chunk) +{ + CGLTF_CHECK_TOKTYPE_RETTYPE(*tok, JSMN_PRIMITIVE, cgltf_size); + char tmp[128]; + int size = (cgltf_size)(tok->end - tok->start) < sizeof(tmp) ? tok->end - tok->start : (int)(sizeof(tmp) - 1); + strncpy(tmp, (const char*)json_chunk + tok->start, size); + tmp[size] = 0; + return (cgltf_size)CGLTF_ATOLL(tmp); +} + static cgltf_float cgltf_json_to_float(jsmntok_t const* tok, const uint8_t* json_chunk) { CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE); @@ -3027,7 +3062,7 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0) { ++i; - out_sparse->indices_byte_offset = cgltf_json_to_int(tokens + i, json_chunk); + out_sparse->indices_byte_offset = cgltf_json_to_size(tokens + i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "componentType") == 0) @@ -3076,7 +3111,7 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0) { ++i; - out_sparse->values_byte_offset = cgltf_json_to_int(tokens + i, json_chunk); + out_sparse->values_byte_offset = cgltf_json_to_size(tokens + i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) @@ -3145,7 +3180,7 @@ static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* to { ++i; out_accessor->offset = - cgltf_json_to_int(tokens+i, json_chunk); + cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "componentType") == 0) @@ -3271,6 +3306,7 @@ static int cgltf_parse_json_texture_transform(jsmntok_t const* tokens, int i, co else if (cgltf_json_strcmp(tokens + i, json_chunk, "texCoord") == 0) { ++i; + out_texture_transform->has_texcoord = 1; out_texture_transform->texcoord = cgltf_json_to_int(tokens + i, json_chunk); ++i; } @@ -4250,19 +4286,19 @@ static int cgltf_parse_json_meshopt_compression(cgltf_options* options, jsmntok_ else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0) { ++i; - out_meshopt_compression->offset = cgltf_json_to_int(tokens+i, json_chunk); + out_meshopt_compression->offset = cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0) { ++i; - out_meshopt_compression->size = cgltf_json_to_int(tokens+i, json_chunk); + out_meshopt_compression->size = cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteStride") == 0) { ++i; - out_meshopt_compression->stride = cgltf_json_to_int(tokens+i, json_chunk); + out_meshopt_compression->stride = cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0) @@ -4348,21 +4384,21 @@ static int cgltf_parse_json_buffer_view(cgltf_options* options, jsmntok_t const* { ++i; out_buffer_view->offset = - cgltf_json_to_int(tokens+i, json_chunk); + cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0) { ++i; out_buffer_view->size = - cgltf_json_to_int(tokens+i, json_chunk); + cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteStride") == 0) { ++i; out_buffer_view->stride = - cgltf_json_to_int(tokens+i, json_chunk); + cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "target") == 0) @@ -4480,7 +4516,7 @@ static int cgltf_parse_json_buffer(cgltf_options* options, jsmntok_t const* toke { ++i; out_buffer->size = - cgltf_json_to_int(tokens+i, json_chunk); + cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "uri") == 0) @@ -6376,7 +6412,7 @@ static void jsmn_init(jsmn_parser *parser) { /* cgltf is distributed under MIT license: * - * Copyright (c) 2018 Johannes Kuhlmann + * Copyright (c) 2018-2021 Johannes Kuhlmann * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/3rdparty/cgltf/cgltf_write.h b/3rdparty/cgltf/cgltf_write.h index 50a9d8064..8b96eb2b6 100644 --- a/3rdparty/cgltf/cgltf_write.h +++ b/3rdparty/cgltf/cgltf_write.h @@ -1,7 +1,7 @@ /** * cgltf_write - a single-file glTF 2.0 writer written in C99. * - * Version: 1.10 + * Version: 1.11 * * Website: https://github.com/jkuhlmann/cgltf * @@ -64,6 +64,7 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si #ifdef CGLTF_WRITE_IMPLEMENTATION +#include #include #include #include @@ -109,6 +110,7 @@ typedef struct { #endif #define CGLTF_SPRINTF(...) { \ + assert(context->cursor || (!context->cursor && context->remaining == 0)); \ context->tmp = snprintf ( context->cursor, context->remaining, __VA_ARGS__ ); \ context->chars_written += context->tmp; \ if (context->cursor) { \ @@ -117,6 +119,7 @@ typedef struct { } } #define CGLTF_SNPRINTF(length, ...) { \ + assert(context->cursor || (!context->cursor && context->remaining == 0)); \ context->tmp = snprintf ( context->cursor, CGLTF_MIN(length + 1, context->remaining), __VA_ARGS__ ); \ context->chars_written += length; \ if (context->cursor) { \ @@ -230,6 +233,16 @@ static void cgltf_write_intprop(cgltf_write_context* context, const char* label, } } +static void cgltf_write_sizeprop(cgltf_write_context* context, const char* label, cgltf_size val, cgltf_size def) +{ + if (val != def) + { + cgltf_write_indent(context); + CGLTF_SPRINTF("\"%s\": %zu", label, val); + context->needs_comma = 1; + } +} + static void cgltf_write_floatprop(cgltf_write_context* context, const char* label, float val, float def) { if (val != def) @@ -378,7 +391,10 @@ static void cgltf_write_texture_transform(cgltf_write_context* context, const cg { cgltf_write_floatarrayprop(context, "scale", transform->scale, 2); } - cgltf_write_intprop(context, "texCoord", transform->texcoord, 0); + if (transform->has_texcoord) + { + cgltf_write_intprop(context, "texCoord", transform->texcoord, -1); + } cgltf_write_line(context, "}"); cgltf_write_line(context, "}"); } @@ -501,9 +517,9 @@ static void cgltf_write_buffer_view(cgltf_write_context* context, const cgltf_bu cgltf_write_line(context, "{"); cgltf_write_strprop(context, "name", view->name); CGLTF_WRITE_IDXPROP("buffer", view->buffer, context->data->buffers); - cgltf_write_intprop(context, "byteLength", (int)view->size, -1); - cgltf_write_intprop(context, "byteOffset", (int)view->offset, 0); - cgltf_write_intprop(context, "byteStride", (int)view->stride, 0); + cgltf_write_sizeprop(context, "byteLength", view->size, (cgltf_size)-1); + cgltf_write_sizeprop(context, "byteOffset", view->offset, 0); + cgltf_write_sizeprop(context, "byteStride", view->stride, 0); // NOTE: We skip writing "target" because the spec says its usage can be inferred. cgltf_write_extras(context, &view->extras); cgltf_write_line(context, "}"); @@ -515,7 +531,7 @@ static void cgltf_write_buffer(cgltf_write_context* context, const cgltf_buffer* cgltf_write_line(context, "{"); cgltf_write_strprop(context, "name", buffer->name); cgltf_write_strprop(context, "uri", buffer->uri); - cgltf_write_intprop(context, "byteLength", (int)buffer->size, -1); + cgltf_write_sizeprop(context, "byteLength", buffer->size, (cgltf_size)-1); cgltf_write_extras(context, &buffer->extras); cgltf_write_line(context, "}"); } @@ -524,7 +540,10 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater { cgltf_write_line(context, "{"); cgltf_write_strprop(context, "name", material->name); - cgltf_write_floatprop(context, "alphaCutoff", material->alpha_cutoff, 0.5f); + if (material->alpha_mode == cgltf_alpha_mode_mask) + { + cgltf_write_floatprop(context, "alphaCutoff", material->alpha_cutoff, 0.5f); + } cgltf_write_boolprop_optional(context, "doubleSided", material->double_sided, false); // cgltf_write_boolprop_optional(context, "unlit", material->unlit, false); @@ -663,7 +682,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater CGLTF_WRITE_TEXTURE_INFO("specularGlossinessTexture", params->specular_glossiness_texture); if (cgltf_check_floatarray(params->diffuse_factor, 4, 1.0f)) { - cgltf_write_floatarrayprop(context, "dffuseFactor", params->diffuse_factor, 4); + cgltf_write_floatarrayprop(context, "diffuseFactor", params->diffuse_factor, 4); } if (cgltf_check_floatarray(params->specular_factor, 3, 1.0f)) { @@ -907,7 +926,7 @@ static void cgltf_write_accessor(cgltf_write_context* context, const cgltf_acces cgltf_write_strprop(context, "type", cgltf_str_from_type(accessor->type)); cgltf_size dim = cgltf_dim_from_type(accessor->type); cgltf_write_boolprop_optional(context, "normalized", accessor->normalized, false); - cgltf_write_intprop(context, "byteOffset", (int)accessor->offset, 0); + cgltf_write_sizeprop(context, "byteOffset", (int)accessor->offset, 0); cgltf_write_intprop(context, "count", (int)accessor->count, -1); if (accessor->has_min) { @@ -922,13 +941,13 @@ static void cgltf_write_accessor(cgltf_write_context* context, const cgltf_acces cgltf_write_line(context, "\"sparse\": {"); cgltf_write_intprop(context, "count", (int)accessor->sparse.count, 0); cgltf_write_line(context, "\"indices\": {"); - cgltf_write_intprop(context, "byteOffset", (int)accessor->sparse.indices_byte_offset, 0); + cgltf_write_sizeprop(context, "byteOffset", (int)accessor->sparse.indices_byte_offset, 0); CGLTF_WRITE_IDXPROP("bufferView", accessor->sparse.indices_buffer_view, context->data->buffer_views); cgltf_write_intprop(context, "componentType", cgltf_int_from_component_type(accessor->sparse.indices_component_type), 0); cgltf_write_extras(context, &accessor->sparse.indices_extras); cgltf_write_line(context, "}"); cgltf_write_line(context, "\"values\": {"); - cgltf_write_intprop(context, "byteOffset", (int)accessor->sparse.values_byte_offset, 0); + cgltf_write_sizeprop(context, "byteOffset", (int)accessor->sparse.values_byte_offset, 0); CGLTF_WRITE_IDXPROP("bufferView", accessor->sparse.values_buffer_view, context->data->buffer_views); cgltf_write_extras(context, &accessor->sparse.values_extras); cgltf_write_line(context, "}"); @@ -1292,7 +1311,7 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si /* cgltf is distributed under MIT license: * - * Copyright (c) 2019 Philip Rideout + * Copyright (c) 2019-2021 Philip Rideout * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal