solstice-solver

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

commit 2ab6e6361e4eee00fa8e386227136427824392a2
parent 6f8426df1cc6ddd823235e4da3449cb1957e214f
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed,  7 Oct 2020 14:30:05 +0200

BugFix: self-intersection on meshed mirrors

Diffstat:
Mcmake/CMakeLists.txt | 2+-
Msrc/ssol_c.h | 4+++-
Msrc/ssol_scene.c | 9++++++++-
Msrc/ssol_solver.c | 15++++++++++++++-
4 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -29,7 +29,7 @@ option(NO_TEST "Do not build tests" OFF) ################################################################################ find_package(RCMake 0.3 REQUIRED) find_package(RSys 0.7.1 REQUIRED) -find_package(Star3D 0.4.1 REQUIRED) +find_package(Star3D 0.7.2 REQUIRED) find_package(Star3DUT 0.2 REQUIRED) find_package(StarCPR 0.1 REQUIRED) find_package(StarSF 0.4 REQUIRED) diff --git a/src/ssol_c.h b/src/ssol_c.h @@ -39,6 +39,7 @@ struct ray_data { short discard_virtual_materials; /* Define if virtual materials are not RT */ short reversed_ray; /* Define if the ray direction is reversed */ float range_min; + int point_init_closest_point; /* Output data */ double N[3]; /* Normal of the nearest punched surface point */ @@ -46,7 +47,8 @@ struct ray_data { }; static const struct ray_data RAY_DATA_NULL = { - NULL, S3D_PRIMITIVE_NULL__, NULL, NULL, SSOL_INVALID_SIDE, 0, 0, 0, {0,0,0}, FLT_MAX + NULL, S3D_PRIMITIVE_NULL__, NULL, NULL, SSOL_INVALID_SIDE, 0, 0, 0, 0, + {0,0,0}, FLT_MAX }; diff --git a/src/ssol_scene.c b/src/ssol_scene.c @@ -455,7 +455,14 @@ hit_filter_function /* No ray data => nothing to filter */ if(!ray_data) return 0; /* Handle numerical imprecision */ - if(hit->distance <= rdata->range_min) return 1; + if(hit->distance < rdata->range_min) return 1; + + /* When searching for closest_point accept any point on the expected object */ + if(rdata->point_init_closest_point) { + int reject = (rdata->prim_from.geom_id != hit->prim.geom_id) + || (rdata->prim_from.inst_id != hit->prim.inst_id); + return reject; + } /* Retrieve the intersected instance and shaded shape */ inst = *htable_instance_find(&rdata->scn->instances_rt, &hit->prim.inst_id); diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -331,9 +331,22 @@ point_init ray_data.reversed_ray = 1; /* The ray direction is reversed */ ray_data.dst = FLT_MAX; + /* pt->prim must live in RT space */ + f3_set_d3(pos, pt->pos); + ray_data.point_init_closest_point = 1; + S3D(shape_get_id(pt->sshape->shape->shape_rt, &ray_data.prim_from.geom_id)); + S3D(shape_get_id(pt->inst->shape_rt, &ray_data.prim_from.inst_id)); + S3D(scene_view_closest_point(view_rt, pos, FLT_MAX, &ray_data, &hit)); + CHK(!S3D_HIT_NONE(&hit)); + /* Sample and RT meshes are supposed to be identical only for SHAPE_MESH */ + ASSERT(pt->sshape->shape->type != SHAPE_MESH + || hit.distance <= (1 + f3_len(pos)) * 1e-6); + pt->prim = hit.prim; + ray_data.prim_from = pt->prim; + /* Trace a ray toward the sun to check if the sampled point is occluded */ f3_minus(dir, f3_set_d3(dir, pt->dir)); - f3_set_d3(pos, pt->pos); + ray_data.point_init_closest_point = 0; S3D(scene_view_trace_ray(view_rt, pos, dir, range, &ray_data, &hit)); *is_lit = S3D_HIT_NONE(&hit);