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;
}
예제 #3
0
TEST(Ray2, PointAt) {
    Ray2D ray;
    EXPECT_EQ(Vector2D(4.5, 0.0), ray.pointAt(4.5));
}