Skip to content

Commit c32e779

Browse files
authored
Merge pull request #273 from zeux/master
Support sparse accessors for cgltf_accessor_read_*
2 parents 08470a2 + 8e0e6a5 commit c32e779

File tree

1 file changed

+43
-4
lines changed

1 file changed

+43
-4
lines changed

cgltf.h

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,11 +2352,46 @@ const cgltf_accessor* cgltf_find_accessor(const cgltf_primitive* prim, cgltf_att
23522352
return NULL;
23532353
}
23542354

2355+
static const uint8_t* cgltf_find_sparse_index(const cgltf_accessor* accessor, cgltf_size needle)
2356+
{
2357+
const cgltf_accessor_sparse* sparse = &accessor->sparse;
2358+
const uint8_t* index_data = cgltf_buffer_view_data(sparse->indices_buffer_view);
2359+
const uint8_t* value_data = cgltf_buffer_view_data(sparse->values_buffer_view);
2360+
2361+
if (index_data == NULL || value_data == NULL)
2362+
return NULL;
2363+
2364+
index_data += sparse->indices_byte_offset;
2365+
value_data += sparse->values_byte_offset;
2366+
2367+
cgltf_size index_stride = cgltf_component_size(sparse->indices_component_type);
2368+
2369+
cgltf_size offset = 0;
2370+
cgltf_size length = sparse->count;
2371+
2372+
while (length)
2373+
{
2374+
cgltf_size rem = length % 2;
2375+
length /= 2;
2376+
2377+
cgltf_size index = cgltf_component_read_index(index_data + (offset + length) * index_stride, sparse->indices_component_type);
2378+
offset += index < needle ? length + rem : 0;
2379+
}
2380+
2381+
if (offset == sparse->count)
2382+
return NULL;
2383+
2384+
cgltf_size index = cgltf_component_read_index(index_data + offset * index_stride, sparse->indices_component_type);
2385+
return index == needle ? value_data + offset * accessor->stride : NULL;
2386+
}
2387+
23552388
cgltf_bool cgltf_accessor_read_float(const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size)
23562389
{
23572390
if (accessor->is_sparse)
23582391
{
2359-
return 0;
2392+
const uint8_t* element = cgltf_find_sparse_index(accessor, index);
2393+
if (element)
2394+
return cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, out, element_size);
23602395
}
23612396
if (accessor->buffer_view == NULL)
23622397
{
@@ -2500,11 +2535,13 @@ cgltf_bool cgltf_accessor_read_uint(const cgltf_accessor* accessor, cgltf_size i
25002535
{
25012536
if (accessor->is_sparse)
25022537
{
2503-
return 0;
2538+
const uint8_t* element = cgltf_find_sparse_index(accessor, index);
2539+
if (element)
2540+
return cgltf_element_read_uint(element, accessor->type, accessor->component_type, out, element_size);
25042541
}
25052542
if (accessor->buffer_view == NULL)
25062543
{
2507-
memset(out, 0, element_size * sizeof( cgltf_uint ));
2544+
memset(out, 0, element_size * sizeof(cgltf_uint));
25082545
return 1;
25092546
}
25102547
const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
@@ -2520,7 +2557,9 @@ cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size
25202557
{
25212558
if (accessor->is_sparse)
25222559
{
2523-
return 0; // This is an error case, but we can't communicate the error with existing interface.
2560+
const uint8_t* element = cgltf_find_sparse_index(accessor, index);
2561+
if (element)
2562+
return cgltf_component_read_index(element, accessor->component_type);
25242563
}
25252564
if (accessor->buffer_view == NULL)
25262565
{

0 commit comments

Comments
 (0)