feat: 测试覆盖扩展 + 文档更新
This commit is contained in:
@@ -1 +1,2 @@
|
||||
add_vde_test(test_gjk)
|
||||
add_vde_test(test_ray)
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
#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();
|
||||
}
|
||||
Reference in New Issue
Block a user