|
|
@ -328,15 +328,6 @@ typedef struct cgltf_accessor_sparse |
|
|
|
cgltf_component_type indices_component_type; |
|
|
|
cgltf_buffer_view* values_buffer_view; |
|
|
|
cgltf_size values_byte_offset; |
|
|
|
cgltf_extras extras; |
|
|
|
cgltf_extras indices_extras; |
|
|
|
cgltf_extras values_extras; |
|
|
|
cgltf_size extensions_count; |
|
|
|
cgltf_extension* extensions; |
|
|
|
cgltf_size indices_extensions_count; |
|
|
|
cgltf_extension* indices_extensions; |
|
|
|
cgltf_size values_extensions_count; |
|
|
|
cgltf_extension* values_extensions; |
|
|
|
} cgltf_accessor_sparse; |
|
|
|
|
|
|
|
typedef struct cgltf_accessor |
|
|
@ -419,9 +410,6 @@ typedef struct cgltf_texture_view |
|
|
|
cgltf_float scale; /* equivalent to strength for occlusion_texture */ |
|
|
|
cgltf_bool has_transform; |
|
|
|
cgltf_texture_transform transform; |
|
|
|
cgltf_extras extras; |
|
|
|
cgltf_size extensions_count; |
|
|
|
cgltf_extension* extensions; |
|
|
|
} cgltf_texture_view; |
|
|
|
|
|
|
|
typedef struct cgltf_pbr_metallic_roughness |
|
|
@ -504,6 +492,13 @@ typedef struct cgltf_iridescence |
|
|
|
cgltf_texture_view iridescence_thickness_texture; |
|
|
|
} cgltf_iridescence; |
|
|
|
|
|
|
|
typedef struct cgltf_anisotropy |
|
|
|
{ |
|
|
|
cgltf_float anisotropy_strength; |
|
|
|
cgltf_float anisotropy_rotation; |
|
|
|
cgltf_texture_view anisotropy_texture; |
|
|
|
} cgltf_anisotropy; |
|
|
|
|
|
|
|
typedef struct cgltf_material |
|
|
|
{ |
|
|
|
char* name; |
|
|
@ -517,6 +512,7 @@ typedef struct cgltf_material |
|
|
|
cgltf_bool has_sheen; |
|
|
|
cgltf_bool has_emissive_strength; |
|
|
|
cgltf_bool has_iridescence; |
|
|
|
cgltf_bool has_anisotropy; |
|
|
|
cgltf_pbr_metallic_roughness pbr_metallic_roughness; |
|
|
|
cgltf_pbr_specular_glossiness pbr_specular_glossiness; |
|
|
|
cgltf_clearcoat clearcoat; |
|
|
@ -527,6 +523,7 @@ typedef struct cgltf_material |
|
|
|
cgltf_volume volume; |
|
|
|
cgltf_emissive_strength emissive_strength; |
|
|
|
cgltf_iridescence iridescence; |
|
|
|
cgltf_anisotropy anisotropy; |
|
|
|
cgltf_texture_view normal_texture; |
|
|
|
cgltf_texture_view occlusion_texture; |
|
|
|
cgltf_texture_view emissive_texture; |
|
|
@ -559,7 +556,6 @@ typedef struct cgltf_draco_mesh_compression { |
|
|
|
} 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; |
|
|
@ -842,10 +838,28 @@ cgltf_size cgltf_component_size(cgltf_component_type component_type); |
|
|
|
cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type); |
|
|
|
|
|
|
|
cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count); |
|
|
|
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count); |
|
|
|
|
|
|
|
/* this function is deprecated and will be removed in the future; use cgltf_extras::data instead */ |
|
|
|
cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* extras, char* dest, cgltf_size* dest_size); |
|
|
|
|
|
|
|
cgltf_size cgltf_mesh_index(const cgltf_data* data, const cgltf_mesh* object); |
|
|
|
cgltf_size cgltf_material_index(const cgltf_data* data, const cgltf_material* object); |
|
|
|
cgltf_size cgltf_accessor_index(const cgltf_data* data, const cgltf_accessor* object); |
|
|
|
cgltf_size cgltf_buffer_view_index(const cgltf_data* data, const cgltf_buffer_view* object); |
|
|
|
cgltf_size cgltf_buffer_index(const cgltf_data* data, const cgltf_buffer* object); |
|
|
|
cgltf_size cgltf_image_index(const cgltf_data* data, const cgltf_image* object); |
|
|
|
cgltf_size cgltf_texture_index(const cgltf_data* data, const cgltf_texture* object); |
|
|
|
cgltf_size cgltf_sampler_index(const cgltf_data* data, const cgltf_sampler* object); |
|
|
|
cgltf_size cgltf_skin_index(const cgltf_data* data, const cgltf_skin* object); |
|
|
|
cgltf_size cgltf_camera_index(const cgltf_data* data, const cgltf_camera* object); |
|
|
|
cgltf_size cgltf_light_index(const cgltf_data* data, const cgltf_light* object); |
|
|
|
cgltf_size cgltf_node_index(const cgltf_data* data, const cgltf_node* object); |
|
|
|
cgltf_size cgltf_scene_index(const cgltf_data* data, const cgltf_scene* object); |
|
|
|
cgltf_size cgltf_animation_index(const cgltf_data* data, const cgltf_animation* object); |
|
|
|
cgltf_size cgltf_animation_sampler_index(const cgltf_animation* animation, const cgltf_animation_sampler* object); |
|
|
|
cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const cgltf_animation_channel* object); |
|
|
|
|
|
|
|
#ifdef __cplusplus |
|
|
|
} |
|
|
|
#endif |
|
|
@ -866,6 +880,7 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* |
|
|
|
|
|
|
|
#ifdef CGLTF_IMPLEMENTATION |
|
|
|
|
|
|
|
#include <assert.h> /* For assert */ |
|
|
|
#include <string.h> /* For strncpy */ |
|
|
|
#include <stdio.h> /* For fopen */ |
|
|
|
#include <limits.h> /* For UINT_MAX etc */ |
|
|
@ -875,10 +890,6 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* |
|
|
|
#include <stdlib.h> /* For malloc, free, atoi, atof */ |
|
|
|
#endif |
|
|
|
|
|
|
|
#if CGLTF_VALIDATE_ENABLE_ASSERTS |
|
|
|
#include <assert.h> |
|
|
|
#endif |
|
|
|
|
|
|
|
/* JSMN_PARENT_LINKS is necessary to make parsing large structures linear in input size */ |
|
|
|
#define JSMN_PARENT_LINKS |
|
|
|
|
|
|
@ -1000,7 +1011,7 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m |
|
|
|
{ |
|
|
|
fseek(file, 0, SEEK_END); |
|
|
|
|
|
|
|
#ifdef _WIN32 |
|
|
|
#ifdef _MSC_VER |
|
|
|
__int64 length = _ftelli64(file); |
|
|
|
#else |
|
|
|
long length = ftell(file); |
|
|
@ -1144,7 +1155,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s |
|
|
|
|
|
|
|
json_chunk += GlbChunkHeaderSize; |
|
|
|
|
|
|
|
const void* bin = mi">0; |
|
|
|
const void* bin = nb">NULL; |
|
|
|
cgltf_size bin_size = 0; |
|
|
|
|
|
|
|
if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size) |
|
|
@ -1763,12 +1774,6 @@ static void cgltf_free_extensions(cgltf_data* data, cgltf_extension* extensions, |
|
|
|
data->memory.free_func(data->memory.user_data, extensions); |
|
|
|
} |
|
|
|
|
|
|
|
static void cgltf_free_texture_view(cgltf_data* data, cgltf_texture_view* view) |
|
|
|
{ |
|
|
|
cgltf_free_extensions(data, view->extensions, view->extensions_count); |
|
|
|
cgltf_free_extras(data, &view->extras); |
|
|
|
} |
|
|
|
|
|
|
|
void cgltf_free(cgltf_data* data) |
|
|
|
{ |
|
|
|
if (!data) |
|
|
@ -1790,15 +1795,6 @@ void cgltf_free(cgltf_data* data) |
|
|
|
{ |
|
|
|
data->memory.free_func(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); |
|
|
|
cgltf_free_extensions(data, data->accessors[i].sparse.indices_extensions, data->accessors[i].sparse.indices_extensions_count); |
|
|
|
cgltf_free_extensions(data, data->accessors[i].sparse.values_extensions, data->accessors[i].sparse.values_extensions_count); |
|
|
|
cgltf_free_extras(data, &data->accessors[i].sparse.extras); |
|
|
|
cgltf_free_extras(data, &data->accessors[i].sparse.indices_extras); |
|
|
|
cgltf_free_extras(data, &data->accessors[i].sparse.values_extras); |
|
|
|
} |
|
|
|
cgltf_free_extensions(data, data->accessors[i].extensions, data->accessors[i].extensions_count); |
|
|
|
cgltf_free_extras(data, &data->accessors[i].extras); |
|
|
|
} |
|
|
@ -1900,50 +1896,6 @@ void cgltf_free(cgltf_data* data) |
|
|
|
{ |
|
|
|
data->memory.free_func(data->memory.user_data, data->materials[i].name); |
|
|
|
|
|
|
|
if(data->materials[i].has_pbr_metallic_roughness) |
|
|
|
{ |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].pbr_metallic_roughness.metallic_roughness_texture); |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].pbr_metallic_roughness.base_color_texture); |
|
|
|
} |
|
|
|
if(data->materials[i].has_pbr_specular_glossiness) |
|
|
|
{ |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].pbr_specular_glossiness.diffuse_texture); |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].pbr_specular_glossiness.specular_glossiness_texture); |
|
|
|
} |
|
|
|
if(data->materials[i].has_clearcoat) |
|
|
|
{ |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_texture); |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_roughness_texture); |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_normal_texture); |
|
|
|
} |
|
|
|
if(data->materials[i].has_specular) |
|
|
|
{ |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].specular.specular_texture); |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].specular.specular_color_texture); |
|
|
|
} |
|
|
|
if(data->materials[i].has_transmission) |
|
|
|
{ |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].transmission.transmission_texture); |
|
|
|
} |
|
|
|
if (data->materials[i].has_volume) |
|
|
|
{ |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].volume.thickness_texture); |
|
|
|
} |
|
|
|
if(data->materials[i].has_sheen) |
|
|
|
{ |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].sheen.sheen_color_texture); |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].sheen.sheen_roughness_texture); |
|
|
|
} |
|
|
|
if(data->materials[i].has_iridescence) |
|
|
|
{ |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].iridescence.iridescence_texture); |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].iridescence.iridescence_thickness_texture); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_free_texture_view(data, &data->materials[i].normal_texture); |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].occlusion_texture); |
|
|
|
cgltf_free_texture_view(data, &data->materials[i].emissive_texture); |
|
|
|
|
|
|
|
cgltf_free_extensions(data, data->materials[i].extensions, data->materials[i].extensions_count); |
|
|
|
cgltf_free_extras(data, &data->materials[i].extras); |
|
|
|
} |
|
|
@ -2198,8 +2150,6 @@ static cgltf_ssize cgltf_component_read_integer(const void* in, cgltf_component_ |
|
|
|
return *((const uint16_t*) in); |
|
|
|
case cgltf_component_type_r_32u: |
|
|
|
return *((const uint32_t*) in); |
|
|
|
case cgltf_component_type_r_32f: |
|
|
|
return (cgltf_ssize)*((const float*) in); |
|
|
|
case cgltf_component_type_r_8: |
|
|
|
return *((const int8_t*) in); |
|
|
|
case cgltf_component_type_r_8u: |
|
|
@ -2217,8 +2167,6 @@ static cgltf_size cgltf_component_read_index(const void* in, cgltf_component_typ |
|
|
|
return *((const uint16_t*) in); |
|
|
|
case cgltf_component_type_r_32u: |
|
|
|
return *((const uint32_t*) in); |
|
|
|
case cgltf_component_type_r_32f: |
|
|
|
return (cgltf_size)((cgltf_ssize)*((const float*) in)); |
|
|
|
case cgltf_component_type_r_8u: |
|
|
|
return *((const uint8_t*) in); |
|
|
|
default: |
|
|
@ -2356,21 +2304,41 @@ cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_fl |
|
|
|
cgltf_size element_count = float_count / floats_per_element; |
|
|
|
|
|
|
|
// First pass: convert each element in the base accessor. |
|
|
|
cgltf_float* dest = out; |
|
|
|
cgltf_accessor dense = *accessor; |
|
|
|
dense.is_sparse = 0; |
|
|
|
for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element) |
|
|
|
if (accessor->buffer_view == NULL) |
|
|
|
{ |
|
|
|
memset(out, 0, element_count * floats_per_element * sizeof(cgltf_float)); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if (!cgltf_accessor_read_float(&dense, index, dest, floats_per_element)) |
|
|
|
const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view); |
|
|
|
if (element == NULL) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
element += accessor->offset; |
|
|
|
|
|
|
|
if (accessor->component_type == cgltf_component_type_r_32f && accessor->stride == floats_per_element * sizeof(cgltf_float)) |
|
|
|
{ |
|
|
|
memcpy(out, element, element_count * floats_per_element * sizeof(cgltf_float)); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
cgltf_float* dest = out; |
|
|
|
|
|
|
|
for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element, element += accessor->stride) |
|
|
|
{ |
|
|
|
if (!cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, dest, floats_per_element)) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Second pass: write out each element in the sparse accessor. |
|
|
|
if (accessor->is_sparse) |
|
|
|
{ |
|
|
|
const cgltf_accessor_sparse* sparse = &dense.sparse; |
|
|
|
const cgltf_accessor_sparse* sparse = &accessor->sparse; |
|
|
|
|
|
|
|
const uint8_t* index_data = cgltf_buffer_view_data(sparse->indices_buffer_view); |
|
|
|
const uint8_t* reader_head = cgltf_buffer_view_data(sparse->values_buffer_view); |
|
|
@ -2384,17 +2352,15 @@ cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_fl |
|
|
|
reader_head += sparse->values_byte_offset; |
|
|
|
|
|
|
|
cgltf_size index_stride = cgltf_component_size(sparse->indices_component_type); |
|
|
|
for (cgltf_size reader_index = 0; reader_index < sparse->count; reader_index++, index_data += index_stride) |
|
|
|
for (cgltf_size reader_index = 0; reader_index < sparse->count; reader_index++, index_data += index_stride, reader_head += accessor->stride) |
|
|
|
{ |
|
|
|
size_t writer_index = cgltf_component_read_index(index_data, sparse->indices_component_type); |
|
|
|
float* writer_head = out + writer_index * floats_per_element; |
|
|
|
|
|
|
|
if (!cgltf_element_read_float(reader_head, dense.type, dense.component_type, dense.normalized, writer_head, floats_per_element)) |
|
|
|
if (!cgltf_element_read_float(reader_head, accessor->type, accessor->component_type, accessor->normalized, writer_head, floats_per_element)) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
reader_head += dense.stride; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -2488,6 +2454,143 @@ cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size |
|
|
|
return cgltf_component_read_index(element, accessor->component_type); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_mesh_index(const cgltf_data* data, const cgltf_mesh* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->meshes) < data->meshes_count); |
|
|
|
return (cgltf_size)(object - data->meshes); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_material_index(const cgltf_data* data, const cgltf_material* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->materials) < data->materials_count); |
|
|
|
return (cgltf_size)(object - data->materials); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_accessor_index(const cgltf_data* data, const cgltf_accessor* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->accessors) < data->accessors_count); |
|
|
|
return (cgltf_size)(object - data->accessors); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_buffer_view_index(const cgltf_data* data, const cgltf_buffer_view* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->buffer_views) < data->buffer_views_count); |
|
|
|
return (cgltf_size)(object - data->buffer_views); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_buffer_index(const cgltf_data* data, const cgltf_buffer* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->buffers) < data->buffers_count); |
|
|
|
return (cgltf_size)(object - data->buffers); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_image_index(const cgltf_data* data, const cgltf_image* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->images) < data->images_count); |
|
|
|
return (cgltf_size)(object - data->images); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_texture_index(const cgltf_data* data, const cgltf_texture* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->textures) < data->textures_count); |
|
|
|
return (cgltf_size)(object - data->textures); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_sampler_index(const cgltf_data* data, const cgltf_sampler* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->samplers) < data->samplers_count); |
|
|
|
return (cgltf_size)(object - data->samplers); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_skin_index(const cgltf_data* data, const cgltf_skin* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->skins) < data->skins_count); |
|
|
|
return (cgltf_size)(object - data->skins); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_camera_index(const cgltf_data* data, const cgltf_camera* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->cameras) < data->cameras_count); |
|
|
|
return (cgltf_size)(object - data->cameras); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_light_index(const cgltf_data* data, const cgltf_light* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->lights) < data->lights_count); |
|
|
|
return (cgltf_size)(object - data->lights); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_node_index(const cgltf_data* data, const cgltf_node* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->nodes) < data->nodes_count); |
|
|
|
return (cgltf_size)(object - data->nodes); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_scene_index(const cgltf_data* data, const cgltf_scene* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->scenes) < data->scenes_count); |
|
|
|
return (cgltf_size)(object - data->scenes); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_animation_index(const cgltf_data* data, const cgltf_animation* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - data->animations) < data->animations_count); |
|
|
|
return (cgltf_size)(object - data->animations); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_animation_sampler_index(const cgltf_animation* animation, const cgltf_animation_sampler* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - animation->samplers) < animation->samplers_count); |
|
|
|
return (cgltf_size)(object - animation->samplers); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const cgltf_animation_channel* object) |
|
|
|
{ |
|
|
|
assert(object && (cgltf_size)(object - animation->channels) < animation->channels_count); |
|
|
|
return (cgltf_size)(object - animation->channels); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count) |
|
|
|
{ |
|
|
|
if (out == NULL) |
|
|
|
{ |
|
|
|
return accessor->count; |
|
|
|
} |
|
|
|
|
|
|
|
index_count = accessor->count < index_count ? accessor->count : index_count; |
|
|
|
|
|
|
|
if (accessor->is_sparse) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if (accessor->buffer_view == NULL) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view); |
|
|
|
if (element == NULL) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
element += accessor->offset; |
|
|
|
|
|
|
|
if (accessor->component_type == cgltf_component_type_r_32u && accessor->stride == sizeof(cgltf_uint)) |
|
|
|
{ |
|
|
|
memcpy(out, element, index_count * sizeof(cgltf_uint)); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
cgltf_uint* dest = out; |
|
|
|
|
|
|
|
for (cgltf_size index = 0; index < index_count; index++, dest++, element += accessor->stride) |
|
|
|
{ |
|
|
|
*dest = (cgltf_uint)cgltf_component_read_index(element, accessor->component_type); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return index_count; |
|
|
|
} |
|
|
|
|
|
|
|
#define CGLTF_ERROR_JSON -1 |
|
|
|
#define CGLTF_ERROR_NOMEM -2 |
|
|
|
#define CGLTF_ERROR_LEGACY -3 |
|
|
@ -2864,6 +2967,10 @@ 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; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
i = cgltf_skip_json(tokens, i+1); |
|
|
|
} |
|
|
|
|
|
|
|
if (i < 0) |
|
|
|
{ |
|
|
@ -2889,11 +2996,9 @@ static int cgltf_parse_json_mesh_gpu_instancing(cgltf_options* options, jsmntok_ |
|
|
|
{ |
|
|
|
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) |
|
|
|
else |
|
|
|
{ |
|
|
|
++i; |
|
|
|
out_mesh_gpu_instancing->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk)); |
|
|
|
++i; |
|
|
|
i = cgltf_skip_json(tokens, i+1); |
|
|
|
} |
|
|
|
|
|
|
|
if (i < 0) |
|
|
@ -3291,7 +3396,7 @@ static cgltf_component_type cgltf_json_to_component_type(jsmntok_t const* tok, c |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor_sparse* out_sparse) |
|
|
|
static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor_sparse* out_sparse) |
|
|
|
{ |
|
|
|
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); |
|
|
|
|
|
|
@ -3338,14 +3443,6 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co |
|
|
|
out_sparse->indices_component_type = cgltf_json_to_component_type(tokens + i, json_chunk); |
|
|
|
++i; |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->indices_extras); |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->indices_extensions_count, &out_sparse->indices_extensions); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
i = cgltf_skip_json(tokens, i+1); |
|
|
@ -3381,14 +3478,6 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co |
|
|
|
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) |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->values_extras); |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->values_extensions_count, &out_sparse->values_extensions); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
i = cgltf_skip_json(tokens, i+1); |
|
|
@ -3400,14 +3489,6 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->extras); |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->extensions_count, &out_sparse->extensions); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
i = cgltf_skip_json(tokens, i+1); |
|
|
@ -3521,7 +3602,7 @@ static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* to |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "sparse") == 0) |
|
|
|
{ |
|
|
|
out_accessor->is_sparse = 1; |
|
|
|
i = cgltf_parse_json_accessor_sparse(options, tokens, i + 1, json_chunk, &out_accessor->sparse); |
|
|
|
i = cgltf_parse_json_accessor_sparse(tokens, i + 1, json_chunk, &out_accessor->sparse); |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) |
|
|
|
{ |
|
|
@ -3593,6 +3674,8 @@ static int cgltf_parse_json_texture_transform(jsmntok_t const* tokens, int i, co |
|
|
|
|
|
|
|
static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture_view* out_texture_view) |
|
|
|
{ |
|
|
|
(void)options; |
|
|
|
|
|
|
|
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); |
|
|
|
|
|
|
|
out_texture_view->scale = 1.0f; |
|
|
@ -3629,28 +3712,12 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const |
|
|
|
out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk); |
|
|
|
++i; |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0) |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_texture_view->extras); |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0) |
|
|
|
{ |
|
|
|
++i; |
|
|
|
|
|
|
|
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); |
|
|
|
if(out_texture_view->extensions) |
|
|
|
{ |
|
|
|
return CGLTF_ERROR_JSON; |
|
|
|
} |
|
|
|
|
|
|
|
int extensions_size = tokens[i].size; |
|
|
|
out_texture_view->extensions_count = 0; |
|
|
|
out_texture_view->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size); |
|
|
|
|
|
|
|
if (!out_texture_view->extensions) |
|
|
|
{ |
|
|
|
return CGLTF_ERROR_NOMEM; |
|
|
|
} |
|
|
|
|
|
|
|
++i; |
|
|
|
|
|
|
@ -3665,7 +3732,7 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture_view->extensions[out_texture_view->extensions_count++])); |
|
|
|
i = cgltf_skip_json(tokens, i + 1); |
|
|
|
} |
|
|
|
|
|
|
|
if (i < 0) |
|
|
@ -3719,13 +3786,11 @@ static int cgltf_parse_json_pbr_metallic_roughness(cgltf_options* options, jsmnt |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens+i, json_chunk, "baseColorTexture") == 0) |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, |
|
|
|
&out_pbr->base_color_texture); |
|
|
|
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->base_color_texture); |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "metallicRoughnessTexture") == 0) |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, |
|
|
|
&out_pbr->metallic_roughness_texture); |
|
|
|
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->metallic_roughness_texture); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
@ -4128,6 +4193,47 @@ static int cgltf_parse_json_iridescence(cgltf_options* options, jsmntok_t const* |
|
|
|
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); |
|
|
|
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, "anisotropyStrength") == 0) |
|
|
|
{ |
|
|
|
++i; |
|
|
|
out_anisotropy->anisotropy_strength = cgltf_json_to_float(tokens + i, json_chunk); |
|
|
|
++i; |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "anisotropyRotation") == 0) |
|
|
|
{ |
|
|
|
++i; |
|
|
|
out_anisotropy->anisotropy_rotation = cgltf_json_to_float(tokens + i, json_chunk); |
|
|
|
++i; |
|
|
|
} |
|
|
|
else if (cgltf_json_strcmp(tokens + i, json_chunk, "anisotropyTexture") == 0) |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_anisotropy->anisotropy_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); |
|
|
@ -4516,6 +4622,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_anisotropy") == 0) |
|
|
|
{ |
|
|
|
out_material->has_anisotropy = 1; |
|
|
|
i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->anisotropy); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++])); |
|
|
@ -6367,6 +6478,8 @@ 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].anisotropy.anisotropy_texture.texture, data->textures, data->textures_count); |
|
|
|
} |
|
|
|
|
|
|
|
for (cgltf_size i = 0; i < data->buffer_views_count; ++i) |
|
|
@ -6411,7 +6524,6 @@ static int cgltf_fixup_pointers(cgltf_data* data) |
|
|
|
|
|
|
|
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); |
|
|
|