@@ -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+
23552388cgltf_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