solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit 514a3ee5f8734b7de79993116dc2a09061d1c7e1
parent 2888a852fbdc55ed2adc14db6f783d7d72d34def
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Mon, 19 Sep 2016 13:33:52 +0200

BugFix: Reject some duplicate hits

Was on triangle's edge where the same hit was filtered twice.
Can lead to duplicate outputs.

Diffstat:
Msrc/ssol_scene.c | 9+++++++++
Msrc/ssol_solver.c | 5+++++
Msrc/ssol_solver_c.h | 1+
3 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/src/ssol_scene.c b/src/ssol_scene.c @@ -287,9 +287,17 @@ hit_filter_function /* these components have been set */ ASSERT_NAN(seg->dir, 3); ASSERT_NAN(seg->org, 3); + ASSERT_NAN(&seg->tmin, 1); ASSERT(seg->self_instance); NCHECK(seg->self_front, 99); + /* need to reject identical hits on triangle's edges */ + if (hit->distance <= seg->tmin) { + ASSERT(hit->distance == seg->tmin); + return 1; + } + seg->tmin = hit->distance; + /* Discard self intersection */ seg->hit_front = f3_dot(hit->normal, dir) < 0; inst = *htable_instance_find(&rs->data.scene->instances_rt, &hit->prim.inst_id); @@ -374,6 +382,7 @@ hit_filter_function if(seg->hit_material->type == MATERIAL_VIRTUAL) { return 1; /* Discard virtual material */ } + seg->hit_instance = inst; return 0; } diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -199,6 +199,7 @@ check_fst_segment(const struct segment* seg) NCHECK(seg->on_punched, 99); ASSERT_NAN(seg->org, 3); ASSERT(seg->weight > 0); + ASSERT_NAN(&seg->tmin, 1); } static void @@ -238,6 +239,8 @@ setup_next_segment(struct realisation* rs) seg->self_instance = prev->hit_instance; seg->self_front = prev->hit_front; seg->sun_segment = 0; + seg->tmin = -1; /* any valid tmin allowed */ + d3_set(seg->org, prev->hit_pos); res = material_shade(prev->hit_material, &data->fragment, rs->freq, data->brdfs); @@ -270,6 +273,7 @@ reset_segment(struct segment* seg) seg->self_instance = NULL; seg->self_front = 99; seg->weight = NAN; + seg->tmin = NAN; #else seg->hit = S3D_HIT_NULL; #endif @@ -510,6 +514,7 @@ receive_sunlight(struct realisation* rs) seg->self_instance = start->instance; seg->self_front = start->front_exposed; seg->sun_segment = 1; + seg->tmin = -1; /* any valid tmin allowed */ /* search for occlusions from starting point */ ASSERT(rs->s_idx == 0); /* sun segment */ diff --git a/src/ssol_solver_c.h b/src/ssol_solver_c.h @@ -66,6 +66,7 @@ struct segment { double hit_pos[3]; double hit_pos_local[3]; /* in local coordinate, only set on punched shapes */ double hit_normal[3]; /* possibly reversed to face the incoming dir */ + float tmin; /* used to reject duplicate hits in raytracing */ char hit_front; /* is the ending point of the segment on the front face? */ char self_front; /* was the starting point of the segment on the front face? */ char on_punched; /* is the hit on a punched shape? */