From 93ed76211eec2660c27b4e26d3099cb001f3529b Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Tue, 22 Jan 2013 19:33:08 -0500 Subject: [PATCH] make intersection routines more robust vs NaNs --- src/emitters/constant.cpp | 2 +- src/shapes/cylinder.cpp | 3 ++- src/shapes/disk.cpp | 2 +- src/shapes/hair.cpp | 4 ++-- src/shapes/rectangle.cpp | 2 +- src/shapes/sphere.cpp | 3 ++- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/emitters/constant.cpp b/src/emitters/constant.cpp index 3c391bf2..f1909c2d 100644 --- a/src/emitters/constant.cpp +++ b/src/emitters/constant.cpp @@ -196,7 +196,7 @@ public: if (!m_sceneBSphere.rayIntersect(ray, nearT, farT)) return Spectrum(0.0f); - if (nearT >= 0 || farT <= 0) + if (!(nearT < 0 && farT > 0)) return Spectrum(0.0f); dRec.p = ray(farT); diff --git a/src/shapes/cylinder.cpp b/src/shapes/cylinder.cpp index 83af281a..27139b0a 100644 --- a/src/shapes/cylinder.cpp +++ b/src/shapes/cylinder.cpp @@ -145,11 +145,12 @@ public: if (!solveQuadratic(A, B, C, nearT, farT)) return false; - if (nearT > maxt || farT < mint) + if (!(nearT <= maxt && farT >= mint)) /* NaN-aware conditionals */ return false; const Float zPosNear = ray.o.z + ray.d.z * nearT; const Float zPosFar = ray.o.z + ray.d.z * farT; + if (zPosNear >= 0 && zPosNear <= m_length && nearT >= mint) { t = nearT; } else if (zPosFar >= 0 && zPosFar <= m_length) { diff --git a/src/shapes/disk.cpp b/src/shapes/disk.cpp index e4b2d429..fac35568 100644 --- a/src/shapes/disk.cpp +++ b/src/shapes/disk.cpp @@ -136,7 +136,7 @@ public: m_worldToObject.transformAffine(_ray, ray); Float hit = -ray.o.z / ray.d.z; - if (hit < mint || hit > maxt) + if (!(hit >= mint && hit <= maxt)) return false; Point local = ray(hit); diff --git a/src/shapes/hair.cpp b/src/shapes/hair.cpp index b98b0eae..411b7db0 100644 --- a/src/shapes/hair.cpp +++ b/src/shapes/hair.cpp @@ -504,7 +504,7 @@ public: if (!solveQuadraticDouble(A, B, C, nearT, farT)) return false; - if (nearT > maxt || farT < mint) + if (!(nearT <= maxt && farT >= mint)) /* NaN-aware conditionals */ return false; /* Next check the intersection points against the miter planes */ @@ -523,7 +523,7 @@ public: p = Point(rayO + rayD * nearT); t = (Float) nearT; } else if (dot(pointFar - v1, n1) >= 0 && - dot(pointFar - v2, n2) <= 0) { + dot(pointFar - v2, n2) <= 0) { if (farT > maxt) return false; p = Point(rayO + rayD * nearT); diff --git a/src/shapes/rectangle.cpp b/src/shapes/rectangle.cpp index e5056a9e..553bbf17 100644 --- a/src/shapes/rectangle.cpp +++ b/src/shapes/rectangle.cpp @@ -127,7 +127,7 @@ public: m_worldToObject.transformAffine(_ray, ray); Float hit = -ray.o.z / ray.d.z; - if (hit < mint || hit > maxt) + if (!(hit >= mint && hit <= maxt)) return false; Point local = ray(hit); diff --git a/src/shapes/sphere.cpp b/src/shapes/sphere.cpp index 0b644d19..522743e2 100644 --- a/src/shapes/sphere.cpp +++ b/src/shapes/sphere.cpp @@ -172,8 +172,9 @@ public: if (!solveQuadraticDouble(A, B, C, nearT, farT)) return false; - if (nearT > maxt || farT < mint) + if (!(nearT <= maxt && farT >= mint)) /* NaN-aware conditionals */ return false; + if (nearT < mint) { if (farT > maxt) return false;