rework API
This commit is contained in:
@@ -28,48 +28,56 @@ namespace
|
||||
TEST_CASE("RaySphereIntersection")
|
||||
{
|
||||
auto sphere = GeometryFactory::MakeSphere(1, 32, 16);
|
||||
RayHit h1, h2;
|
||||
// 2 intersections
|
||||
{
|
||||
RayHit h1, h2;
|
||||
Ray ray(Vector3f(0, 0, -5), Vector3f(0, 0, 1));
|
||||
REQUIRE(ray.IntersectSphere(Vector3f(0), 1, h1, h2) == 2);
|
||||
REQUIRE((h1.point == Vector3f(0, 0, -1) && h2.point == Vector3f(0, 0, 1)));
|
||||
REQUIRE((h1.normal == Vector3f(0, 0, -1) && h2.normal == Vector3f(0, 0, 1)));
|
||||
REQUIRE(h1.distance < h2.distance);
|
||||
REQUIRE((h1.distance == distance(ray.GetOrigin(), h1.point) && h2.distance == distance(ray.GetOrigin(), h2.point)));
|
||||
REQUIRE(h1.distance2 < h2.distance2);
|
||||
REQUIRE((h1.GetDistance() == distance(ray.GetOrigin(), h1.point)
|
||||
&& h2.GetDistance() == distance(ray.GetOrigin(), h2.point)));
|
||||
REQUIRE_THAT(h1.GetDistance(), Catch::Matchers::WithinRel(std::sqrt(h1.distance2)));
|
||||
// this returns just closest point
|
||||
if (auto opt = ray.IntersectSphere(Vector3f(0), 1))
|
||||
{
|
||||
opt->GetDistance();
|
||||
REQUIRE(opt.value() == h1);
|
||||
}
|
||||
}
|
||||
// 1 intersection
|
||||
{
|
||||
RayHit h1, h2;
|
||||
Ray ray(Vector3f(1, 0, -1), Vector3f(0, 0, 1));
|
||||
REQUIRE(ray.IntersectSphere(Vector3f(0), 1, h1, h2) == 1);
|
||||
REQUIRE(h1 == h2);
|
||||
REQUIRE(h1.point == Vector3f(1, 0, 0));
|
||||
REQUIRE(ray.IntersectSphere(Vector3f(0), 1).value() == h1);
|
||||
REQUIRE(ray.IntersectSphere(Vector3f(0), 1) == h1);
|
||||
}
|
||||
// 0 intersections
|
||||
{
|
||||
RayHit h1, h2;
|
||||
Ray ray(Vector3f(2, 0, -1), Vector3f(0, 0, 1));
|
||||
REQUIRE(ray.IntersectSphere(Vector3f(0), 1, h1, h2) == 0);
|
||||
REQUIRE(!ray.IntersectSphere(Vector3f(0), 1).has_value());
|
||||
}
|
||||
// ray is inside sphere
|
||||
{
|
||||
RayHit h1, h2;
|
||||
Ray ray(Vector3f(0, 0, 0), Vector3f(0.5, 0.5, 1));
|
||||
REQUIRE(ray.IntersectSphere(Vector3f(0), 1, h1, h2) == 1);
|
||||
REQUIRE(h1 == h2);
|
||||
::CompareVec3Approx(h1.normal, h1.point);
|
||||
auto value = ray.IntersectSphere(Vector3f(0), 1);
|
||||
REQUIRE(value->distance == h1.distance);
|
||||
REQUIRE(value->GetDistance() == h1.GetDistance());
|
||||
REQUIRE_THAT(value->distance2, Catch::Matchers::WithinRel(h1.distance2));
|
||||
::CompareVec3Approx(value->normal, h1.normal);
|
||||
::CompareVec3Approx(value->point, h1.point);
|
||||
}
|
||||
// ray intersects sphere behind the origin
|
||||
{
|
||||
RayHit h1, h2;
|
||||
Ray ray(Vector3f(0, 0, 3), Vector3f(0, 0, 1));
|
||||
REQUIRE(ray.IntersectSphere(Vector3f(0), 1, h1, h2) == 0);
|
||||
REQUIRE(!ray.IntersectSphere(Vector3f(0), 1).has_value());
|
||||
@@ -79,31 +87,30 @@ TEST_CASE("RaySphereIntersection")
|
||||
TEST_CASE("RayTriangleIntersection")
|
||||
{
|
||||
auto tri = GeometryFactory::MakeTriangle(Vector3f(0), Vector3f(3, 0, 0), Vector3f(1.5, 2, 0));
|
||||
std::optional<RayHit> hit;
|
||||
// intersects
|
||||
{
|
||||
Ray ray(Vector3f(1.5, 2, -5), Vector3f(0, 0, 1));
|
||||
hit = ray.IntersectTriangle(tri.vertices[0].position, tri.vertices[1].position, tri.vertices[2].position);
|
||||
std::optional<RayHit> hit = ray.IntersectTriangle(tri.vertices[0].position, tri.vertices[1].position, tri.vertices[2].position);
|
||||
REQUIRE(hit.has_value());
|
||||
REQUIRE(hit->distance == distance(ray.GetOrigin(), hit->point));
|
||||
REQUIRE(hit->GetDistance() == distance(ray.GetOrigin(), hit->point));
|
||||
REQUIRE(hit->point == Vector3f(1.5, 2, 0));
|
||||
}
|
||||
{
|
||||
Ray ray(Vector3f(1.5, 1, -1), Vector3f(0, 0, 1));
|
||||
hit = ray.IntersectTriangle(tri.vertices[0].position, tri.vertices[1].position, tri.vertices[2].position);
|
||||
std::optional<RayHit> hit = ray.IntersectTriangle(tri.vertices[0].position, tri.vertices[1].position, tri.vertices[2].position);
|
||||
REQUIRE(hit.has_value());
|
||||
REQUIRE(hit->distance == distance(ray.GetOrigin(), hit->point));
|
||||
REQUIRE(hit->GetDistance() == distance(ray.GetOrigin(), hit->point));
|
||||
REQUIRE(hit->point == Vector3f(1.5, 1, 0));
|
||||
}
|
||||
// no intersections
|
||||
{
|
||||
Ray ray(Vector3f(5, 0, 0), Vector3f(0, 0, 1));
|
||||
hit = ray.IntersectTriangle(tri.vertices[0].position, tri.vertices[1].position, tri.vertices[2].position);
|
||||
std::optional<RayHit> hit = ray.IntersectTriangle(tri.vertices[0].position, tri.vertices[1].position, tri.vertices[2].position);
|
||||
REQUIRE(!hit.has_value());
|
||||
}
|
||||
{
|
||||
Ray ray(Vector3f(1.5, 1, 0.5), Vector3f(0, 0, 1));
|
||||
hit = ray.IntersectTriangle(tri.vertices[0].position, tri.vertices[1].position, tri.vertices[2].position);
|
||||
std::optional<RayHit> hit = ray.IntersectTriangle(tri.vertices[0].position, tri.vertices[1].position, tri.vertices[2].position);
|
||||
REQUIRE(!hit.has_value());
|
||||
}
|
||||
}
|
||||
@@ -141,52 +148,59 @@ TEST_CASE("RayAABBIntersection")
|
||||
auto sphere = GeometryFactory::MakeSphere(1, 32, 16);
|
||||
sphere.CalculateAABB();
|
||||
std::optional<RayHit> hit;
|
||||
RayHit h1, h2;
|
||||
// intersects
|
||||
{
|
||||
RayHit h1, h2;
|
||||
Ray ray(Vector3f(0, 0, -2), Vector3f(0, 0, 1));
|
||||
REQUIRE(ray.IntersectAABB(sphere.aabb, h1, h2) == 2);
|
||||
REQUIRE(h1.distance < h2.distance);
|
||||
REQUIRE(h1.distance2 < h2.distance2);
|
||||
REQUIRE(h1.point == Vector3f(0, 0, -1));
|
||||
REQUIRE(h2.point == Vector3f(0, 0, 1));
|
||||
auto p = ray.IntersectAABB(sphere.aabb);
|
||||
REQUIRE(p->point == h1.point);
|
||||
REQUIRE(p->distance == h1.distance);
|
||||
REQUIRE(p->distance2 == h1.distance2);
|
||||
REQUIRE(p->GetDistance() == h1.GetDistance());
|
||||
}
|
||||
{
|
||||
RayHit h1, h2;
|
||||
Ray ray(Vector3f(0, 0, 1), Vector3f(0, 0, 1));
|
||||
REQUIRE(ray.IntersectAABB(sphere.aabb, h1, h2) == 1);
|
||||
REQUIRE(h1.distance == h2.distance);
|
||||
REQUIRE(h1.distance2 == h2.distance2);
|
||||
CompareVec3Approx(h1.point, h2.point);
|
||||
REQUIRE(h1.point == Vector3f(0, 0, 1));
|
||||
REQUIRE(ray.IntersectAABB(sphere.aabb)->distance == h1.distance);
|
||||
REQUIRE(ray.IntersectAABB(sphere.aabb)->distance2 == h1.distance2);
|
||||
}
|
||||
{
|
||||
RayHit h1, h2;
|
||||
// inside sphere
|
||||
Ray ray(Vector3f(0), Vector3f(0.3));
|
||||
REQUIRE(ray.IntersectAABB(sphere.aabb, h1, h2) == 1);
|
||||
REQUIRE(h1 == h2);
|
||||
auto val = ray.IntersectAABB(sphere.aabb);
|
||||
REQUIRE(val.has_value());
|
||||
REQUIRE_THAT(val->distance, Catch::Matchers::WithinRel(h1.distance));
|
||||
REQUIRE_THAT(val->distance2, Catch::Matchers::WithinRel(h1.distance2));
|
||||
CompareVec3Approx(val->point, h1.point);
|
||||
}
|
||||
{
|
||||
RayHit h1, h2;
|
||||
Ray ray(Vector3f(2, -0.5, 1.5), Vector3f(-2, 0.5, -1.5));
|
||||
REQUIRE(ray.IntersectAABB(sphere.aabb, h1, h2) == 2);
|
||||
REQUIRE(h1.distance < h2.distance);
|
||||
REQUIRE(h1.distance2 < h2.distance2);
|
||||
auto val = ray.IntersectAABB(sphere.aabb);
|
||||
REQUIRE(val.has_value());
|
||||
REQUIRE(val->distance == h1.distance);
|
||||
REQUIRE(val->distance2 == h1.distance2);
|
||||
REQUIRE_THAT(val->GetDistance(), Catch::Matchers::WithinRel(h1.GetDistance()));
|
||||
CompareVec3Approx(val->point, h1.point);
|
||||
}
|
||||
// no intersections
|
||||
{
|
||||
RayHit h1, h2;
|
||||
Ray ray(Vector3f(3, 0, 1), Vector3f(0, 0, 1));
|
||||
REQUIRE(ray.IntersectAABB(sphere.aabb, h1, h2) == 0);
|
||||
REQUIRE(!ray.IntersectAABB(sphere.aabb).has_value());
|
||||
}
|
||||
{
|
||||
RayHit h1, h2;
|
||||
Ray ray(Vector3f(0, 0, 1.1), Vector3f(0, 0, 1));
|
||||
REQUIRE(ray.IntersectAABB(sphere.aabb, h1, h2) == 0);
|
||||
REQUIRE(!ray.IntersectAABB(sphere.aabb).has_value());
|
||||
@@ -202,7 +216,7 @@ TEST_CASE("RayPlaneIntersection")
|
||||
auto hit = ray.IntersectPlane(pOrigin, pNorm);
|
||||
REQUIRE(hit.has_value());
|
||||
REQUIRE(hit->normal == pNorm);
|
||||
REQUIRE(hit->distance == 2.f);
|
||||
REQUIRE(hit->GetDistance() == 2.f);
|
||||
REQUIRE(hit->point == Vector3f(2, 0, 2));
|
||||
}
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user