diff --git a/third_party/cgltf/README.md b/third_party/cgltf/README.md index 06ef5e2da3..f8893ce529 100644 --- a/third_party/cgltf/README.md +++ b/third_party/cgltf/README.md @@ -105,6 +105,7 @@ cgltf also supports some glTF extensions: - KHR_materials_pbrSpecularGlossiness - KHR_materials_unlit - KHR_texture_transform +- KHR_draco_mesh_compression (requires a library like [Google's Draco](https://github.com/google/draco) for decompression though) cgltf does **not** yet support unlisted extensions. diff --git a/third_party/cgltf/cgltf.h b/third_party/cgltf/cgltf.h index bbc641cf9c..18a2dd693c 100644 --- a/third_party/cgltf/cgltf.h +++ b/third_party/cgltf/cgltf.h @@ -385,6 +385,12 @@ typedef struct cgltf_morph_target { cgltf_size attributes_count; } cgltf_morph_target; +typedef struct cgltf_draco_mesh_compression { + cgltf_buffer_view* buffer_view; + cgltf_attribute* attributes; + cgltf_size attributes_count; +} cgltf_draco_mesh_compression; + typedef struct cgltf_primitive { cgltf_primitive_type type; cgltf_accessor* indices; @@ -394,6 +400,8 @@ typedef struct cgltf_primitive { cgltf_morph_target* targets; cgltf_size targets_count; cgltf_extras extras; + cgltf_bool has_draco_mesh_compression; + cgltf_draco_mesh_compression draco_mesh_compression; } cgltf_primitive; typedef struct cgltf_mesh { @@ -632,8 +640,8 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* * */ -#ifdef __INTELLISENSE__ -/* This makes MSVC intellisense work. */ +#if defined(__INTELLISENSE__) || defined(__JETBRAINS_IDE__) +/* This makes MSVC/CLion intellisense work. */ #define CGLTF_IMPLEMENTATION #endif @@ -948,7 +956,6 @@ cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cg return cgltf_result_invalid_options; } - void* (*memory_alloc)(void*, cgltf_size) = options->memory.alloc ? options->memory.alloc : &cgltf_default_alloc; void (*memory_free)(void*, void*) = options->memory.free ? options->memory.free : &cgltf_default_free; cgltf_result (*file_read)(const struct cgltf_memory_options*, const struct cgltf_file_options*, const char*, cgltf_size*, void**) = options->file.read ? options->file.read : &cgltf_default_file_read; @@ -995,7 +1002,6 @@ static void cgltf_combine_paths(char* path, const char* base, const char* uri) static cgltf_result cgltf_load_buffer_file(const cgltf_options* options, cgltf_size size, const char* uri, const char* gltf_path, void** out_data) { void* (*memory_alloc)(void*, cgltf_size) = options->memory.alloc ? options->memory.alloc : &cgltf_default_alloc; - void (*memory_free)(void*, void*) = options->memory.free ? options->memory.free : &cgltf_default_free; cgltf_result (*file_read)(const struct cgltf_memory_options*, const struct cgltf_file_options*, const char*, cgltf_size*, void**) = options->file.read ? options->file.read : &cgltf_default_file_read; char* path = (char*)memory_alloc(options->memory.user_data, strlen(uri) + strlen(gltf_path) + 1); @@ -1852,8 +1858,6 @@ static cgltf_uint cgltf_component_read_uint(const void* in, cgltf_component_type default: return 0; } - - return 0; } static cgltf_bool cgltf_element_read_uint(const uint8_t* element, cgltf_type type, cgltf_component_type component_type, cgltf_uint* out, cgltf_size element_size) @@ -2173,6 +2177,32 @@ static int cgltf_parse_json_extras(jsmntok_t const* tokens, int i, const uint8_t return i; } +static int cgltf_parse_json_draco_mesh_compression(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_draco_mesh_compression* out_draco_mesh_compression) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + + int size = tokens[i].size; + ++i; + + for (int j = 0; j < size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens + i, json_chunk, "attributes") == 0) + { + i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_draco_mesh_compression->attributes, &out_draco_mesh_compression->attributes_count); + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "bufferView") == 0) + { + ++i; + out_draco_mesh_compression->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk)); + ++i; + } + } + + return i; +} + static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_primitive* out_prim) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -2231,6 +2261,35 @@ static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* t { i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_prim->extras); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) + { + ++i; + + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + + int extensions_size = tokens[i].size; + ++i; + + for (int k = 0; k < extensions_size; ++k) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_draco_mesh_compression") == 0) + { + out_prim->has_draco_mesh_compression = 1; + i = cgltf_parse_json_draco_mesh_compression(options, tokens, i + 1, json_chunk, &out_prim->draco_mesh_compression); + } + else + { + i = cgltf_skip_json(tokens, i+1); + } + + if (i < 0) + { + return i; + } + } + } else { i = cgltf_skip_json(tokens, i+1); @@ -4585,6 +4644,14 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].targets[k].attributes[m].data, data->accessors, data->accessors_count); } } + + if (data->meshes[i].primitives[j].has_draco_mesh_compression) { + CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.buffer_view, data->buffer_views, data->buffer_views_count); + for (cgltf_size m = 0; m < data->meshes[i].primitives[j].draco_mesh_compression.attributes_count; ++m) + { + CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.attributes[m].data, data->accessors, data->accessors_count); + } + } } } diff --git a/third_party/cgltf/cgltf_write.h b/third_party/cgltf/cgltf_write.h index ce90bcd86c..77914a7943 100644 --- a/third_party/cgltf/cgltf_write.h +++ b/third_party/cgltf/cgltf_write.h @@ -57,9 +57,9 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si * */ -#ifdef __INTELLISENSE__ -/* This makes MSVC intellisense work. */ -#define CGLTF_WRITE_IMPLEMENTATION +#if defined(__INTELLISENSE__) || defined(__JETBRAINS_IDE__) +/* This makes MSVC/CLion intellisense work. */ +#define CGLTF_IMPLEMENTATION #endif #ifdef CGLTF_WRITE_IMPLEMENTATION @@ -69,10 +69,11 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si #include #include -#define CGLTF_EXTENSION_FLAG_TEXTURE_TRANSFORM (1 << 0) -#define CGLTF_EXTENSION_FLAG_MATERIALS_UNLIT (1 << 1) -#define CGLTF_EXTENSION_FLAG_SPECULAR_GLOSSINESS (1 << 2) -#define CGLTF_EXTENSION_FLAG_LIGHTS_PUNCTUAL (1 << 3) +#define CGLTF_EXTENSION_FLAG_TEXTURE_TRANSFORM (1 << 0) +#define CGLTF_EXTENSION_FLAG_MATERIALS_UNLIT (1 << 1) +#define CGLTF_EXTENSION_FLAG_SPECULAR_GLOSSINESS (1 << 2) +#define CGLTF_EXTENSION_FLAG_LIGHTS_PUNCTUAL (1 << 3) +#define CGLTF_EXTENSION_FLAG_DRACO_MESH_COMPRESSION (1 << 4) typedef struct { char* buffer; @@ -86,6 +87,7 @@ typedef struct { const char* indent; int needs_comma; uint32_t extension_flags; + uint32_t required_extension_flags; } cgltf_write_context; #define CGLTF_MIN(a, b) (a < b ? a : b) @@ -405,6 +407,31 @@ static void cgltf_write_primitive(cgltf_write_context* context, const cgltf_prim cgltf_write_line(context, "]"); } cgltf_write_extras(context, &prim->extras); + + cgltf_bool has_extensions = prim->has_draco_mesh_compression; + if (has_extensions) { + cgltf_write_line(context, "\"extensions\": {"); + + if (prim->has_draco_mesh_compression) { + context->extension_flags |= CGLTF_EXTENSION_FLAG_DRACO_MESH_COMPRESSION; + if (prim->attributes_count == 0 || prim->indices == 0) { + context->required_extension_flags |= CGLTF_EXTENSION_FLAG_DRACO_MESH_COMPRESSION; + } + + cgltf_write_line(context, "\"KHR_draco_mesh_compression\": {"); + CGLTF_WRITE_IDXPROP("bufferView", prim->draco_mesh_compression.buffer_view, context->data->buffer_views); + cgltf_write_line(context, "\"attributes\": {"); + for (cgltf_size i = 0; i < prim->draco_mesh_compression.attributes_count; ++i) + { + const cgltf_attribute* attr = prim->draco_mesh_compression.attributes + i; + CGLTF_WRITE_IDXPROP(attr->name, attr->data, context->data->accessors); + } + cgltf_write_line(context, "}"); + cgltf_write_line(context, "}"); + } + + cgltf_write_line(context, "}"); + } } static void cgltf_write_mesh(cgltf_write_context* context, const cgltf_mesh* mesh) @@ -836,6 +863,25 @@ cgltf_result cgltf_write_file(const cgltf_options* options, const char* path, co return cgltf_result_success; } +static void cgltf_write_extensions(cgltf_write_context* context, uint32_t extension_flags) +{ + if (extension_flags & CGLTF_EXTENSION_FLAG_TEXTURE_TRANSFORM) { + cgltf_write_stritem(context, "KHR_texture_transform"); + } + if (extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_UNLIT) { + cgltf_write_stritem(context, "KHR_materials_unlit"); + } + if (extension_flags & CGLTF_EXTENSION_FLAG_SPECULAR_GLOSSINESS) { + cgltf_write_stritem(context, "KHR_materials_pbrSpecularGlossiness"); + } + if (extension_flags & CGLTF_EXTENSION_FLAG_LIGHTS_PUNCTUAL) { + cgltf_write_stritem(context, "KHR_lights_punctual"); + } + if (extension_flags & CGLTF_EXTENSION_FLAG_DRACO_MESH_COMPRESSION) { + cgltf_write_stritem(context, "KHR_draco_mesh_compression"); + } +} + cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size size, const cgltf_data* data) { (void)options; @@ -850,6 +896,7 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si ctx.indent = " "; ctx.needs_comma = 0; ctx.extension_flags = 0; + ctx.required_extension_flags = 0; cgltf_write_context* context = &ctx; @@ -1007,18 +1054,13 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si if (context->extension_flags != 0) { cgltf_write_line(context, "\"extensionsUsed\": ["); - if (context->extension_flags & CGLTF_EXTENSION_FLAG_TEXTURE_TRANSFORM) { - cgltf_write_stritem(context, "KHR_texture_transform"); - } - if (context->extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_UNLIT) { - cgltf_write_stritem(context, "KHR_materials_unlit"); - } - if (context->extension_flags & CGLTF_EXTENSION_FLAG_SPECULAR_GLOSSINESS) { - cgltf_write_stritem(context, "KHR_materials_pbrSpecularGlossiness"); - } - if (context->extension_flags & CGLTF_EXTENSION_FLAG_LIGHTS_PUNCTUAL) { - cgltf_write_stritem(context, "KHR_lights_punctual"); - } + cgltf_write_extensions(context, context->extension_flags); + cgltf_write_line(context, "]"); + } + + if (context->required_extension_flags != 0) { + cgltf_write_line(context, "\"extensionsRequired\": ["); + cgltf_write_extensions(context, context->required_extension_flags); cgltf_write_line(context, "]"); } diff --git a/third_party/cgltf/test/CMakeLists.txt b/third_party/cgltf/test/CMakeLists.txt index 805221402e..a017aa71d3 100644 --- a/third_party/cgltf/test/CMakeLists.txt +++ b/third_party/cgltf/test/CMakeLists.txt @@ -5,19 +5,43 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) set( EXE_NAME cgltf_test ) add_executable( ${EXE_NAME} main.c ) set_property( TARGET ${EXE_NAME} PROPERTY C_STANDARD 99 ) +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) +endif() install( TARGETS ${EXE_NAME} RUNTIME DESTINATION bin ) set( EXE_NAME test_conversion ) add_executable( ${EXE_NAME} test_conversion.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) +endif() install( TARGETS ${EXE_NAME} RUNTIME DESTINATION bin ) set( EXE_NAME test_write ) add_executable( ${EXE_NAME} test_write.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) +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 ) +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) +endif() install( TARGETS ${EXE_NAME} RUNTIME DESTINATION bin ) diff --git a/third_party/cgltf/test/main.c b/third_party/cgltf/test/main.c index a6050d6761..75543c19db 100644 --- a/third_party/cgltf/test/main.c +++ b/third_party/cgltf/test/main.c @@ -13,7 +13,8 @@ int main(int argc, char** argv) return -1; } - cgltf_options options = {0}; + cgltf_options options; + memset(&options, 0, sizeof(cgltf_options)); cgltf_data* data = NULL; cgltf_result result = cgltf_parse_file(&options, argv[1], &data); @@ -28,7 +29,7 @@ int main(int argc, char** argv) if (result == cgltf_result_success) { printf("Type: %u\n", data->file_type); - printf("Meshes: %lu\n", data->meshes_count); + printf("Meshes: %u\n", (unsigned)data->meshes_count); } cgltf_free(data); diff --git a/third_party/cgltf/test/test_conversion.cpp b/third_party/cgltf/test/test_conversion.cpp index 2566292e63..938a0ac83b 100644 --- a/third_party/cgltf/test/test_conversion.cpp +++ b/third_party/cgltf/test/test_conversion.cpp @@ -29,7 +29,7 @@ int main(int argc, char** argv) if (result != cgltf_result_success || strstr(argv[1], "Draco")) return result; - const cgltf_accessor* blobs = data->accessors; + //const cgltf_accessor* blobs = data->accessors; cgltf_float element_float[16]; cgltf_uint element_uint[4]; for (cgltf_size blob_index = 0; blob_index < data->accessors_count; ++blob_index) diff --git a/third_party/cgltf/test/test_math.cpp b/third_party/cgltf/test/test_math.cpp index 6de608341c..84f93052a7 100644 --- a/third_party/cgltf/test/test_math.cpp +++ b/third_party/cgltf/test/test_math.cpp @@ -22,7 +22,7 @@ static void check(cgltf_float target[3], float x, float y, float z) { } } -int main(int argc, char** argv) +int main(int, char**) { cgltf_node node = {};