bool CustomImplicitSurface2::intersectsLocal(const Ray2D& ray) const { BoundingBoxRayIntersection2D intersection = _domain.closestIntersection(ray); if (intersection.isIntersecting) { double tStart, tEnd; if (intersection.tFar == kMaxD) { tStart = 0.0; tEnd = intersection.tNear; } else { tStart = intersection.tNear; tEnd = intersection.tFar; } double t = tStart; Vector2D pt = ray.pointAt(t); double prevPhi = _func(pt); while (t <= tEnd) { pt = ray.pointAt(t); const double newPhi = _func(pt); const double newPhiAbs = std::fabs(newPhi); if (newPhi * prevPhi < 0.0) { return true; } t += std::max(newPhiAbs, _rayMarchingResolution); prevPhi = newPhi; } } return false; }
SurfaceRayIntersection2 CustomImplicitSurface2::closestIntersectionLocal( const Ray2D& ray) const { SurfaceRayIntersection2 result; BoundingBoxRayIntersection2D intersection = _domain.closestIntersection(ray); if (intersection.isIntersecting) { double tStart, tEnd; if (intersection.tFar == kMaxD) { tStart = 0.0; tEnd = intersection.tNear; } else { tStart = intersection.tNear; tEnd = intersection.tFar; } double t = tStart; Vector2D pt = ray.pointAt(t); double prevPhi = _func(pt); while (t <= tEnd) { pt = ray.pointAt(t); const double newPhi = _func(pt); const double newPhiAbs = std::fabs(newPhi); if (newPhi * prevPhi < 0.0) { const double frac = prevPhi / (prevPhi - newPhi); const double tSub = t + _rayMarchingResolution * frac; result.isIntersecting = true; result.distance = tSub; result.point = ray.pointAt(tSub); result.normal = gradientLocal(result.point); if (result.normal.length() > 0.0) { result.normal.normalize(); } return result; } t += std::max(newPhiAbs, _rayMarchingResolution); prevPhi = newPhi; } } return result; }
TEST(Ray2, PointAt) { Ray2D ray; EXPECT_EQ(Vector2D(4.5, 0.0), ray.pointAt(4.5)); }