Skip to content

Commit

Permalink
Merge pull request #145 from prideout/pr/asserts
Browse files Browse the repository at this point in the history
Add optional asserts to cgltf_validate.
  • Loading branch information
jkuhlmann authored Mar 22, 2021
2 parents fdbfb59 + b4db326 commit b83559c
Showing 1 changed file with 41 additions and 116 deletions.
157 changes: 41 additions & 116 deletions cgltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,9 @@ static const uint32_t GlbMagicBinChunk = 0x004E4942;
#ifndef CGLTF_ATOF
#define CGLTF_ATOF(str) atof(str)
#endif
#ifndef CGLTF_VALIDATE_ENABLE_ASSERTS
#define CGLTF_VALIDATE_ENABLE_ASSERTS 0
#endif

static void* cgltf_default_alloc(void* user, cgltf_size size)
{
Expand Down Expand Up @@ -1380,6 +1383,12 @@ static cgltf_size cgltf_calc_index_bound(cgltf_buffer_view* buffer_view, cgltf_s
return bound;
}

#if CGLTF_VALIDATE_ENABLE_ASSERTS
#define CGLTF_ASSERT_IF(cond, result) assert(!(cond)); if (cond) return result;
#else
#define CGLTF_ASSERT_IF(cond, result) if (cond) return result;
#endif

cgltf_result cgltf_validate(cgltf_data* data)
{
for (cgltf_size i = 0; i < data->accessors_count; ++i)
Expand All @@ -1392,10 +1401,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
cgltf_size req_size = accessor->offset + accessor->stride * (accessor->count - 1) + element_size;

if (accessor->buffer_view->size < req_size)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(accessor->buffer_view->size < req_size, cgltf_result_data_too_short);
}

if (accessor->is_sparse)
Expand All @@ -1406,27 +1412,18 @@ cgltf_result cgltf_validate(cgltf_data* data)
cgltf_size indices_req_size = sparse->indices_byte_offset + indices_component_size * sparse->count;
cgltf_size values_req_size = sparse->values_byte_offset + element_size * sparse->count;

if (sparse->indices_buffer_view->size < indices_req_size ||
sparse->values_buffer_view->size < values_req_size)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(sparse->indices_buffer_view->size < indices_req_size ||
sparse->values_buffer_view->size < values_req_size, cgltf_result_data_too_short);

if (sparse->indices_component_type != cgltf_component_type_r_8u &&
sparse->indices_component_type != cgltf_component_type_r_16u &&
sparse->indices_component_type != cgltf_component_type_r_32u)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(sparse->indices_component_type != cgltf_component_type_r_8u &&
sparse->indices_component_type != cgltf_component_type_r_16u &&
sparse->indices_component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);

if (sparse->indices_buffer_view->buffer->data)
{
cgltf_size index_bound = cgltf_calc_index_bound(sparse->indices_buffer_view, sparse->indices_byte_offset, sparse->indices_component_type, sparse->count);

if (index_bound >= accessor->count)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(index_bound >= accessor->count, cgltf_result_data_too_short);
}
}
}
Expand All @@ -1435,141 +1432,84 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
cgltf_size req_size = data->buffer_views[i].offset + data->buffer_views[i].size;

if (data->buffer_views[i].buffer && data->buffer_views[i].buffer->size < req_size)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(data->buffer_views[i].buffer && data->buffer_views[i].buffer->size < req_size, cgltf_result_data_too_short);

if (data->buffer_views[i].has_meshopt_compression)
{
cgltf_meshopt_compression* mc = &data->buffer_views[i].meshopt_compression;

if (mc->buffer == NULL || mc->buffer->size < mc->offset + mc->size)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(mc->buffer == NULL || mc->buffer->size < mc->offset + mc->size, cgltf_result_data_too_short);

if (data->buffer_views[i].stride && mc->stride != data->buffer_views[i].stride)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->buffer_views[i].stride && mc->stride != data->buffer_views[i].stride, cgltf_result_invalid_gltf);

if (data->buffer_views[i].size != mc->stride * mc->count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->buffer_views[i].size != mc->stride * mc->count, cgltf_result_invalid_gltf);

if (mc->mode == cgltf_meshopt_compression_mode_invalid)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_invalid, cgltf_result_invalid_gltf);

if (mc->mode == cgltf_meshopt_compression_mode_attributes && !(mc->stride % 4 == 0 && mc->stride <= 256))
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_attributes && !(mc->stride % 4 == 0 && mc->stride <= 256), cgltf_result_invalid_gltf);

if (mc->mode == cgltf_meshopt_compression_mode_triangles && mc->count % 3 != 0)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_triangles && mc->count % 3 != 0, cgltf_result_invalid_gltf);

if ((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->stride != 2 && mc->stride != 4)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->stride != 2 && mc->stride != 4, cgltf_result_invalid_gltf);

if ((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->filter != cgltf_meshopt_compression_filter_none)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->filter != cgltf_meshopt_compression_filter_none, cgltf_result_invalid_gltf);

if (mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8, cgltf_result_invalid_gltf);

if (mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8, cgltf_result_invalid_gltf);
}
}

for (cgltf_size i = 0; i < data->meshes_count; ++i)
{
if (data->meshes[i].weights)
{
if (data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].weights_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].weights_count, cgltf_result_invalid_gltf);
}

if (data->meshes[i].target_names)
{
if (data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].target_names_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].target_names_count, cgltf_result_invalid_gltf);
}

for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
{
if (data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count, cgltf_result_invalid_gltf);

if (data->meshes[i].primitives[j].attributes_count)
{
cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data;

for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
{
if (data->meshes[i].primitives[j].attributes[k].data->count != first->count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
}

for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
{
for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
{
if (data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf);
}
}

cgltf_accessor* indices = data->meshes[i].primitives[j].indices;

if (indices &&
CGLTF_ASSERT_IF(indices &&
indices->component_type != cgltf_component_type_r_8u &&
indices->component_type != cgltf_component_type_r_16u &&
indices->component_type != cgltf_component_type_r_32u)
{
return cgltf_result_invalid_gltf;
}
indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);

if (indices && indices->buffer_view && indices->buffer_view->buffer->data)
{
cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count);

if (index_bound >= first->count)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short);
}

for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
{
if (data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf);
}
}
}
Expand All @@ -1579,10 +1519,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
if (data->nodes[i].weights && data->nodes[i].mesh)
{
if (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf);
}
}

Expand All @@ -1593,10 +1530,7 @@ cgltf_result cgltf_validate(cgltf_data* data)

while (p1 && p2)
{
if (p1 == p2)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(p1 == p2, cgltf_result_invalid_gltf);

p1 = p1->parent;
p2 = p2->parent ? p2->parent->parent : NULL;
Expand All @@ -1607,10 +1541,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
for (cgltf_size j = 0; j < data->scenes[i].nodes_count; ++j)
{
if (data->scenes[i].nodes[j]->parent)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->scenes[i].nodes[j]->parent, cgltf_result_invalid_gltf);
}
}

Expand All @@ -1629,20 +1560,14 @@ cgltf_result cgltf_validate(cgltf_data* data)

if (channel->target_path == cgltf_animation_path_type_weights)
{
if (!channel->target_node->mesh || !channel->target_node->mesh->primitives_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(!channel->target_node->mesh || !channel->target_node->mesh->primitives_count, cgltf_result_invalid_gltf);

components = channel->target_node->mesh->primitives[0].targets_count;
}

cgltf_size values = channel->sampler->interpolation == cgltf_interpolation_type_cubic_spline ? 3 : 1;

if (channel->sampler->input->count * components * values != channel->sampler->output->count)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_data_too_short);
}
}

Expand Down

0 comments on commit b83559c

Please sign in to comment.