16TEST(TestPerspectiveCamera, CreateWithDefaultValues) {
18 std::make_unique<PerspectiveCamera>(60.0f, 16.0f / 9.0f, 0.1f, 100.0f);
21 EXPECT_FLOAT_EQ(camera->fov().value(), 60.0f);
22 EXPECT_FLOAT_EQ(camera->aspect().value(), 16.0f / 9.0f);
23 EXPECT_FLOAT_EQ(camera->near().value(), 0.1f);
24 EXPECT_FLOAT_EQ(camera->far().value(), 100.0f);
27 EXPECT_FLOAT_EQ(camera->position().value()[0], 0.0f);
28 EXPECT_FLOAT_EQ(camera->position().value()[1], 0.0f);
29 EXPECT_FLOAT_EQ(camera->position().value()[2], -1.0f);
31 EXPECT_FLOAT_EQ(camera->target().value()[0], 0.0f);
32 EXPECT_FLOAT_EQ(camera->target().value()[1], 0.0f);
33 EXPECT_FLOAT_EQ(camera->target().value()[2], 0.0f);
35 EXPECT_FLOAT_EQ(camera->up().value()[0], 0.0f);
36 EXPECT_FLOAT_EQ(camera->up().value()[1], 1.0f);
37 EXPECT_FLOAT_EQ(camera->up().value()[2], 0.0f);
43TEST(TestPerspectiveCamera, CreateWithCustomValues) {
45 std::make_unique<PerspectiveCamera>(45.0f, 4.0f / 3.0f, 1.0f, 1000.0f);
47 EXPECT_FLOAT_EQ(camera->fov().value(), 45.0f);
48 EXPECT_FLOAT_EQ(camera->aspect().value(), 4.0f / 3.0f);
49 EXPECT_FLOAT_EQ(camera->near().value(), 1.0f);
50 EXPECT_FLOAT_EQ(camera->far().value(), 1000.0f);
56TEST(TestPerspectiveCamera, ProjectionMatrixCalculation) {
58 std::make_unique<PerspectiveCamera>(90.0f, 1.0f, 0.1f, 100.0f);
61 const auto& P = camera->projection_matrix();
64 EXPECT_NE(P[0][0], 0.0f);
65 EXPECT_NE(P[1][1], 0.0f);
66 EXPECT_NE(P[2][2], 0.0f);
67 EXPECT_NE(P[2][3], 0.0f);
68 EXPECT_EQ(P[3][2], -1.0f);
72 float expected_f = 1.0f / tan(90.0f * 3.14159265358979323846f / 360.0f);
73 EXPECT_NEAR(P[0][0], expected_f, 1e-5f);
74 EXPECT_NEAR(P[1][1], expected_f, 1e-5f);
80TEST(TestPerspectiveCamera, ViewMatrixLookAt) {
82 std::make_unique<PerspectiveCamera>(60.0f, 16.0f / 9.0f, 0.1f, 100.0f);
85 camera->position().value() = {0.0f, 0.0f, -5.0f};
86 camera->target().value() = {0.0f, 0.0f, 0.0f};
87 camera->up().value() = {0.0f, 1.0f, 0.0f};
90 const auto& V = camera->view_matrix();
94 EXPECT_NEAR(V[0][2], 0.0f, 1e-5f);
97TEST(TestPerspectiveCamera, VPTransformWholeVectors_Strict) {
98 auto cam = std::make_unique<PerspectiveCamera>(60.0f,
103 cam->set_position(0, 0, -5)->set_target(0, 0, 0)->set_up(0, 1, 0);
105 const auto& V = cam->view_matrix();
106 const auto& P = cam->projection_matrix();
107 const auto VP = P ^ V;
108 const auto VP_inv = VP.inv();
111 const float n = 0.1f;
112 const float f = 100.0f;
113 const float a = 16.0f / 9.0f;
114 const float tanHalf = std::tan(60.0f * 0.5f *
float(
xcmath::PI) / 180.0f);
115 const float halfH = n * tanHalf;
116 const float halfW = a * halfH;
118 auto worldFromNDC = [&](
float x_ndc,
float y_ndc,
121 float clip_w = (2.0f * f * n) / (f + n - z_ndc * (f - n));
124 float clip_x = x_ndc * clip_w;
125 float clip_y = y_ndc * clip_w;
126 float clip_z = z_ndc * clip_w;
131 return world4.
xyz() / world4.
w();
135 for (
int iz = -1; iz <= 1; ++iz) {
136 for (
int iy = -1; iy <= 1; ++iy) {
137 for (
int ix = -1; ix <= 1; ++ix) {
139 auto world = worldFromNDC(ndc.x(), ndc.y(), ndc.z());
147 EXPECT_NEAR(back.
x(), ndc.x(), 1e-4f);
148 EXPECT_NEAR(back.
y(), ndc.y(), 1e-4f);
149 EXPECT_NEAR(back.
z(), ndc.z(), 1e-4f);