commit 2c0a29b18cfb52cfa5b461e474e321b8669402fd
parent f2313c345c26c603c72e87a85369ec360f1aaf4b
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 12 Jun 2020 14:17:10 +0200
BugFix: could enter an endless loop with some invalid models
Diffstat:
1 file changed, 30 insertions(+), 0 deletions(-)
diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c
@@ -57,6 +57,7 @@ struct filter_ctx {
struct senc3d_scene* scn;
component_id_t origin_component;
struct darray_triangle_comp* triangles_comp;
+ struct darray_ptr_component_descriptor* components;
/* Result of hit */
component_id_t hit_component;
};
@@ -175,6 +176,34 @@ self_hit_filter
? SENC3D_BACK : SENC3D_FRONT;
filter_ctx->hit_component = hit_trg_comp->component[hit_side];
+
+ if(hit->distance == 0) {
+ /* To avoid create loops, allow dist=0 only if the hit component has
+ * a higher max_z than the origin component */
+ const struct cc_descriptor** descriptors
+ = darray_ptr_component_descriptor_cdata_get(filter_ctx->components);
+ const struct cc_descriptor* origin_desc;
+ const struct cc_descriptor* hit_desc;
+ const union double3* positions
+ = darray_position_cdata_get(&filter_ctx->scn->vertices);
+ ASSERT(filter_ctx->origin_component
+ < darray_ptr_component_descriptor_size_get(filter_ctx->components));
+ ASSERT(filter_ctx->hit_component
+ < darray_ptr_component_descriptor_size_get(filter_ctx->components));
+ origin_desc = descriptors[filter_ctx->origin_component];
+ hit_desc = descriptors[filter_ctx->hit_component];
+ ASSERT(origin_desc->max_z_vrtx_id
+ < darray_position_size_get(&filter_ctx->scn->vertices));
+ ASSERT(hit_desc->max_z_vrtx_id
+ < darray_position_size_get(&filter_ctx->scn->vertices));
+ ASSERT(positions[origin_desc->max_z_vrtx_id].pos.z
+ <= positions[origin_desc->max_z_vrtx_id].pos.z);
+ if(positions[origin_desc->max_z_vrtx_id].pos.z
+ == positions[origin_desc->max_z_vrtx_id].pos.z)
+ {
+ return 1;
+ }
+ }
return 0; /* Keep */
}
@@ -637,6 +666,7 @@ group_connex_components
positions = darray_position_cdata_get(&scn->vertices);
filter_ctx.scn = scn;
filter_ctx.triangles_comp = triangles_comp;
+ filter_ctx.components = connex_components;
*res = s3d_scene_view_get_aabb(s3d_view, lower, upper);
if(*res != RES_OK) return;
/* Cast rays to find links between connex components */