commit f52946dbc673f80fc2f37f08699835a0b8687293
parent 8f47cde2d21c759488d960edc6e9082616ce3675
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 22 Feb 2017 15:51:58 +0100
Improved version of the wrong-face bugfix.
There was a residual case where the hit-face was not determined.
Diffstat:
| M | src/ssol_scene.c | | | 79 | +++++++++++++++++++++++++++++++++++++------------------------------------------ |
1 file changed, 37 insertions(+), 42 deletions(-)
diff --git a/src/ssol_scene.c b/src/ssol_scene.c
@@ -403,50 +403,46 @@ hit_filter_function
/* Discard self intersection */
switch(sshape->shape->type) {
- case SHAPE_MESH:
- if(hit->distance <= 1.e-6 /* FIXME hack */
+ case SHAPE_MESH:
+ if(hit->distance <= 1.e-6 /* FIXME hack */
|| hit->distance <= rdata->range_min
|| S3D_PRIMITIVE_EQ(&hit->prim, &rdata->prim_from)) {
- /* Discard self intersection for mesh, i.e. when the intersected
- * primitive is the primitive from which the ray starts */
- return 1;
- } else {
- /* No self intersection. Define which side of the primitive is hit.
- * Note that incoming direction points inward the primitive */
- hit_side = f3_dot(hit->normal, dirf) < 0 ? SSOL_FRONT : SSOL_BACK;
- }
- break;
- case SHAPE_PUNCHED:
- /* Project the hit position into the punched shape */
- d3_set_f3(dir, dirf);
- d3_set_f3(pos, posf);
- dst = punched_shape_trace_ray(sshape->shape, inst->transform, pos, dir,
- hit->distance, pos, N);
- if(dst >= FLT_MAX) {
- /* No projection is found => the ray does not intersect the quadric */
- return 1;
- }
- else if (inst != rdata->inst_from) {
- hit_side = d3_dot(dir, N) < 0 ? SSOL_FRONT : SSOL_BACK;
- } else {
- if(hit->distance <= rdata->range_min) {
- /* Handle RT numerical imprecision, the hit is below the lower bound
- * of the ray range. */
- return 1;
- } else {
- /* If the intersected instance is the one from which the ray starts,
- * ensure that the ray does not intersect the opposite side of the
- * quadric */
- if(hit_side != rdata->side_from) {
- return 1;
- }
- }
- }
- break;
- default: FATAL("Unreachable code.\n"); break;
+ /* Discard self intersection for mesh, i.e. when the intersected
+ * primitive is the primitive from which the ray starts */
+ return 1;
+ }
+ /* No self intersection. Define which side of the primitive is hit.
+ * Note that incoming direction points inward the primitive */
+ hit_side = f3_dot(hit->normal, dirf) < 0 ? SSOL_FRONT : SSOL_BACK;
+ break;
+ case SHAPE_PUNCHED:
+ /* Project the hit position into the punched shape */
+ d3_set_f3(dir, dirf);
+ d3_set_f3(pos, posf);
+ dst = punched_shape_trace_ray(sshape->shape, inst->transform, pos, dir,
+ hit->distance, pos, N);
+ if(dst >= FLT_MAX) {
+ /* No projection is found => the ray does not intersect the quadric */
+ return 1;
+ }
+ if(dst <= rdata->range_min) {
+ /* Handle RT numerical imprecision, the hit is below the lower bound
+ * of the ray range. */
+ return 1;
+ }
+ hit_side = d3_dot(dir, N) < 0 ? SSOL_FRONT : SSOL_BACK;
+ if(inst == rdata->inst_from && hit_side != rdata->side_from) {
+ /* Reversed_ray is intentionally not considered here! */
+ /* The intersected instance is the one from which the ray starts,
+ * ensure that the ray does not intersect the opposite side of the
+ * quadric */
+ return 1;
+ }
+ break;
+ default: FATAL("Unreachable code.\n"); break;
}
ASSERT(hit_side == SSOL_BACK || hit_side == SSOL_FRONT);
- if (rdata->reversed_ray) {
+ if(rdata->reversed_ray) {
hit_side = (hit_side == SSOL_FRONT) ? SSOL_BACK : SSOL_FRONT;
}
mtl = hit_side == SSOL_FRONT ? sshape->mtl_front : sshape->mtl_back;
@@ -454,7 +450,7 @@ hit_filter_function
/* Discard all virtual materials */
if(rdata->discard_virtual_materials) return 1;
/* Discard virtual material that are not receivers */
- if((inst->receiver_mask&(int)hit_side) == 0) return 1;
+ if((inst->receiver_mask&(int) hit_side) == 0) return 1;
}
/* Save the nearest intersected quadric point */
@@ -465,4 +461,3 @@ hit_filter_function
return 0;
}
-