Skip to content

Commit

Permalink
Merge pull request #227 from shawnhatori/unpack-indices
Browse files Browse the repository at this point in the history
  • Loading branch information
jkuhlmann authored Nov 27, 2023
2 parents fd3a618 + 1afdc74 commit 3209a22
Showing 1 changed file with 41 additions and 20 deletions.
61 changes: 41 additions & 20 deletions cgltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,14 @@
* By passing null for the output pointer, users can find out how many floats are required in the
* output buffer.
*
* `cgltf_accessor_unpack_indices` reads in the index data from an accessor. Assumes that
* `cgltf_load_buffers` has already been called. By passing null for the output pointer, users can
* find out how many indices are required in the output buffer. Returns 0 if the accessor is
* sparse or if the output component size is less than the accessor's component size.
*
* `cgltf_num_components` is a tiny utility that tells you the dimensionality of
* a certain accessor type. This can be used before `cgltf_accessor_unpack_floats` to help allocate
* the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for
* the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for
* similar purposes.
*
* `cgltf_accessor_read_float` reads a certain element from a non-sparse accessor and converts it to
Expand All @@ -75,7 +80,7 @@
*
* `cgltf_accessor_read_uint` is similar to its floating-point counterpart, but limited to reading
* vector types and does not support matrix types. The passed-in element size is the number of uints
* in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in
* in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in
* element_size is too small, or if the accessor is sparse.
*
* `cgltf_accessor_read_index` is similar to its floating-point counterpart, but it returns size_t
Expand Down Expand Up @@ -838,7 +843,7 @@ 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);
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, 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);
Expand Down Expand Up @@ -1033,7 +1038,7 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m
fclose(file);
return cgltf_result_out_of_memory;
}

cgltf_size read_size = fread(file_data, 1, file_size, file);

fclose(file);
Expand Down Expand Up @@ -1902,7 +1907,7 @@ void cgltf_free(cgltf_data* data)

data->memory.free_func(data->memory.user_data, data->materials);

for (cgltf_size i = 0; i < data->images_count; ++i)
for (cgltf_size i = 0; i < data->images_count; ++i)
{
data->memory.free_func(data->memory.user_data, data->images[i].name);
data->memory.free_func(data->memory.user_data, data->images[i].uri);
Expand Down Expand Up @@ -2550,14 +2555,15 @@ cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const
return (cgltf_size)(object - animation->channels);
}

cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count)
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count)
{
if (out == NULL)
{
return accessor->count;
}

index_count = accessor->count < index_count ? accessor->count : index_count;
cgltf_size index_component_size = cgltf_component_size(accessor->component_type);

if (accessor->is_sparse)
{
Expand All @@ -2567,25 +2573,40 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u
{
return 0;
}
if (index_component_size > out_component_size)
{
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))
if (index_component_size == out_component_size && accessor->stride == out_component_size)
{
memcpy(out, element, index_count * sizeof(cgltf_uint));
memcpy(out, element, index_count * index_component_size);
return index_count;
}
else
{
cgltf_uint* dest = out;

for (cgltf_size index = 0; index < index_count; index++, dest++, element += accessor->stride)
// The component size of the output array is larger than the component size of the index data, so index data will be padded.
switch (out_component_size)
{
case 2:
for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)
{
*dest = (cgltf_uint)cgltf_component_read_index(element, accessor->component_type);
((uint16_t*)out)[index] = (uint16_t)cgltf_component_read_index(element, accessor->component_type);
}
break;
case 4:
for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)
{
((uint32_t*)out)[index] = (uint32_t)cgltf_component_read_index(element, accessor->component_type);
}
break;
default:
break;
}

return index_count;
Expand Down Expand Up @@ -3700,7 +3721,7 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const
out_texture_view->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0)
else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0)
{
++i;
out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
Expand Down Expand Up @@ -3769,11 +3790,11 @@ static int cgltf_parse_json_pbr_metallic_roughness(cgltf_options* options, jsmnt
if (cgltf_json_strcmp(tokens+i, json_chunk, "metallicFactor") == 0)
{
++i;
out_pbr->metallic_factor =
out_pbr->metallic_factor =
cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0)
else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0)
{
++i;
out_pbr->roughness_factor =
Expand Down Expand Up @@ -4241,11 +4262,11 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token
int size = tokens[i].size;
++i;

for (int j = 0; j < size; ++j)
for (int j = 0; j < size; ++j)
{
CGLTF_CHECK_KEY(tokens[i]);

if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0)
if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0)
{
i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->uri);
}
Expand Down Expand Up @@ -4325,7 +4346,7 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok
= cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0)
else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0)
{
++i;
out_sampler->wrap_t
Expand Down Expand Up @@ -4375,7 +4396,7 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok
out_texture->sampler = CGLTF_PTRINDEX(cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk));
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0)
else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0)
{
++i;
out_texture->image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
Expand Down

0 comments on commit 3209a22

Please sign in to comment.