bool Triangle3::intersectsLocal(const Ray3D& ray) const { Vector3D n = faceNormal(); double nd = n.dot(ray.direction); if (nd < std::numeric_limits<double>::epsilon()) { return false; } double d = n.dot(points[0]); double t = (d - n.dot(ray.origin)) / nd; if (t < 0.0) { return false; } Vector3D q = ray.pointAt(t); Vector3D q01 = (points[1] - points[0]).cross(q - points[0]); if (n.dot(q01) <= 0.0) { return false; } Vector3D q12 = (points[2] - points[1]).cross(q - points[1]); if (n.dot(q12) <= 0.0) { return false; } Vector3D q02 = (points[0] - points[2]).cross(q - points[2]); if (n.dot(q02) <= 0.0) { return false; } return true; }
SurfaceRayIntersection3 Triangle3::closestIntersectionLocal( const Ray3D& ray) const { SurfaceRayIntersection3 intersection; Vector3D n = faceNormal(); double nd = n.dot(ray.direction); if (nd < std::numeric_limits<double>::epsilon()) { intersection.isIntersecting = false; return intersection; } double d = n.dot(points[0]); double t = (d - n.dot(ray.origin)) / nd; if (t < 0.0) { intersection.isIntersecting = false; return intersection; } Vector3D q = ray.pointAt(t); Vector3D q01 = (points[1] - points[0]).cross(q - points[0]); if (n.dot(q01) <= 0.0) { intersection.isIntersecting = false; return intersection; } Vector3D q12 = (points[2] - points[1]).cross(q - points[1]); if (n.dot(q12) <= 0.0) { intersection.isIntersecting = false; return intersection; } Vector3D q02 = (points[0] - points[2]).cross(q - points[2]); if (n.dot(q02) <= 0.0) { intersection.isIntersecting = false; return intersection; } double a = area(); double b0 = 0.5 * q12.length() / a; double b1 = 0.5 * q02.length() / a; double b2 = 0.5 * q01.length() / a; Vector3D normal = b0 * normals[0] + b1 * normals[1] + b2 * normals[2]; intersection.isIntersecting = true; intersection.distance = t; intersection.point = q; intersection.normal = normal.normalized(); return intersection; }
SurfaceRayIntersection3 ImplicitSurfaceSet3::closestIntersectionLocal( const Ray3D& ray) const { buildBvh(); const auto testFunc = [](const Surface3Ptr& surface, const Ray3D& ray) { SurfaceRayIntersection3 result = surface->closestIntersection(ray); return result.distance; }; const auto queryResult = _bvh.closestIntersection(ray, testFunc); SurfaceRayIntersection3 result; result.distance = queryResult.distance; result.isIntersecting = queryResult.item != nullptr; if (queryResult.item != nullptr) { result.point = ray.pointAt(queryResult.distance); result.normal = (*queryResult.item)->closestNormal(result.point); } return result; }
TEST(Ray3, PointAt) { Ray3D ray; EXPECT_EQ(Vector3D(4.5, 0.0, 0.0), ray.pointAt(4.5)); }