Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 43 additions & 4 deletions cgltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -2352,11 +2352,46 @@ const cgltf_accessor* cgltf_find_accessor(const cgltf_primitive* prim, cgltf_att
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)
{
Expand Down Expand Up @@ -2500,11 +2535,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);
Expand All @@ -2520,7 +2557,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)
{
Expand Down