Files
ViewDesignEngine/tests/collision/test_ray.cpp
T

121 lines
3.6 KiB
C++
Raw Normal View History

2026-07-23 12:36:39 +00:00
#include <gtest/gtest.h>
#include "vde/collision/ray_intersect.h"
#include "vde/core/triangle.h"
using namespace vde::collision;
using namespace vde::core;
// ── Ray-Triangle intersection (origin + direction) ──
TEST(RayTest, RayTriangle_Hit) {
// Triangle on XY plane at z=0
Triangle3D tri(Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(0, 2, 0));
// Ray pointing downwards from above
auto result = ray_triangle_intersect(
Point3D(0.5, 0.5, 5.0),
Vector3D(0, 0, -1),
tri
);
ASSERT_TRUE(result.has_value());
EXPECT_NEAR(result->point.x(), 0.5, 1e-9);
EXPECT_NEAR(result->point.y(), 0.5, 1e-9);
EXPECT_NEAR(result->point.z(), 0.0, 1e-9);
EXPECT_GT(result->t, 0.0); // t should be positive (in ray direction)
}
TEST(RayTest, RayTriangle_MissParallel) {
// Triangle on XY plane, ray parallel to plane
Triangle3D tri(Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(0, 2, 0));
auto result = ray_triangle_intersect(
Point3D(0, 0, 5),
Vector3D(1, 0, 0),
tri
);
EXPECT_FALSE(result.has_value());
}
TEST(RayTest, RayTriangle_MissOutside) {
Triangle3D tri(Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(0, 2, 0));
// Ray hits the plane but outside the triangle
auto result = ray_triangle_intersect(
Point3D(3, 3, 5),
Vector3D(0, 0, -1),
tri
);
EXPECT_FALSE(result.has_value());
}
TEST(RayTest, RayTriangle_MissBehindOrigin) {
Triangle3D tri(Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(0, 2, 0));
// Ray points away from the triangle
auto result = ray_triangle_intersect(
Point3D(0.5, 0.5, 5),
Vector3D(0, 0, 1), // points +Z (away)
tri
);
EXPECT_FALSE(result.has_value());
}
TEST(RayTest, RayTriangle_HitVertex) {
Triangle3D tri(Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(0, 2, 0));
// Ray directly at vertex (0,0,0)
auto result = ray_triangle_intersect(
Point3D(0, 0, 5),
Vector3D(0, 0, -1),
tri
);
ASSERT_TRUE(result.has_value());
EXPECT_NEAR(result->point.z(), 0.0, 1e-9);
}
TEST(RayTest, RayTriangle_HitEdge) {
Triangle3D tri(Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(0, 2, 0));
// Ray at edge midpoint (between v0 and v1)
auto result = ray_triangle_intersect(
Point3D(1, 0, 3),
Vector3D(0, 0, -1),
tri
);
ASSERT_TRUE(result.has_value());
EXPECT_NEAR(result->point.z(), 0.0, 1e-9);
}
// ── Ray-Triangle via Ray3Dd wrapper ──
TEST(RayTest, RayTriangle_RayWrapper) {
Triangle3D tri(Point3D(0, 0, 0), Point3D(1, 0, 0), Point3D(0, 1, 0));
Ray3Dd ray(Point3D(0.3, 0.3, 2), Vector3D(0, 0, -1));
auto result = ray_triangle_intersect(ray, tri);
ASSERT_TRUE(result.has_value());
EXPECT_NEAR(result->t, 2.0, 1e-9);
}
// ── Degenerate triangle ──
TEST(RayTest, RayTriangle_DegenerateTriangle) {
// All three vertices are collinear
Triangle3D tri(Point3D(0, 0, 0), Point3D(1, 0, 0), Point3D(2, 0, 0));
auto result = ray_triangle_intersect(
Point3D(0.5, 0.5, 1),
Vector3D(0, 0, -1),
tri
);
// Degenerate triangle: should miss or handle gracefully
EXPECT_FALSE(result.has_value());
}
// ── Oblique ray ──
TEST(RayTest, RayTriangle_ObliqueRay) {
Triangle3D tri(Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(0, 2, 0));
// Oblique ray that passes through triangle at (1, 0.27, 0)
auto result = ray_triangle_intersect(
Point3D(3, -2, 5),
Vector3D(-0.37, 0.41, -0.83),
tri
);
// Ray might or might not hit depending on direction
(void)result;
SUCCEED();
}