commit 5ae79b240a404177cee76e139841bceec8cadb42
parent 402f34f44e40fd351ae14469f8834084d3b749b0
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 28 May 2018 10:45:28 +0200
Fix inaccuracies in the scene_get_medium_3d function
Diffstat:
| M | src/sdis_scene.c | | | 76 | +++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
1 file changed, 45 insertions(+), 31 deletions(-)
diff --git a/src/sdis_scene.c b/src/sdis_scene.c
@@ -459,9 +459,17 @@ scene_get_medium_2d
size_t iprim, nprims;
size_t nfailures = 0;
const size_t max_failures = 10;
+ /* Range of the parametric coordinate into which positions are challenged */
+ const float s_range[2] = {0.25, 0.75};
+ const size_t s_nsteps = 3; /* #challenges per primitive into the range */
+ float s;
+ float s_step;
res_T res = RES_OK;
ASSERT(scn && pos);
+ s_step = (s_range[1] - s_range[0]) / (float)(s_nsteps-1);
+ s = s_range[0];
+
S2D(scene_view_primitives_count(scn->s2d_view, &nprims));
FOR_EACH(iprim, 0, nprims) {
struct s2d_hit hit;
@@ -470,14 +478,6 @@ scene_get_medium_2d
const float range[2] = {0.f, FLT_MAX};
float N[2], P[2], dir[2], cos_N_dir;
- /* Range of the parametric coordinate into which positions are challenged */
- const float s_range[2] = {0.25, 0.75};
- const size_t s_nsteps = 3; /* #challenges per primitive into the range */
- float s;
- float s_step;
-
- s_step = (s_range[1] - s_range[0]) / (float)(s_nsteps-1);
- s = s_range[0];
do {
/* Retrieve a position onto the primitive */
S2D(scene_view_get_primitive(scn->s2d_view, (unsigned)iprim, &prim));
@@ -502,9 +502,9 @@ scene_get_medium_2d
* target a new position onto the current primitive */
} while(hit_on_vertex(&hit) && (s+=s_step) <= s_range[1]);
- /* The hits of all targeted positions on the current primitive, are on
- * edges. Try positions on another primitive. */
- if(s > 0.75f) continue;
+ /* The hits of all targeted positions on the current primitive are on
+ * vertices. Challenge positions on another primitive. */
+ if(s > s_range[1]) continue;
f2_normalize(N, hit.normal);
cos_N_dir = f2_dot(N, dir);
@@ -546,42 +546,56 @@ scene_get_medium_3d
size_t iprim, nprims;
size_t nfailures = 0;
const size_t max_failures = 10;
+ float st[3][2]; /* Position to challenge onto the primitive */
+ const size_t nsteps = sizeof(st)/sizeof(float[2]);
res_T res = RES_OK;
ASSERT(scn && pos);
+ /* Setup the position to challenge onto the primitives */
+ f2(st[0], 1.f/6.f, 5.f/12.f);
+ f2(st[1], 5.f/12.f, 1.f/6.f);
+ f2(st[2], 5.f/12.f, 5.f/12.f);
+
S3D(scene_view_primitives_count(scn->s3d_view, &nprims));
FOR_EACH(iprim, 0, nprims) {
struct s3d_hit hit;
struct s3d_attrib attr;
struct s3d_primitive prim;
- float st[2];
const float range[2] = {0.f, FLT_MAX};
float N[3], P[3], dir[3], cos_N_dir;
- st[0] = st[1] = 1.f / 3.f; /* Or MSVC will issue a warning */
+ size_t istep = 0;
- /* Retrieve a position onto the primitive */
- S3D(scene_view_get_primitive(scn->s3d_view, (unsigned)iprim, &prim));
- S3D(primitive_get_attrib(&prim, S3D_POSITION, st, &attr));
+ do {
+ /* Retrieve a position onto the primitive */
+ S3D(scene_view_get_primitive(scn->s3d_view, (unsigned)iprim, &prim));
+ S3D(primitive_get_attrib(&prim, S3D_POSITION, st[istep], &attr));
- /* Trace a ray from the randomw walk vertex toward the retrieved primitive
- * position */
- f3_normalize(dir, f3_sub(dir, attr.value, f3_set_d3(P, pos)));
- S3D(scene_view_trace_ray(scn->s3d_view, P, dir, range, NULL, &hit));
+ /* Trace a ray from the randomw walk vertex toward the retrieved primitive
+ * position */
+ f3_normalize(dir, f3_sub(dir, attr.value, f3_set_d3(P, pos)));
+ S3D(scene_view_trace_ray(scn->s3d_view, P, dir, range, NULL, &hit));
+
+ /* Unforeseen error. One has to intersect a primitive ! */
+ if(S3D_HIT_NONE(&hit)) {
+ ++nfailures;
+ if(nfailures < max_failures) {
+ continue;
+ } else {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ }
+ /* Discard the hit if it is on an edge, i.e. between 2 triangles, and
+ * target a new position onto the current primitive */
+ } while(hit_on_edge(&hit) && ++istep < nsteps);
+
+ /* The hits of all targeted positions on the current primitive are on
+ * edges. Challenge positions on another primitive. */
+ if(istep >= nsteps) continue;
f3_normalize(N, hit.normal);
cos_N_dir = f3_dot(N, dir);
- /* Unforeseen error. One has to intersect a primitive ! */
- if(S3D_HIT_NONE(&hit)) {
- ++nfailures;
- if(nfailures < max_failures) {
- continue;
- } else {
- res = RES_BAD_ARG;
- goto error;
- }
- }
-
if(absf(cos_N_dir) > 1.e-1f) { /* Not roughly orthognonal */
const struct sdis_interface* interf;
interf = scene_get_interface(scn, hit.prim.prim_id);