Update cgltf.h

This commit is contained in:
Ray
2026-03-29 21:17:51 +02:00
parent d3cc78d9d7
commit a1bf8d9c75

211
src/external/cgltf.h vendored
View File

@@ -1,7 +1,7 @@
/**
* cgltf - a single-file glTF 2.0 parser written in C99.
*
* Version: 1.14
* Version: 1.15
*
* Website: https://github.com/jkuhlmann/cgltf
*
@@ -141,7 +141,7 @@ typedef struct cgltf_memory_options
typedef struct cgltf_file_options
{
cgltf_result(*read)(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, const char* path, cgltf_size* size, void** data);
void (*release)(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, void* data);
void (*release)(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, void* data, cgltf_size size);
void* user_data;
} cgltf_file_options;
@@ -296,6 +296,7 @@ typedef enum cgltf_meshopt_compression_filter {
cgltf_meshopt_compression_filter_octahedral,
cgltf_meshopt_compression_filter_quaternion,
cgltf_meshopt_compression_filter_exponential,
cgltf_meshopt_compression_filter_color,
cgltf_meshopt_compression_filter_max_enum
} cgltf_meshopt_compression_filter;
@@ -308,6 +309,7 @@ typedef struct cgltf_meshopt_compression
cgltf_size count;
cgltf_meshopt_compression_mode mode;
cgltf_meshopt_compression_filter filter;
cgltf_bool is_khr;
} cgltf_meshopt_compression;
typedef struct cgltf_buffer_view
@@ -376,13 +378,29 @@ typedef struct cgltf_image
cgltf_extension* extensions;
} cgltf_image;
typedef enum cgltf_filter_type {
cgltf_filter_type_undefined = 0,
cgltf_filter_type_nearest = 9728,
cgltf_filter_type_linear = 9729,
cgltf_filter_type_nearest_mipmap_nearest = 9984,
cgltf_filter_type_linear_mipmap_nearest = 9985,
cgltf_filter_type_nearest_mipmap_linear = 9986,
cgltf_filter_type_linear_mipmap_linear = 9987
} cgltf_filter_type;
typedef enum cgltf_wrap_mode {
cgltf_wrap_mode_clamp_to_edge = 33071,
cgltf_wrap_mode_mirrored_repeat = 33648,
cgltf_wrap_mode_repeat = 10497
} cgltf_wrap_mode;
typedef struct cgltf_sampler
{
char* name;
cgltf_int mag_filter;
cgltf_int min_filter;
cgltf_int wrap_s;
cgltf_int wrap_t;
cgltf_filter_type mag_filter;
cgltf_filter_type min_filter;
cgltf_wrap_mode wrap_s;
cgltf_wrap_mode wrap_t;
cgltf_extras extras;
cgltf_size extensions_count;
cgltf_extension* extensions;
@@ -500,6 +518,14 @@ typedef struct cgltf_iridescence
cgltf_texture_view iridescence_thickness_texture;
} cgltf_iridescence;
typedef struct cgltf_diffuse_transmission
{
cgltf_texture_view diffuse_transmission_texture;
cgltf_float diffuse_transmission_factor;
cgltf_float diffuse_transmission_color_factor[3];
cgltf_texture_view diffuse_transmission_color_texture;
} cgltf_diffuse_transmission;
typedef struct cgltf_anisotropy
{
cgltf_float anisotropy_strength;
@@ -525,6 +551,7 @@ typedef struct cgltf_material
cgltf_bool has_sheen;
cgltf_bool has_emissive_strength;
cgltf_bool has_iridescence;
cgltf_bool has_diffuse_transmission;
cgltf_bool has_anisotropy;
cgltf_bool has_dispersion;
cgltf_pbr_metallic_roughness pbr_metallic_roughness;
@@ -537,6 +564,7 @@ typedef struct cgltf_material
cgltf_volume volume;
cgltf_emissive_strength emissive_strength;
cgltf_iridescence iridescence;
cgltf_diffuse_transmission diffuse_transmission;
cgltf_anisotropy anisotropy;
cgltf_dispersion dispersion;
cgltf_texture_view normal_texture;
@@ -743,6 +771,7 @@ typedef struct cgltf_data
{
cgltf_file_type file_type;
void* file_data;
cgltf_size file_size;
cgltf_asset asset;
@@ -844,6 +873,8 @@ void cgltf_node_transform_world(const cgltf_node* node, cgltf_float* out_matrix)
const uint8_t* cgltf_buffer_view_data(const cgltf_buffer_view* view);
const cgltf_accessor* cgltf_find_accessor(const cgltf_primitive* prim, cgltf_attribute_type type, cgltf_int index);
cgltf_bool cgltf_accessor_read_float(const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size);
cgltf_bool cgltf_accessor_read_uint(const cgltf_accessor* accessor, cgltf_size index, cgltf_uint* out, cgltf_size element_size);
cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size index);
@@ -1071,9 +1102,10 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m
return cgltf_result_success;
}
static void cgltf_default_file_release(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, void* data)
static void cgltf_default_file_release(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, void* data, cgltf_size size)
{
(void)file_options;
(void)size;
void (*memfree)(void*, void*) = memory_options->free_func ? memory_options->free_func : &cgltf_default_free;
memfree(memory_options->user_data, data);
}
@@ -1220,7 +1252,7 @@ cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cg
}
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_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data, cgltf_size size) = options->file.release ? options->file.release : cgltf_default_file_release;
void* file_data = NULL;
cgltf_size file_size = 0;
@@ -1234,11 +1266,12 @@ cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cg
if (result != cgltf_result_success)
{
file_release(&options->memory, &options->file, file_data);
file_release(&options->memory, &options->file, file_data, file_size);
return result;
}
(*out_data)->file_data = file_data;
(*out_data)->file_size = file_size;
return cgltf_result_success;
}
@@ -1630,8 +1663,8 @@ cgltf_result cgltf_validate(cgltf_data* data)
CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->filter != cgltf_meshopt_compression_filter_none, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_color && mc->stride != 4 && mc->stride != 8, cgltf_result_invalid_gltf);
}
}
@@ -1822,7 +1855,7 @@ void cgltf_free(cgltf_data* data)
return;
}
void (*file_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data) = data->file.release ? data->file.release : cgltf_default_file_release;
void (*file_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data, cgltf_size size) = data->file.release ? data->file.release : cgltf_default_file_release;
data->memory.free_func(data->memory.user_data, data->asset.copyright);
data->memory.free_func(data->memory.user_data, data->asset.generator);
@@ -1857,7 +1890,7 @@ void cgltf_free(cgltf_data* data)
if (data->buffers[i].data_free_method == cgltf_data_free_method_file_release)
{
file_release(&data->memory, &data->file, data->buffers[i].data);
file_release(&data->memory, &data->file, data->buffers[i].data, data->buffers[i].size);
}
else if (data->buffers[i].data_free_method == cgltf_data_free_method_memory_free)
{
@@ -2096,7 +2129,7 @@ void cgltf_free(cgltf_data* data)
data->memory.free_func(data->memory.user_data, data->extensions_required);
file_release(&data->memory, &data->file, data->file_data);
file_release(&data->memory, &data->file, data->file_data, data->file_size);
data->memory.free_func(data->memory.user_data, data);
}
@@ -2312,11 +2345,58 @@ const uint8_t* cgltf_buffer_view_data(const cgltf_buffer_view* view)
return result;
}
const cgltf_accessor* cgltf_find_accessor(const cgltf_primitive* prim, cgltf_attribute_type type, cgltf_int index)
{
for (cgltf_size i = 0; i < prim->attributes_count; ++i)
{
const cgltf_attribute* attr = &prim->attributes[i];
if (attr->type == type && attr->index == index)
return attr->data;
}
return NULL;
}
static const uint8_t* cgltf_find_sparse_index(const cgltf_accessor* accessor, cgltf_size needle)
{
const cgltf_accessor_sparse* sparse = &accessor->sparse;
const uint8_t* index_data = cgltf_buffer_view_data(sparse->indices_buffer_view);
const uint8_t* value_data = cgltf_buffer_view_data(sparse->values_buffer_view);
if (index_data == NULL || value_data == NULL)
return NULL;
index_data += sparse->indices_byte_offset;
value_data += sparse->values_byte_offset;
cgltf_size index_stride = cgltf_component_size(sparse->indices_component_type);
cgltf_size offset = 0;
cgltf_size length = sparse->count;
while (length)
{
cgltf_size rem = length % 2;
length /= 2;
cgltf_size index = cgltf_component_read_index(index_data + (offset + length) * index_stride, sparse->indices_component_type);
offset += index < needle ? length + rem : 0;
}
if (offset == sparse->count)
return NULL;
cgltf_size index = cgltf_component_read_index(index_data + offset * index_stride, sparse->indices_component_type);
return index == needle ? value_data + offset * accessor->stride : NULL;
}
cgltf_bool cgltf_accessor_read_float(const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size)
{
if (accessor->is_sparse)
{
return 0;
const uint8_t* element = cgltf_find_sparse_index(accessor, index);
if (element)
return cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, out, element_size);
}
if (accessor->buffer_view == NULL)
{
@@ -2460,11 +2540,13 @@ cgltf_bool cgltf_accessor_read_uint(const cgltf_accessor* accessor, cgltf_size i
{
if (accessor->is_sparse)
{
return 0;
const uint8_t* element = cgltf_find_sparse_index(accessor, index);
if (element)
return cgltf_element_read_uint(element, accessor->type, accessor->component_type, out, element_size);
}
if (accessor->buffer_view == NULL)
{
memset(out, 0, element_size * sizeof( cgltf_uint ));
memset(out, 0, element_size * sizeof(cgltf_uint));
return 1;
}
const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
@@ -2480,7 +2562,9 @@ cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size
{
if (accessor->is_sparse)
{
return 0; // This is an error case, but we can't communicate the error with existing interface.
const uint8_t* element = cgltf_find_sparse_index(accessor, index);
if (element)
return cgltf_component_read_index(element, accessor->component_type);
}
if (accessor->buffer_view == NULL)
{
@@ -2598,7 +2682,10 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* o
return accessor->count;
}
index_count = accessor->count < index_count ? accessor->count : index_count;
cgltf_size numbers_per_element = cgltf_num_components(accessor->type);
cgltf_size available_numbers = accessor->count * numbers_per_element;
index_count = available_numbers < index_count ? available_numbers : index_count;
cgltf_size index_component_size = cgltf_component_size(accessor->component_type);
if (accessor->is_sparse)
@@ -2620,15 +2707,23 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* o
}
element += accessor->offset;
if (index_component_size == out_component_size && accessor->stride == out_component_size)
if (index_component_size == out_component_size && accessor->stride == out_component_size * numbers_per_element)
{
memcpy(out, element, index_count * index_component_size);
return index_count;
}
// Data couldn't be copied with memcpy due to stride being larger than the component size.
// OR
// The component size of the output array is larger than the component size of the index data, so index data will be padded.
switch (out_component_size)
{
case 1:
for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)
{
((uint8_t*)out)[index] = (uint8_t)cgltf_component_read_index(element, accessor->component_type);
}
break;
case 2:
for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)
{
@@ -2642,7 +2737,7 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* o
}
break;
default:
break;
return 0;
}
return index_count;
@@ -4278,6 +4373,52 @@ static int cgltf_parse_json_iridescence(cgltf_options* options, jsmntok_t const*
return i;
}
static int cgltf_parse_json_diffuse_transmission(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_diffuse_transmission* out_diff_transmission)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
int size = tokens[i].size;
++i;
// Defaults
cgltf_fill_float_array(out_diff_transmission->diffuse_transmission_color_factor, 3, 1.0f);
out_diff_transmission->diffuse_transmission_factor = 0.f;
for (int j = 0; j < size; ++j)
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionFactor") == 0)
{
++i;
out_diff_transmission->diffuse_transmission_factor = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionTexture") == 0)
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_diff_transmission->diffuse_transmission_texture);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionColorFactor") == 0)
{
i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_diff_transmission->diffuse_transmission_color_factor, 3);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionColorTexture") == 0)
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_diff_transmission->diffuse_transmission_color_texture);
}
else
{
i = cgltf_skip_json(tokens, i + 1);
}
if (i < 0)
{
return i;
}
}
return i;
}
static int cgltf_parse_json_anisotropy(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_anisotropy* out_anisotropy)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@@ -4406,8 +4547,8 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok
(void)options;
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
out_sampler->wrap_s = 10497;
out_sampler->wrap_t = 10497;
out_sampler->wrap_s = cgltf_wrap_mode_repeat;
out_sampler->wrap_t = cgltf_wrap_mode_repeat;
int size = tokens[i].size;
++i;
@@ -4424,28 +4565,28 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok
{
++i;
out_sampler->mag_filter
= cgltf_json_to_int(tokens + i, json_chunk);
= (cgltf_filter_type)cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "minFilter") == 0)
{
++i;
out_sampler->min_filter
= cgltf_json_to_int(tokens + i, json_chunk);
= (cgltf_filter_type)cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapS") == 0)
{
++i;
out_sampler->wrap_s
= cgltf_json_to_int(tokens + i, json_chunk);
= (cgltf_wrap_mode)cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0)
{
++i;
out_sampler->wrap_t
= cgltf_json_to_int(tokens + i, json_chunk);
= (cgltf_wrap_mode)cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
@@ -4766,6 +4907,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to
out_material->has_iridescence = 1;
i = cgltf_parse_json_iridescence(options, tokens, i + 1, json_chunk, &out_material->iridescence);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_diffuse_transmission") == 0)
{
out_material->has_diffuse_transmission = 1;
i = cgltf_parse_json_diffuse_transmission(options, tokens, i + 1, json_chunk, &out_material->diffuse_transmission);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_anisotropy") == 0)
{
out_material->has_anisotropy = 1;
@@ -4974,6 +5120,10 @@ static int cgltf_parse_json_meshopt_compression(cgltf_options* options, jsmntok_
{
out_meshopt_compression->filter = cgltf_meshopt_compression_filter_exponential;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "COLOR") == 0)
{
out_meshopt_compression->filter = cgltf_meshopt_compression_filter_color;
}
++i;
}
else
@@ -5084,6 +5234,12 @@ static int cgltf_parse_json_buffer_view(cgltf_options* options, jsmntok_t const*
out_buffer_view->has_meshopt_compression = 1;
i = cgltf_parse_json_meshopt_compression(options, tokens, i + 1, json_chunk, &out_buffer_view->meshopt_compression);
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_meshopt_compression") == 0)
{
out_buffer_view->has_meshopt_compression = 1;
out_buffer_view->meshopt_compression.is_khr = 1;
i = cgltf_parse_json_meshopt_compression(options, tokens, i + 1, json_chunk, &out_buffer_view->meshopt_compression);
}
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_buffer_view->extensions[out_buffer_view->extensions_count++]));
@@ -6629,6 +6785,9 @@ static int cgltf_fixup_pointers(cgltf_data* data)
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);
CGLTF_PTRFIXUP(data->materials[i].diffuse_transmission.diffuse_transmission_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].diffuse_transmission.diffuse_transmission_color_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].anisotropy.anisotropy_texture.texture, data->textures, data->textures_count);
}