commit 90edf161d38fa7bb9e1a0e2e8aba9996bcba5bf9
parent bf92ade10d11e306b21aedaca255d37f7a3ae8b3
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 5 Apr 2024 15:12:40 +0200
Continue bugfixes on connec components grouping
Fixes include:
- first inner component volume test was wrong
- outer prevalence over inner not inforced
- unexpected NaN occurences on side computation
Diffstat:
1 file changed, 45 insertions(+), 12 deletions(-)
diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c
@@ -218,7 +218,11 @@ get_side_not_in_connex_component
/* Here unsigned are required by s3d API */
static void
-get_scn_indices(const unsigned itri, unsigned ids[3], void* ctx) {
+get_scn_indices
+ (const unsigned itri,
+ unsigned ids[3],
+ void* ctx)
+{
int i;
const struct senc3d_scene* scene = ctx;
const struct triangle_in* trg =
@@ -232,7 +236,11 @@ get_scn_indices(const unsigned itri, unsigned ids[3], void* ctx) {
/* Here unsigned are required by s3d API */
static void
-get_scn_position(const unsigned ivert, float pos[3], void* ctx) {
+get_scn_position
+ (const unsigned ivert,
+ float pos[3],
+ void* ctx)
+{
const struct senc3d_scene* scene = ctx;
const union double3* pt =
darray_position_cdata_get(&scene->vertices) + ivert;
@@ -337,6 +345,11 @@ self_hit_filter
ASSERT(hit->prim.prim_id
< darray_triangle_comp_size_get(ctx->triangles_comp));
+ if(hit->distance > ctx->hit_dist) {
+ /* No improvement */
+ return 1;
+ }
+
if(hit_comp[SENC3D_FRONT] == ctx->origin_component
|| hit_comp[SENC3D_BACK] == ctx->origin_component)
{
@@ -359,6 +372,10 @@ self_hit_filter
const enum senc3d_side sides[2] = { SENC3D_FRONT, SENC3D_BACK };
component_id_t c = hit_comp[sides[n]];
ASSERT(c < darray_ptr_component_descriptor_size_get(ctx->components));
+ if(c == ctx->hit_component) {
+ /* Cannot change ctx->hit_component */
+ continue;
+ }
if(comp_descriptors[c]->is_outer_border) {
double v;
/* The inner component we are trying to link can only be linked to
@@ -369,14 +386,20 @@ self_hit_filter
continue;
}
v = fabs(comp_descriptors[c]->_6volume);
- /* If origin_component is inside several outer components, the one
+ /* If already linked to an inner component, prefer an outer one
+ * regardless of their respective volumes.
+ * If origin_component is inside several outer components, the one
* we are looking for is the smallest one (to manage outer component
- * inside another outer component) */
- if(v < ctx->current_6volume) {
+ * inside another outer component). */
+ if((ctx->hit_component != COMPONENT_NULL__
+ && !comp_descriptors[ctx->hit_component]->is_outer_border )
+ || v < ctx->current_6volume) {
ctx->hit_component = c;
ctx->current_6volume = v;
ctx->hit_dist = 0;
ctx->hit_prim = hit->prim;
+ } else {
+ continue;
}
} else {
/* c is an inner component */
@@ -409,11 +432,13 @@ self_hit_filter
/* If origin_component is facing several inner components, the one
* we are looking for is the largest one (to manage inner component
* inside another inner component) */
- if(v > ctx->current_6volume) {
+ if(ctx->current_6volume == DBL_MAX || v > ctx->current_6volume) {
ctx->hit_component = c;
ctx->current_6volume = v;
ctx->hit_dist = 0;
ctx->hit_prim = hit->prim;
+ } else {
+ continue;
}
}
}
@@ -435,14 +460,22 @@ self_hit_filter
/* For s to be comparable, vectors must be normailzed */
f3_normalize(hit_normal, hit->normal);
f3_normalize(rdir, ray_dir);
- s = f3_dot(rdir, hit_normal);
+ s = f3_dot(rdir, hit_normal); /* Can be NaN for tiny distances */
+ if(isnan(s)) {
+ /* Try to fix it */
+ f3_divf(rdir, ray_dir, hit->distance);
+ f3_normalize(rdir, rdir);
+ s = f3_dot(rdir, hit_normal);
+ ASSERT(!isnan(s));
+ }
+
+ if(ctx->hit_dist == hit->distance && fabsf(ctx->s) >= fabsf(s)) {
+ /* Same distance with no s improvement: keep the previous hit */
+ return 1;
+ }
if(fabsf(s) < DOT_THRESHOLD) {
/* We cannot know for sure which side to consider */
- if(ctx->hit_dist == hit->distance && fabsf(ctx->s) > fabsf(s)) {
- /* Same distance with worse s: keep the previous hit */
- return 1;
- }
ctx->hit_component = COMPONENT_NULL__;
ctx->s = s;
f3_set(ctx->hit_dir, ray_dir);
@@ -1014,12 +1047,12 @@ group_connex_components
}
if(*res != RES_OK) return;
#endif
-
descriptors = darray_ptr_component_descriptor_data_get(connex_components);
tmp = darray_ptr_component_descriptor_size_get(connex_components);
ASSERT(tmp <= COMPONENT_MAX__);
cc_count = (component_id_t)tmp;
positions = darray_position_cdata_get(&scn->vertices);
+
ctx0.type = FCTX0;
ctx0.c.ctx0.triangles_comp = triangles_comp;
ctx1.type = FCTX1;