summaryrefslogtreecommitdiffhomepage
path: root/src/external/cgltf.h
diff options
context:
space:
mode:
authorRay <[email protected]>2021-04-14 21:06:00 +0200
committerRay <[email protected]>2021-04-14 21:06:00 +0200
commit37f523fdeb6b3bfa60a84aa0014903a4925da671 (patch)
treeeb650585c749c27ab9b7af98e284df0452f93d27 /src/external/cgltf.h
parent646f1f06c45a2b9c81c6853adf31766041eb24ea (diff)
downloadraylib-37f523fdeb6b3bfa60a84aa0014903a4925da671.tar.gz
raylib-37f523fdeb6b3bfa60a84aa0014903a4925da671.zip
Update external libraries
Diffstat (limited to 'src/external/cgltf.h')
-rw-r--r--src/external/cgltf.h527
1 files changed, 406 insertions, 121 deletions
diff --git a/src/external/cgltf.h b/src/external/cgltf.h
index 41b75da0..4cc2d7ec 100644
--- a/src/external/cgltf.h
+++ b/src/external/cgltf.h
@@ -1,7 +1,7 @@
/**
* cgltf - a single-file glTF 2.0 parser written in C99.
*
- * Version: 1.8
+ * Version: 1.10
*
* Website: https://github.com/jkuhlmann/cgltf
*
@@ -24,7 +24,7 @@
*
* `cgltf_options` is the struct passed to `cgltf_parse()` to control
* parts of the parsing process. You can use it to force the file type
- * and provide memory allocation as well as file operation callbacks.
+ * and provide memory allocation as well as file operation callbacks.
* Should be zero-initialized to trigger default behavior.
*
* `cgltf_data` is the struct allocated and filled by `cgltf_parse()`.
@@ -42,8 +42,8 @@
*
* `cgltf_result cgltf_load_buffer_base64(const cgltf_options* options,
* cgltf_size size, const char* base64, void** out_data)` decodes
- * base64-encoded data content. Used internally by `cgltf_load_buffers()`
- * and may be useful if you're not dealing with normal files.
+ * base64-encoded data content. Used internally by `cgltf_load_buffers()`.
+ * This is useful when decoding data URIs in images.
*
* `cgltf_result cgltf_parse_file(const cgltf_options* options, const
* char* path, cgltf_data** out_data)` can be used to open the given
@@ -246,6 +246,7 @@ typedef struct cgltf_extension {
typedef struct cgltf_buffer
{
+ char* name;
cgltf_size size;
char* uri;
void* data; /* loaded by cgltf_load_buffers */
@@ -281,6 +282,7 @@ typedef struct cgltf_meshopt_compression
typedef struct cgltf_buffer_view
{
+ char *name;
cgltf_buffer* buffer;
cgltf_size offset;
cgltf_size size;
@@ -315,6 +317,7 @@ typedef struct cgltf_accessor_sparse
typedef struct cgltf_accessor
{
+ char* name;
cgltf_component_type component_type;
cgltf_bool normalized;
cgltf_type type;
@@ -354,6 +357,7 @@ typedef struct cgltf_image
typedef struct cgltf_sampler
{
+ char* name;
cgltf_int mag_filter;
cgltf_int min_filter;
cgltf_int wrap_s;
@@ -439,10 +443,19 @@ typedef struct cgltf_ior
typedef struct cgltf_specular
{
cgltf_texture_view specular_texture;
+ cgltf_texture_view specular_color_texture;
cgltf_float specular_color_factor[3];
cgltf_float specular_factor;
} cgltf_specular;
+typedef struct cgltf_volume
+{
+ cgltf_texture_view thickness_texture;
+ cgltf_float thickness_factor;
+ cgltf_float attenuation_color[3];
+ cgltf_float attenuation_distance;
+} cgltf_volume;
+
typedef struct cgltf_sheen
{
cgltf_texture_view sheen_color_texture;
@@ -458,6 +471,7 @@ typedef struct cgltf_material
cgltf_bool has_pbr_specular_glossiness;
cgltf_bool has_clearcoat;
cgltf_bool has_transmission;
+ cgltf_bool has_volume;
cgltf_bool has_ior;
cgltf_bool has_specular;
cgltf_bool has_sheen;
@@ -468,6 +482,7 @@ typedef struct cgltf_material
cgltf_specular specular;
cgltf_sheen sheen;
cgltf_transmission transmission;
+ cgltf_volume volume;
cgltf_texture_view normal_texture;
cgltf_texture_view occlusion_texture;
cgltf_texture_view emissive_texture;
@@ -481,6 +496,13 @@ typedef struct cgltf_material
cgltf_extension* extensions;
} cgltf_material;
+typedef struct cgltf_material_mapping
+{
+ cgltf_size variant;
+ cgltf_material* material;
+ cgltf_extras extras;
+} cgltf_material_mapping;
+
typedef struct cgltf_morph_target {
cgltf_attribute* attributes;
cgltf_size attributes_count;
@@ -503,6 +525,8 @@ typedef struct cgltf_primitive {
cgltf_extras extras;
cgltf_bool has_draco_mesh_compression;
cgltf_draco_mesh_compression draco_mesh_compression;
+ cgltf_material_mapping* mappings;
+ cgltf_size mappings_count;
cgltf_size extensions_count;
cgltf_extension* extensions;
} cgltf_primitive;
@@ -534,8 +558,10 @@ typedef struct cgltf_skin {
} cgltf_skin;
typedef struct cgltf_camera_perspective {
+ cgltf_bool has_aspect_ratio;
cgltf_float aspect_ratio;
cgltf_float yfov;
+ cgltf_bool has_zfar;
cgltf_float zfar;
cgltf_float znear;
cgltf_extras extras;
@@ -633,6 +659,12 @@ typedef struct cgltf_animation {
cgltf_extension* extensions;
} cgltf_animation;
+typedef struct cgltf_material_variant
+{
+ char* name;
+ cgltf_extras extras;
+} cgltf_material_variant;
+
typedef struct cgltf_asset {
char* copyright;
char* generator;
@@ -694,6 +726,9 @@ typedef struct cgltf_data
cgltf_animation* animations;
cgltf_size animations_count;
+ cgltf_material_variant* variants;
+ cgltf_size variants_count;
+
cgltf_extras extras;
cgltf_size data_extensions_count;
@@ -776,6 +811,7 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras*
#include <string.h> /* For strncpy */
#include <stdio.h> /* For fopen */
#include <limits.h> /* For UINT_MAX etc */
+#include <float.h> /* For FLT_MAX */
#if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF)
#include <stdlib.h> /* For malloc, free, atoi, atof */
@@ -847,6 +883,9 @@ static const uint32_t GlbMagicBinChunk = 0x004E4942;
#ifndef CGLTF_ATOF
#define CGLTF_ATOF(str) atof(str)
#endif
+#ifndef CGLTF_VALIDATE_ENABLE_ASSERTS
+#define CGLTF_VALIDATE_ENABLE_ASSERTS 0
+#endif
static void* cgltf_default_alloc(void* user, cgltf_size size)
{
@@ -1344,6 +1383,12 @@ static cgltf_size cgltf_calc_index_bound(cgltf_buffer_view* buffer_view, cgltf_s
return bound;
}
+#if CGLTF_VALIDATE_ENABLE_ASSERTS
+#define CGLTF_ASSERT_IF(cond, result) assert(!(cond)); if (cond) return result;
+#else
+#define CGLTF_ASSERT_IF(cond, result) if (cond) return result;
+#endif
+
cgltf_result cgltf_validate(cgltf_data* data)
{
for (cgltf_size i = 0; i < data->accessors_count; ++i)
@@ -1356,10 +1401,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
cgltf_size req_size = accessor->offset + accessor->stride * (accessor->count - 1) + element_size;
- if (accessor->buffer_view->size < req_size)
- {
- return cgltf_result_data_too_short;
- }
+ CGLTF_ASSERT_IF(accessor->buffer_view->size < req_size, cgltf_result_data_too_short);
}
if (accessor->is_sparse)
@@ -1370,27 +1412,18 @@ cgltf_result cgltf_validate(cgltf_data* data)
cgltf_size indices_req_size = sparse->indices_byte_offset + indices_component_size * sparse->count;
cgltf_size values_req_size = sparse->values_byte_offset + element_size * sparse->count;
- if (sparse->indices_buffer_view->size < indices_req_size ||
- sparse->values_buffer_view->size < values_req_size)
- {
- return cgltf_result_data_too_short;
- }
+ CGLTF_ASSERT_IF(sparse->indices_buffer_view->size < indices_req_size ||
+ sparse->values_buffer_view->size < values_req_size, cgltf_result_data_too_short);
- if (sparse->indices_component_type != cgltf_component_type_r_8u &&
- sparse->indices_component_type != cgltf_component_type_r_16u &&
- sparse->indices_component_type != cgltf_component_type_r_32u)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(sparse->indices_component_type != cgltf_component_type_r_8u &&
+ sparse->indices_component_type != cgltf_component_type_r_16u &&
+ sparse->indices_component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
if (sparse->indices_buffer_view->buffer->data)
{
cgltf_size index_bound = cgltf_calc_index_bound(sparse->indices_buffer_view, sparse->indices_byte_offset, sparse->indices_component_type, sparse->count);
- if (index_bound >= accessor->count)
- {
- return cgltf_result_data_too_short;
- }
+ CGLTF_ASSERT_IF(index_bound >= accessor->count, cgltf_result_data_too_short);
}
}
}
@@ -1399,64 +1432,31 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
cgltf_size req_size = data->buffer_views[i].offset + data->buffer_views[i].size;
- if (data->buffer_views[i].buffer && data->buffer_views[i].buffer->size < req_size)
- {
- return cgltf_result_data_too_short;
- }
+ CGLTF_ASSERT_IF(data->buffer_views[i].buffer && data->buffer_views[i].buffer->size < req_size, cgltf_result_data_too_short);
if (data->buffer_views[i].has_meshopt_compression)
{
cgltf_meshopt_compression* mc = &data->buffer_views[i].meshopt_compression;
- if (mc->buffer == NULL || mc->buffer->size < mc->offset + mc->size)
- {
- return cgltf_result_data_too_short;
- }
+ CGLTF_ASSERT_IF(mc->buffer == NULL || mc->buffer->size < mc->offset + mc->size, cgltf_result_data_too_short);
- if (data->buffer_views[i].stride && mc->stride != data->buffer_views[i].stride)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(data->buffer_views[i].stride && mc->stride != data->buffer_views[i].stride, cgltf_result_invalid_gltf);
- if (data->buffer_views[i].size != mc->stride * mc->count)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(data->buffer_views[i].size != mc->stride * mc->count, cgltf_result_invalid_gltf);
- if (mc->mode == cgltf_meshopt_compression_mode_invalid)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_invalid, cgltf_result_invalid_gltf);
- if (mc->mode == cgltf_meshopt_compression_mode_attributes && !(mc->stride % 4 == 0 && mc->stride <= 256))
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_attributes && !(mc->stride % 4 == 0 && mc->stride <= 256), cgltf_result_invalid_gltf);
- if (mc->mode == cgltf_meshopt_compression_mode_triangles && mc->count % 3 != 0)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_triangles && mc->count % 3 != 0, cgltf_result_invalid_gltf);
- if ((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->stride != 2 && mc->stride != 4)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->stride != 2 && mc->stride != 4, cgltf_result_invalid_gltf);
- if ((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->filter != cgltf_meshopt_compression_filter_none)
- {
- return cgltf_result_invalid_gltf;
- }
+ 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);
- if (mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8, cgltf_result_invalid_gltf);
- if (mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8, cgltf_result_invalid_gltf);
}
}
@@ -1464,26 +1464,17 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
if (data->meshes[i].weights)
{
- if (data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].weights_count)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].weights_count, cgltf_result_invalid_gltf);
}
if (data->meshes[i].target_names)
{
- if (data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].target_names_count)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].target_names_count, cgltf_result_invalid_gltf);
}
for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
{
- if (data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count, cgltf_result_invalid_gltf);
if (data->meshes[i].primitives[j].attributes_count)
{
@@ -1491,41 +1482,34 @@ cgltf_result cgltf_validate(cgltf_data* data)
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
{
- if (data->meshes[i].primitives[j].attributes[k].data->count != first->count)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
}
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
{
for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
{
- if (data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf);
}
}
cgltf_accessor* indices = data->meshes[i].primitives[j].indices;
- if (indices &&
+ CGLTF_ASSERT_IF(indices &&
indices->component_type != cgltf_component_type_r_8u &&
indices->component_type != cgltf_component_type_r_16u &&
- indices->component_type != cgltf_component_type_r_32u)
- {
- return cgltf_result_invalid_gltf;
- }
+ indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
if (indices && indices->buffer_view && indices->buffer_view->buffer->data)
{
cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count);
- if (index_bound >= first->count)
- {
- return cgltf_result_data_too_short;
- }
+ CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short);
+ }
+
+ for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
+ {
+ CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf);
}
}
}
@@ -1535,10 +1519,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
if (data->nodes[i].weights && data->nodes[i].mesh)
{
- if (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf);
}
}
@@ -1549,10 +1530,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
while (p1 && p2)
{
- if (p1 == p2)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(p1 == p2, cgltf_result_invalid_gltf);
p1 = p1->parent;
p2 = p2->parent ? p2->parent->parent : NULL;
@@ -1563,10 +1541,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
for (cgltf_size j = 0; j < data->scenes[i].nodes_count; ++j)
{
- if (data->scenes[i].nodes[j]->parent)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(data->scenes[i].nodes[j]->parent, cgltf_result_invalid_gltf);
}
}
@@ -1585,20 +1560,14 @@ cgltf_result cgltf_validate(cgltf_data* data)
if (channel->target_path == cgltf_animation_path_type_weights)
{
- if (!channel->target_node->mesh || !channel->target_node->mesh->primitives_count)
- {
- return cgltf_result_invalid_gltf;
- }
+ CGLTF_ASSERT_IF(!channel->target_node->mesh || !channel->target_node->mesh->primitives_count, cgltf_result_invalid_gltf);
components = channel->target_node->mesh->primitives[0].targets_count;
}
cgltf_size values = channel->sampler->interpolation == cgltf_interpolation_type_cubic_spline ? 3 : 1;
- if (channel->sampler->input->count * components * values != channel->sampler->output->count)
- {
- return cgltf_result_data_too_short;
- }
+ CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_data_too_short);
}
}
@@ -1661,6 +1630,8 @@ void cgltf_free(cgltf_data* data)
for (cgltf_size i = 0; i < data->accessors_count; ++i)
{
+ data->memory.free(data->memory.user_data, data->accessors[i].name);
+
if(data->accessors[i].is_sparse)
{
cgltf_free_extensions(data, data->accessors[i].sparse.extensions, data->accessors[i].sparse.extensions_count);
@@ -1673,6 +1644,7 @@ void cgltf_free(cgltf_data* data)
for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
{
+ data->memory.free(data->memory.user_data, data->buffer_views[i].name);
data->memory.free(data->memory.user_data, data->buffer_views[i].data);
cgltf_free_extensions(data, data->buffer_views[i].extensions, data->buffer_views[i].extensions_count);
@@ -1681,6 +1653,8 @@ void cgltf_free(cgltf_data* data)
for (cgltf_size i = 0; i < data->buffers_count; ++i)
{
+ data->memory.free(data->memory.user_data, data->buffers[i].name);
+
if (data->buffers[i].data != data->bin)
{
file_release(&data->memory, &data->file, data->buffers[i].data);
@@ -1727,6 +1701,8 @@ void cgltf_free(cgltf_data* data)
data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes);
}
+ data->memory.free(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);
}
@@ -1768,11 +1744,16 @@ void cgltf_free(cgltf_data* data)
if(data->materials[i].has_specular)
{
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_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_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_extensions(data, data->materials[i].sheen.sheen_color_texture.extensions, data->materials[i].sheen.sheen_color_texture.extensions_count);
@@ -1809,6 +1790,7 @@ void cgltf_free(cgltf_data* data)
for (cgltf_size i = 0; i < data->samplers_count; ++i)
{
+ data->memory.free(data->memory.user_data, data->samplers[i].name);
cgltf_free_extensions(data, data->samplers[i].extensions, data->samplers[i].extensions_count);
}
@@ -1879,6 +1861,13 @@ void cgltf_free(cgltf_data* data)
data->memory.free(data->memory.user_data, data->animations);
+ for (cgltf_size i = 0; i < data->variants_count; ++i)
+ {
+ data->memory.free(data->memory.user_data, data->variants[i].name);
+ }
+
+ data->memory.free(data->memory.user_data, data->variants);
+
cgltf_free_extensions(data, data->data_extensions, data->data_extensions_count);
for (cgltf_size i = 0; i < data->extensions_used_count; ++i)
@@ -2608,6 +2597,136 @@ static int cgltf_parse_json_draco_mesh_compression(cgltf_options* options, jsmnt
out_draco_mesh_compression->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;
+ CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
+
+ int size = tokens[i].size;
+ ++i;
+
+ for (int j = 0; j < size; ++j)
+ {
+ CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
+
+ int obj_size = tokens[i].size;
+ ++i;
+
+ int material = -1;
+ int variants_tok = -1;
+ cgltf_extras extras = {0, 0};
+
+ for (int k = 0; k < obj_size; ++k)
+ {
+ CGLTF_CHECK_KEY(tokens[i]);
+
+ if (cgltf_json_strcmp(tokens + i, json_chunk, "material") == 0)
+ {
+ ++i;
+ material = cgltf_json_to_int(tokens + i, json_chunk);
+ ++i;
+ }
+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "variants") == 0)
+ {
+ variants_tok = i+1;
+ CGLTF_CHECK_TOKTYPE(tokens[variants_tok], JSMN_ARRAY);
+
+ i = cgltf_skip_json(tokens, i+1);
+ }
+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
+ {
+ i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &extras);
+ }
+ else
+ {
+ i = cgltf_skip_json(tokens, i+1);
+ }
+
+ if (i < 0)
+ {
+ return i;
+ }
+ }
+
+ if (material < 0 || variants_tok < 0)
+ {
+ return CGLTF_ERROR_JSON;
+ }
+
+ if (out_mappings)
+ {
+ for (int k = 0; k < tokens[variants_tok].size; ++k)
+ {
+ int variant = cgltf_json_to_int(&tokens[variants_tok + 1 + k], json_chunk);
+ if (variant < 0)
+ return variant;
+
+ out_mappings[*offset].material = CGLTF_PTRINDEX(cgltf_material, material);
+ out_mappings[*offset].variant = variant;
+ out_mappings[*offset].extras = extras;
+
+ (*offset)++;
+ }
+ }
+ else
+ {
+ (*offset) += tokens[variants_tok].size;
+ }
+ }
+
+ return i;
+}
+
+static int cgltf_parse_json_material_mappings(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);
+
+ 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, "mappings") == 0)
+ {
+ if (out_prim->mappings)
+ {
+ return CGLTF_ERROR_JSON;
+ }
+
+ cgltf_size mappings_offset = 0;
+ int k = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, NULL, &mappings_offset);
+ if (k < 0)
+ {
+ return k;
+ }
+
+ out_prim->mappings_count = mappings_offset;
+ out_prim->mappings = (cgltf_material_mapping*)cgltf_calloc(options, sizeof(cgltf_material_mapping), out_prim->mappings_count);
+
+ mappings_offset = 0;
+ i = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, out_prim->mappings, &mappings_offset);
+ }
+ else
+ {
+ i = cgltf_skip_json(tokens, i+1);
+ }
+
+ if (i < 0)
+ {
+ return i;
+ }
}
return i;
@@ -2700,6 +2819,10 @@ static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* t
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 if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_variants") == 0)
+ {
+ i = cgltf_parse_json_material_mappings(options, tokens, i + 1, json_chunk, out_prim);
+ }
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_prim->extensions[out_prim->extensions_count++]));
@@ -2783,7 +2906,7 @@ static int cgltf_parse_json_mesh(cgltf_options* options, jsmntok_t const* tokens
{
CGLTF_CHECK_KEY(tokens[i]);
- if (cgltf_json_strcmp(tokens+i, json_chunk, "targetNames") == 0)
+ if (cgltf_json_strcmp(tokens+i, json_chunk, "targetNames") == 0 && tokens[i+1].type == JSMN_ARRAY)
{
i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_mesh->target_names, &out_mesh->target_names_count);
}
@@ -3005,7 +3128,11 @@ static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* to
{
CGLTF_CHECK_KEY(tokens[i]);
- if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
+ if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
+ {
+ i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_accessor->name);
+ }
+ else if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
{
++i;
out_accessor->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
@@ -3467,6 +3594,10 @@ static int cgltf_parse_json_specular(cgltf_options* options, jsmntok_t const* to
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_texture);
}
+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "specularColorTexture") == 0)
+ {
+ i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_color_texture);
+ }
else
{
i = cgltf_skip_json(tokens, i+1);
@@ -3515,6 +3646,50 @@ static int cgltf_parse_json_transmission(cgltf_options* options, jsmntok_t const
return i;
}
+static int cgltf_parse_json_volume(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_volume* out_volume)
+{
+ 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, "thicknessFactor") == 0)
+ {
+ ++i;
+ out_volume->thickness_factor = cgltf_json_to_float(tokens + i, json_chunk);
+ ++i;
+ }
+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "thicknessTexture") == 0)
+ {
+ i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_volume->thickness_texture);
+ }
+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "attenuationColor") == 0)
+ {
+ i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_volume->attenuation_color, 3);
+ }
+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "attenuationDistance") == 0)
+ {
+ ++i;
+ out_volume->attenuation_distance = cgltf_json_to_float(tokens + i, json_chunk);
+ ++i;
+ }
+ else
+ {
+ i = cgltf_skip_json(tokens, i + 1);
+ }
+
+ if (i < 0)
+ {
+ return i;
+ }
+ }
+
+ return i;
+}
+
static int cgltf_parse_json_sheen(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_sheen* out_sheen)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@@ -3623,7 +3798,11 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok
{
CGLTF_CHECK_KEY(tokens[i]);
- if (cgltf_json_strcmp(tokens + i, json_chunk, "magFilter") == 0)
+ if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
+ {
+ i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_sampler->name);
+ }
+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "magFilter") == 0)
{
++i;
out_sampler->mag_filter
@@ -3734,6 +3913,9 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to
cgltf_fill_float_array(out_material->pbr_specular_glossiness.specular_factor, 3, 1.0f);
out_material->pbr_specular_glossiness.glossiness_factor = 1.0f;
+ cgltf_fill_float_array(out_material->volume.attenuation_color, 3, 1.0f);
+ out_material->volume.attenuation_distance = FLT_MAX;
+
out_material->alpha_cutoff = 0.5f;
int size = tokens[i].size;
@@ -3859,6 +4041,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to
out_material->has_transmission = 1;
i = cgltf_parse_json_transmission(options, tokens, i + 1, json_chunk, &out_material->transmission);
}
+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_volume") == 0)
+ {
+ out_material->has_volume = 1;
+ i = cgltf_parse_json_volume(options, tokens, i + 1, json_chunk, &out_material->volume);
+ }
else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_sheen") == 0)
{
out_material->has_sheen = 1;
@@ -4089,7 +4276,11 @@ static int cgltf_parse_json_buffer_view(cgltf_options* options, jsmntok_t const*
{
CGLTF_CHECK_KEY(tokens[i]);
- if (cgltf_json_strcmp(tokens+i, json_chunk, "buffer") == 0)
+ if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
+ {
+ i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer_view->name);
+ }
+ else if (cgltf_json_strcmp(tokens+i, json_chunk, "buffer") == 0)
{
++i;
out_buffer_view->buffer = CGLTF_PTRINDEX(cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
@@ -4223,7 +4414,11 @@ static int cgltf_parse_json_buffer(cgltf_options* options, jsmntok_t const* toke
{
CGLTF_CHECK_KEY(tokens[i]);
- if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
+ if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
+ {
+ i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->name);
+ }
+ else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
{
++i;
out_buffer->size =
@@ -4405,6 +4600,7 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke
if (cgltf_json_strcmp(tokens+i, json_chunk, "aspectRatio") == 0)
{
++i;
+ out_camera->data.perspective.has_aspect_ratio = 1;
out_camera->data.perspective.aspect_ratio = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
@@ -4417,6 +4613,7 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke
else if (cgltf_json_strcmp(tokens+i, json_chunk, "zfar") == 0)
{
++i;
+ out_camera->data.perspective.has_zfar = 1;
out_camera->data.perspective.zfar = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
@@ -5160,6 +5357,58 @@ static int cgltf_parse_json_animations(cgltf_options* options, jsmntok_t const*
return i;
}
+static int cgltf_parse_json_variant(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_material_variant* out_variant)
+{
+ 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, "name") == 0)
+ {
+ i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_variant->name);
+ }
+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
+ {
+ i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_variant->extras);
+ }
+ else
+ {
+ i = cgltf_skip_json(tokens, i+1);
+ }
+
+ if (i < 0)
+ {
+ return i;
+ }
+ }
+
+ return i;
+}
+
+static int cgltf_parse_json_variants(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
+{
+ i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_material_variant), (void**)&out_data->variants, &out_data->variants_count);
+ if (i < 0)
+ {
+ return i;
+ }
+
+ for (cgltf_size j = 0; j < out_data->variants_count; ++j)
+ {
+ i = cgltf_parse_json_variant(options, tokens, i, json_chunk, &out_data->variants[j]);
+ if (i < 0)
+ {
+ return i;
+ }
+ }
+ return i;
+}
+
static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_asset* out_asset)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@@ -5400,6 +5649,34 @@ static int cgltf_parse_json_root(cgltf_options* options, jsmntok_t const* tokens
}
}
}
+ else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_variants") == 0)
+ {
+ ++i;
+
+ CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
+
+ int data_size = tokens[i].size;
+ ++i;
+
+ for (int m = 0; m < data_size; ++m)
+ {
+ CGLTF_CHECK_KEY(tokens[i]);
+
+ if (cgltf_json_strcmp(tokens + i, json_chunk, "variants") == 0)
+ {
+ i = cgltf_parse_json_variants(options, tokens, i + 1, json_chunk, out_data);
+ }
+ else
+ {
+ i = cgltf_skip_json(tokens, i + 1);
+ }
+
+ if (i < 0)
+ {
+ return i;
+ }
+ }
+ }
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_data->data_extensions[out_data->data_extensions_count++]));
@@ -5542,6 +5819,11 @@ static int cgltf_fixup_pointers(cgltf_data* data)
CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.attributes[m].data, data->accessors, data->accessors_count);
}
}
+
+ for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
+ {
+ CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].mappings[k].material, data->materials, data->materials_count);
+ }
}
}
@@ -5594,9 +5876,12 @@ static int cgltf_fixup_pointers(cgltf_data* data)
CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_normal_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].specular.specular_texture.texture, data->textures, data->textures_count);
+ CGLTF_PTRFIXUP(data->materials[i].specular.specular_color_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].transmission.transmission_texture.texture, data->textures, data->textures_count);
+ CGLTF_PTRFIXUP(data->materials[i].volume.thickness_texture.texture, data->textures, data->textures_count);
+
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);
}