@@ -26,24 +26,19 @@ void cg::world::camera::set_position(float3 in_position)
2626void cg::world::camera::set_theta (float in_theta)
2727{
2828 // TODO Lab: 1.04 Implement `cg::world::camera` class
29- theta = in_theta;
29+ theta = in_theta * static_cast < float >(M_PI) / 180 . f ;
3030}
3131
3232void cg::world::camera::set_phi (float in_phi)
3333{
3434 // TODO Lab: 1.04 Implement `cg::world::camera` class
35- // Ограничим phi, чтобы избежать выворота вверх/вниз
36- const float limit = static_cast <float >(M_PI_2 - 1e-4 );
37- if (in_phi > limit) in_phi = limit;
38- if (in_phi < -limit) in_phi = -limit;
39- phi = in_phi;
35+ phi = in_phi * static_cast <float >(M_PI) / 180 .f ;
4036}
4137
4238void cg::world::camera::set_angle_of_view (float in_aov)
4339{
4440 // TODO Lab: 1.04 Implement `cg::world::camera` class
45- // Ожидается, что сюда приходит значение в градусах из settings — переведём в радианы
46- angle_of_view = in_aov * static_cast <float >(M_PI / 180.0 );
41+ angle_of_view = in_aov * static_cast <float >(M_PI) / 180 .f ;
4742}
4843
4944void cg::world::camera::set_height (float in_height)
@@ -75,30 +70,19 @@ void cg::world::camera::set_z_far(float in_z_far)
7570const float4x4 cg::world::camera::get_view_matrix () const
7671{
7772 // TODO Lab: 1.04 Implement `cg::world::camera` class
78- // Вычислим базис камеры из углов
79- const float cth = cosf (theta), sth = sinf (theta);
80- const float cph = cosf (phi), sph = sinf (phi);
81-
82- const float3 dir{
83- cth * cph,
84- sph,
85- sth * cph
86- };
87- const float3 up_world{ 0 .f , 1 .f , 0 .f };
88-
89- // right = normalize(cross(up, dir))
73+ // Классический look-at: оси камеры и сдвиг
74+ const float3 up_world{0 .f , 1 .f , 0 .f };
75+ const float3 dir = get_direction ();
9076 const float3 right = normalize (cross (up_world, dir));
91- // up = cross(dir, right)
9277 const float3 up = cross (dir, right);
9378
94- // Look-at матрица (row-major): R и t = -R * pos
95- float4x4 V {
79+ // Праворукая система; третья строка соответствует -dir
80+ return float4x4 {
9681 { right.x , right.y , right.z , -dot (right, position) },
9782 { up.x , up.y , up.z , -dot (up, position) },
9883 { -dir.x , -dir.y , -dir.z , dot (dir, position) },
9984 { 0 .f , 0 .f , 0 .f , 1 .f }
10085 };
101- return V;
10286}
10387
10488#ifdef DX12
@@ -124,20 +108,14 @@ const DirectX::XMMATRIX camera::get_dxm_mvp_matrix() const
124108const float4x4 cg::world::camera::get_projection_matrix () const
125109{
126110 // TODO Lab: 1.04 Implement `cg::world::camera` class
127- // Перспективная матрица RH с диапазоном глубины [-1,1] в clip (стандартная учебная форма)
128- const float f = 1 .0f / tanf (angle_of_view * 0 .5f );
129- const float A = f / aspect_ratio;
130- const float B = f;
131- const float C = -(z_far + z_near) / (z_far - z_near);
132- const float D = -(2 .f * z_far * z_near) / (z_far - z_near);
133-
134- float4x4 P{
135- { A, 0 .f , 0 .f , 0 .f },
136- { 0 .f , B, 0 .f , 0 .f },
137- { 0 .f , 0 .f , C, D },
138- { 0 .f , 0 .f , -1 .f , 0 .f }
111+ // Праворукая перспектива с NDC z в [-1,1]
112+ const float f = 1 .f / tanf (angle_of_view * 0 .5f );
113+ return float4x4{
114+ { f / aspect_ratio, 0 .f , 0 .f , 0 .f },
115+ { 0 .f , f, 0 .f , 0 .f },
116+ { 0 .f , 0 .f , z_far / (z_near - z_far), -1 .f },
117+ { 0 .f , 0 .f , (z_far * z_near) / (z_near - z_far), 0 .f }
139118 };
140- return P;
141119}
142120
143121const float3 cg::world::camera::get_position () const
@@ -149,27 +127,24 @@ const float3 cg::world::camera::get_position() const
149127const float3 cg::world::camera::get_direction () const
150128{
151129 // TODO Lab: 1.04 Implement `cg::world::camera` class
152- const float cth = cosf (theta), sth = sinf (theta);
153- const float cph = cosf (phi), sph = sinf (phi);
154- const float3 dir{ cth * cph, sph, sth * cph };
155- return normalize (dir);
156-
130+ // Направление из yaw=theta и pitch=phi; при theta=0, phi=0 — взгляд вдоль -Z
131+ return float3{
132+ sinf (theta) * cosf (phi),
133+ sinf (phi),
134+ -cosf (theta) * cosf (phi)
135+ };
157136}
158137
159138const float3 cg::world::camera::get_right () const
160139{
161140 // TODO Lab: 1.04 Implement `cg::world::camera` class
162- const float3 up_world{ 0 .f , 1 .f , 0 .f };
163- const float3 dir = get_direction ();
164- return normalize (cross (up_world, dir));
141+ return normalize (cross (float3{0 .f , 1 .f , 0 .f }, get_direction ()));
165142}
166143
167144const float3 cg::world::camera::get_up () const
168145{
169146 // TODO Lab: 1.04 Implement `cg::world::camera` class
170- const float3 dir = get_direction ();
171- const float3 right = get_right ();
172- return cross (dir, right);
147+ return cross (get_direction (), get_right ());
173148}
174149const float camera::get_theta () const
175150{
0 commit comments