diff --git a/3rdparty/cgltf/cgltf.h b/3rdparty/cgltf/cgltf.h index ee1ac1f3f..f69ad7716 100644 --- a/3rdparty/cgltf/cgltf.h +++ b/3rdparty/cgltf/cgltf.h @@ -479,6 +479,16 @@ typedef struct cgltf_emissive_strength cgltf_float emissive_strength; } cgltf_emissive_strength; +typedef struct cgltf_iridescence +{ + cgltf_float iridescence_factor; + cgltf_texture_view iridescence_texture; + cgltf_float iridescence_ior; + cgltf_float iridescence_thickness_min; + cgltf_float iridescence_thickness_max; + cgltf_texture_view iridescence_thickness_texture; +} cgltf_iridescence; + typedef struct cgltf_material { char* name; @@ -491,6 +501,7 @@ typedef struct cgltf_material cgltf_bool has_specular; cgltf_bool has_sheen; cgltf_bool has_emissive_strength; + cgltf_bool has_iridescence; cgltf_pbr_metallic_roughness pbr_metallic_roughness; cgltf_pbr_specular_glossiness pbr_specular_glossiness; cgltf_clearcoat clearcoat; @@ -500,6 +511,7 @@ typedef struct cgltf_material cgltf_transmission transmission; cgltf_volume volume; cgltf_emissive_strength emissive_strength; + cgltf_iridescence iridescence; cgltf_texture_view normal_texture; cgltf_texture_view occlusion_texture; cgltf_texture_view emissive_texture; @@ -531,6 +543,12 @@ typedef struct cgltf_draco_mesh_compression { cgltf_size attributes_count; } cgltf_draco_mesh_compression; +typedef struct cgltf_mesh_gpu_instancing { + cgltf_buffer_view* buffer_view; + cgltf_attribute* attributes; + cgltf_size attributes_count; +} cgltf_mesh_gpu_instancing; + typedef struct cgltf_primitive { cgltf_primitive_type type; cgltf_accessor* indices; @@ -635,6 +653,8 @@ struct cgltf_node { cgltf_float scale[3]; cgltf_float matrix[16]; cgltf_extras extras; + cgltf_bool has_mesh_gpu_instancing; + cgltf_mesh_gpu_instancing mesh_gpu_instancing; cgltf_size extensions_count; cgltf_extension* extensions; }; @@ -1866,6 +1886,11 @@ void cgltf_free(cgltf_data* data) 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_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_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); @@ -2725,6 +2750,37 @@ static int cgltf_parse_json_draco_mesh_compression(cgltf_options* options, jsmnt return i; } +static int cgltf_parse_json_mesh_gpu_instancing(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_mesh_gpu_instancing* out_mesh_gpu_instancing) +{ + 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_mesh_gpu_instancing->attributes, &out_mesh_gpu_instancing->attributes_count); + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "bufferView") == 0) + { + ++i; + out_mesh_gpu_instancing->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk)); + ++i; + } + + if (i < 0) + { + return i; + } + } + + return i; +} + static int cgltf_parse_json_material_mapping_data(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_material_mapping* out_mappings, cgltf_size* offset) { (void)options; @@ -3884,6 +3940,67 @@ static int cgltf_parse_json_emissive_strength(jsmntok_t const* tokens, int i, co return i; } +static int cgltf_parse_json_iridescence(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_iridescence* out_iridescence) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i].size; + ++i; + + // Default + out_iridescence->iridescence_ior = 1.3f; + out_iridescence->iridescence_thickness_min = 100.f; + out_iridescence->iridescence_thickness_max = 400.f; + + for (int j = 0; j < size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceFactor") == 0) + { + ++i; + out_iridescence->iridescence_factor = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceTexture") == 0) + { + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_iridescence->iridescence_texture); + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceIor") == 0) + { + ++i; + out_iridescence->iridescence_ior = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceThicknessMinimum") == 0) + { + ++i; + out_iridescence->iridescence_thickness_min = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceThicknessMaximum") == 0) + { + ++i; + out_iridescence->iridescence_thickness_max = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "iridescenceThicknessTexture") == 0) + { + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_iridescence->iridescence_thickness_texture); + } + else + { + i = cgltf_skip_json(tokens, i + 1); + } + + if (i < 0) + { + return i; + } + } + + return i; +} + static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_image* out_image) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -4081,6 +4198,10 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok { i = cgltf_skip_json(tokens, i + 1); } + if (i < 0) + { + return i; + } } } else @@ -4263,6 +4384,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to out_material->has_emissive_strength = 1; i = cgltf_parse_json_emissive_strength(tokens, i + 1, json_chunk, &out_material->emissive_strength); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_iridescence") == 0) + { + out_material->has_iridescence = 1; + i = cgltf_parse_json_iridescence(options, tokens, i + 1, json_chunk, &out_material->iridescence); + } else { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++])); @@ -5223,6 +5349,11 @@ static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens } } } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "EXT_mesh_gpu_instancing") == 0) + { + 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 { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_node->extensions[out_node->extensions_count++])); @@ -6109,6 +6240,9 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP(data->materials[i].sheen.sheen_color_texture.texture, data->textures, data->textures_count); CGLTF_PTRFIXUP(data->materials[i].sheen.sheen_roughness_texture.texture, data->textures, data->textures_count); + + CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_texture.texture, data->textures, data->textures_count); + CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_thickness_texture.texture, data->textures, data->textures_count); } for (cgltf_size i = 0; i < data->buffer_views_count; ++i) @@ -6150,6 +6284,15 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP(data->nodes[i].skin, data->skins, data->skins_count); CGLTF_PTRFIXUP(data->nodes[i].camera, data->cameras, data->cameras_count); CGLTF_PTRFIXUP(data->nodes[i].light, data->lights, data->lights_count); + + if (data->nodes[i].has_mesh_gpu_instancing) + { + CGLTF_PTRFIXUP_REQ(data->nodes[i].mesh_gpu_instancing.buffer_view, data->buffer_views, data->buffer_views_count); + for (cgltf_size m = 0; m < data->nodes[i].mesh_gpu_instancing.attributes_count; ++m) + { + CGLTF_PTRFIXUP_REQ(data->nodes[i].mesh_gpu_instancing.attributes[m].data, data->accessors, data->accessors_count); + } + } } for (cgltf_size i = 0; i < data->scenes_count; ++i) diff --git a/3rdparty/cgltf/cgltf_write.h b/3rdparty/cgltf/cgltf_write.h index 430f693b2..dc4ab87f7 100644 --- a/3rdparty/cgltf/cgltf_write.h +++ b/3rdparty/cgltf/cgltf_write.h @@ -85,6 +85,8 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si #define CGLTF_EXTENSION_FLAG_MATERIALS_VOLUME (1 << 11) #define CGLTF_EXTENSION_FLAG_TEXTURE_BASISU (1 << 12) #define CGLTF_EXTENSION_FLAG_MATERIALS_EMISSIVE_STRENGTH (1 << 13) +#define CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING (1 << 14) +#define CGLTF_EXTENSION_FLAG_MATERIALS_IRIDESCENCE (1 << 15) typedef struct { char* buffer; @@ -509,6 +511,7 @@ static void cgltf_write_mesh(cgltf_write_context* context, const cgltf_mesh* mes { cgltf_write_floatarrayprop(context, "weights", mesh->weights, mesh->weights_count); } + cgltf_write_extras(context, &mesh->extras); cgltf_write_line(context, "}"); } @@ -545,7 +548,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater { 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, "doubleSided", (bool)material->double_sided, false); // cgltf_write_boolprop_optional(context, "unlit", material->unlit, false); if (material->unlit) @@ -593,6 +596,11 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater context->extension_flags |= CGLTF_EXTENSION_FLAG_MATERIALS_EMISSIVE_STRENGTH; } + if (material->has_iridescence) + { + context->extension_flags |= CGLTF_EXTENSION_FLAG_MATERIALS_IRIDESCENCE; + } + if (material->has_pbr_metallic_roughness) { const cgltf_pbr_metallic_roughness* params = &material->pbr_metallic_roughness; @@ -609,7 +617,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) + 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) { cgltf_write_line(context, "\"extensions\": {"); if (material->has_clearcoat) @@ -708,6 +716,18 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater cgltf_write_floatprop(context, "emissiveStrength", params->emissive_strength, 1.f); cgltf_write_line(context, "}"); } + if (material->has_iridescence) + { + cgltf_write_line(context, "\"KHR_materials_iridescence\": {"); + const cgltf_iridescence* params = &material->iridescence; + cgltf_write_floatprop(context, "iridescenceFactor", params->iridescence_factor, 0.f); + CGLTF_WRITE_TEXTURE_INFO("iridescenceTexture", params->iridescence_texture); + cgltf_write_floatprop(context, "iridescenceIor", params->iridescence_ior, 1.3f); + cgltf_write_floatprop(context, "iridescenceThicknessMinimum", params->iridescence_thickness_min, 100.f); + cgltf_write_floatprop(context, "iridescenceThicknessMaximum", params->iridescence_thickness_max, 400.f); + CGLTF_WRITE_TEXTURE_INFO("iridescenceThicknessTexture", params->iridescence_thickness_texture); + cgltf_write_line(context, "}"); + } cgltf_write_line(context, "}"); } @@ -897,16 +917,42 @@ 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); + if(has_extension) + cgltf_write_line(context, "\"extensions\": {"); + if (node->light) { context->extension_flags |= CGLTF_EXTENSION_FLAG_LIGHTS_PUNCTUAL; - cgltf_write_line(context, "\"extensions\": {"); cgltf_write_line(context, "\"KHR_lights_punctual\": {"); CGLTF_WRITE_IDXPROP("light", node->light, context->data->lights); cgltf_write_line(context, "}"); + } + + if (node->has_mesh_gpu_instancing && node->mesh_gpu_instancing.attributes_count > 0) + { + context->extension_flags |= CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING; + context->required_extension_flags |= CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING; + + cgltf_write_line(context, "\"EXT_mesh_gpu_instancing\": {"); + { + CGLTF_WRITE_IDXPROP("bufferView", node->mesh_gpu_instancing.buffer_view, context->data->buffer_views); + cgltf_write_line(context, "\"attributes\": {"); + { + for (cgltf_size i = 0; i < node->mesh_gpu_instancing.attributes_count; ++i) + { + const cgltf_attribute* attr = node->mesh_gpu_instancing.attributes + i; + CGLTF_WRITE_IDXPROP(attr->name, attr->data, context->data->accessors); + } + } + cgltf_write_line(context, "}"); + } cgltf_write_line(context, "}"); } + if (has_extension) + cgltf_write_line(context, "}"); + if (node->weights_count > 0) { cgltf_write_floatarrayprop(context, "weights", node->weights, node->weights_count); @@ -938,7 +984,7 @@ static void cgltf_write_accessor(cgltf_write_context* context, const cgltf_acces cgltf_write_intprop(context, "componentType", cgltf_int_from_component_type(accessor->component_type), 0); 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_boolprop_optional(context, "normalized", (bool)accessor->normalized, false); cgltf_write_sizeprop(context, "byteOffset", (int)accessor->offset, 0); cgltf_write_intprop(context, "count", (int)accessor->count, -1); if (accessor->has_min) @@ -1113,6 +1159,12 @@ static void cgltf_write_extensions(cgltf_write_context* context, uint32_t extens if (extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_EMISSIVE_STRENGTH) { cgltf_write_stritem(context, "KHR_materials_emissive_strength"); } + if (extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_IRIDESCENCE) { + cgltf_write_stritem(context, "KHR_materials_iridescence"); + } + if (extension_flags & CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING) { + cgltf_write_stritem(context, "EXT_mesh_gpu_instancing"); + } } cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size size, const cgltf_data* data)