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:
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);