Tatooine
matrices.h
Go to the documentation of this file.
1#ifndef TATOOINE_RENDERING_MATRICES_H
2#define TATOOINE_RENDERING_MATRICES_H
3//==============================================================================
4#include <tatooine/mat.h>
5
6#include <cmath>
7//==============================================================================
8namespace tatooine::rendering {
9//==============================================================================
10template <typename Real>
11auto constexpr translation_matrix(Real const x, Real const y, Real const z) {
12 auto constexpr O = Real(0);
13 auto constexpr I = Real(1);
14 return Mat4<Real>{{I, O, O, x}, {O, I, O, y}, {O, O, I, z}, {O, O, O, I}};
15}
16//------------------------------------------------------------------------------
17template <typename Real>
18auto constexpr translation_matrix(Vec3<Real> const& t) {
19 auto constexpr O = Real(0);
20 auto constexpr I = Real(1);
21 return Mat4<Real>{
22 {I, O, O, t.x()}, {O, I, O, t.y()}, {O, O, I, t.z()}, {O, O, O, I}};
23}
24//------------------------------------------------------------------------------
25template <typename Real>
26auto constexpr scale_matrix(Real s) {
27 auto constexpr O = Real(0);
28 auto constexpr I = Real(1);
29 return Mat4<Real>{{s, O, O, O}, {O, s, O, O}, {O, O, s, O}, {O, O, O, I}};
30}
31//------------------------------------------------------------------------------
32template <typename Real>
33auto constexpr scale_matrix(Real x, Real y, Real z) {
34 auto constexpr O = Real(0);
35 auto constexpr I = Real(1);
36 return Mat4<Real>{{x, O, O, O}, {O, y, O, O}, {O, O, z, O}, {O, O, O, I}};
37}
38//------------------------------------------------------------------------------
39template <typename Real>
40auto constexpr scale_matrix(Vec3<Real> const& s) {
41 auto constexpr O = Real(0);
42 auto constexpr I = Real(1);
43 return Mat4<Real>{
44 {s.x(), O, O, O}, {O, s.y(), O, O}, {O, O, s.z(), O}, {O, O, O, I}};
45}
46//------------------------------------------------------------------------------
47template <typename Real>
48auto constexpr rotation_matrix(Real angle, Real u, Real v, Real w)
49 -> Mat4<Real> {
50 Real const s = gcem::sin(angle);
51 Real const c = gcem::cos(angle);
52 auto constexpr O = Real(0);
53 auto constexpr I = Real(1);
54 return Mat4<Real>{{u * u + (v * v + w * w) * c, u * v * (1 - c) - w * s,
55 u * w * (1 - c) + v * s, O},
56 {u * v + (1 - c) + w * s, v * v * (u * u + w * w) * c,
57 v * w * (1 - c) + u * s, O},
58 {u * w + (1 - c) - v * s, v * v * (1 - c) + u * s,
59 w * w + (u * u + v * v) * c, O},
60 {O, O, O, I}};
61}
62//------------------------------------------------------------------------------
63template <typename Real>
64auto constexpr rotation_matrix(Real angle, Vec3<Real> const& axis) {
65 return rotation_matrix(angle, axis(0), axis(1), axis(2));
66}
67//------------------------------------------------------------------------------
68template <typename Real>
69auto constexpr orthographic_matrix(Real const left, Real const right,
70 Real const bottom, Real const top,
71 Real const near, Real const far) {
72 auto constexpr O = Real(0);
73 auto constexpr I = Real(1);
74 auto const width = right - left;
75 auto const inv_width = 1 / width;
76 auto const height = top - bottom;
77 auto const inv_height = 1 / height;
78 auto const depth = far - near;
79 auto const inv_depth = 1 / depth;
80
81 return Mat4<Real>{{2 * inv_width, O, O, -(right + left) * inv_width},
82 {O, 2 * inv_height, O, -(top + bottom) * inv_height},
83 {O, O, -2 * inv_depth, -(far + near) * inv_depth},
84 {O, O, O, I}};
85}
86//==============================================================================
88template <typename Real>
89auto constexpr look_at_matrix_left_hand(Vec3<Real> const& eye,
90 Vec3<Real> const& center,
91 Vec3<Real> const& up = {0, 1, 0})
92 -> Mat4<Real> {
93 auto constexpr O = Real(0);
94 auto constexpr I = Real(1);
95
96 auto const zaxis = normalize(center - eye);
97 auto const xaxis = cross(zaxis, normalize(up));
98 auto const yaxis = cross(xaxis, zaxis);
99 return Mat4<Real>{{xaxis.x(), yaxis.x(), zaxis.x(), eye.x()},
100 {xaxis.y(), yaxis.y(), zaxis.y(), eye.y()},
101 {xaxis.z(), yaxis.z(), zaxis.z(), eye.z()},
102 {O, O, O, I}};
103}
104//------------------------------------------------------------------------------
106template <typename Real>
107auto constexpr inv_look_at_matrix_left_hand(Vec3<Real> const& eye,
108 Vec3<Real> const& center,
109 Vec3<Real> const& up = {0, 1, 0}) {
110 auto constexpr O = Real(0);
111 auto constexpr I = Real(1);
112
113 auto const zaxis = normalize(center - eye);
114 auto const xaxis = cross(zaxis, normalize(up));
115 auto const yaxis = cross(xaxis, zaxis);
116
117 return Mat4<Real>{{xaxis.x(), xaxis.y(), xaxis.z(), -dot(xaxis, eye)},
118 {yaxis.x(), yaxis.y(), yaxis.z(), -dot(yaxis, eye)},
119 {zaxis.x(), zaxis.y(), zaxis.z(), -dot(zaxis, eye)},
120 {O, O, O, I}};
121}
122//------------------------------------------------------------------------------
124template <typename Real>
125auto constexpr look_at_matrix_right_hand(Vec3<Real> const& eye,
126 Vec3<Real> const& center,
127 Vec3<Real> const& up = {0, 1, 0}) {
128 auto const zaxis = normalize(eye - center);
129 auto const xaxis = cross(normalize(up), zaxis);
130 auto const yaxis = cross(zaxis, xaxis);
131 return Mat4<Real>{{xaxis.x(), yaxis.x(), zaxis.x(), eye.x()},
132 {xaxis.y(), yaxis.y(), zaxis.y(), eye.y()},
133 {xaxis.z(), yaxis.z(), zaxis.z(), eye.z()},
134 {Real(0), Real(0), Real(0), Real(1)}};
135}
136//------------------------------------------------------------------------------
138template <typename Real>
140 Vec3<Real> const& center,
141 Vec3<Real> const& up = {0, 1, 0}) {
142 auto constexpr O = Real(0);
143 auto constexpr I = Real(1);
144
145 auto const zaxis = normalize(eye - center);
146 auto const xaxis = cross(normalize(up), zaxis);
147 auto const yaxis = cross(zaxis, xaxis);
148 return Mat4<Real>{{xaxis.x(), xaxis.y(), xaxis.z(), -dot(xaxis, eye)},
149 {yaxis.x(), yaxis.y(), yaxis.z(), -dot(yaxis, eye)},
150 {zaxis.x(), zaxis.y(), zaxis.z(), -dot(zaxis, eye)},
151 {O, O, O, I}};
152}
153//------------------------------------------------------------------------------
154template <typename Real>
155auto constexpr look_at_matrix(Vec3<Real> const& eye, Vec3<Real> const& center,
156 Vec3<Real> const& up = {0, 1, 0}) -> Mat4<Real> {
157 return look_at_matrix_right_hand(eye, center, up);
158}
159//------------------------------------------------------------------------------
161template <typename Real>
162auto constexpr inv_look_at_matrix(Vec3<Real> const& eye,
163 Vec3<Real> const& center,
164 Vec3<Real> const& up = {0, 1, 0}) {
165 return inv_look_at_matrix_left_hand(eye, center, up);
166}
167//==============================================================================
169template <typename Real>
170auto constexpr fps_look_at_matrix_left_hand(Vec3<Real> const& eye,
171 arithmetic auto const pitch,
172 arithmetic auto const yaw)
173 -> Mat4<Real> {
174 auto constexpr O = Real(0);
175 auto constexpr I = Real(1);
176
177 auto const cos_pitch = gcem::cos(pitch);
178 auto const sin_pitch = gcem::sin(pitch);
179 auto const cos_yaw = gcem::cos(yaw);
180 auto const sin_yaw = gcem::sin(yaw);
181
182 auto xaxis = normalize(vec{-cos_yaw, 0, sin_yaw});
183 auto yaxis =
184 normalize(vec{sin_yaw * sin_pitch, cos_pitch, cos_yaw * sin_pitch});
185 auto zaxis =
186 normalize(vec{-sin_yaw * cos_pitch, sin_pitch, -cos_pitch * cos_yaw});
187
188 return Mat4<Real>{{xaxis.x(), yaxis.x(), zaxis.x(), eye.x()},
189 {xaxis.y(), yaxis.y(), zaxis.y(), eye.y()},
190 {xaxis.z(), yaxis.z(), zaxis.z(), eye.z()},
191 {O, O, O, I}};
192}
193//------------------------------------------------------------------------------
195template <typename Real>
197 arithmetic auto const pitch,
198 arithmetic auto const yaw)
199 -> Mat4<Real> {
200 auto constexpr O = Real(0);
201 auto constexpr I = Real(1);
202
203 auto const cos_pitch = gcem::cos(pitch);
204 auto const sin_pitch = gcem::sin(pitch);
205 auto const cos_yaw = gcem::cos(yaw);
206 auto const sin_yaw = gcem::sin(yaw);
207
208 auto const xaxis = normalize(vec{-cos_yaw, 0, sin_yaw});
209 auto const yaxis =
210 normalize(vec{sin_yaw * sin_pitch, cos_pitch, cos_yaw * sin_pitch});
211 auto const zaxis =
212 normalize(vec{-sin_yaw * cos_pitch, sin_pitch, -cos_pitch * cos_yaw});
213
214 return Mat4<Real>{{xaxis.x(), xaxis.y(), xaxis.z(), -dot(xaxis, eye)},
215 {yaxis.x(), yaxis.y(), yaxis.z(), -dot(yaxis, eye)},
216 {zaxis.x(), zaxis.y(), zaxis.z(), -dot(zaxis, eye)},
217 {O, O, O, I}};
218}
219//------------------------------------------------------------------------------
221template <typename Real>
223 arithmetic auto const pitch,
224 arithmetic auto const yaw)
225 -> Mat4<Real> {
226 auto constexpr O = Real(0);
227 auto constexpr I = Real(1);
228
229 auto cos_pitch = gcem::cos(pitch);
230 auto sin_pitch = gcem::sin(pitch);
231 auto cos_yaw = gcem::cos(yaw);
232 auto sin_yaw = gcem::sin(yaw);
233
234 auto xaxis = normalize(vec{cos_yaw, 0, -sin_yaw});
235 auto yaxis =
236 normalize(vec{sin_yaw * sin_pitch, cos_pitch, cos_yaw * sin_pitch});
237 auto zaxis =
238 normalize(vec{sin_yaw * cos_pitch, -sin_pitch, cos_pitch * cos_yaw});
239
240 return Mat4<Real>{{xaxis.x(), yaxis.x(), zaxis.x(), eye.x()},
241 {xaxis.y(), yaxis.y(), zaxis.y(), eye.y()},
242 {xaxis.z(), yaxis.z(), zaxis.z(), eye.z()},
243 {O, O, O, I}};
244}
245//------------------------------------------------------------------------------
247template <typename Real>
249 arithmetic auto const pitch,
250 arithmetic auto const yaw)
251 -> Mat4<Real> {
252 auto constexpr O = Real(0);
253 auto constexpr I = Real(1);
254
255 auto const cos_pitch = gcem::cos(pitch);
256 auto const sin_pitch = gcem::sin(pitch);
257 auto const cos_yaw = gcem::cos(yaw);
258 auto const sin_yaw = gcem::sin(yaw);
259
260 auto const xaxis = normalize(vec{cos_yaw, 0, -sin_yaw});
261 auto const yaxis =
262 normalize(vec{sin_yaw * sin_pitch, cos_pitch, cos_yaw * sin_pitch});
263 auto const zaxis =
264 normalize(vec{sin_yaw * cos_pitch, -sin_pitch, cos_pitch * cos_yaw});
265
266 return Mat4<Real>{{xaxis.x(), xaxis.y(), xaxis.z(), -dot(xaxis, eye)},
267 {yaxis.x(), yaxis.y(), yaxis.z(), -dot(yaxis, eye)},
268 {zaxis.x(), zaxis.y(), zaxis.z(), -dot(zaxis, eye)},
269 {O, O, O, I}};
270}
271//------------------------------------------------------------------------------
273template <typename Real>
274auto constexpr fps_look_at_matrix(Vec3<Real> const& eye,
275 arithmetic auto const pitch,
276 arithmetic auto const yaw) -> Mat4<Real> {
277 return fps_look_at_matrix_right_hand(eye, pitch, yaw);
278}
279//------------------------------------------------------------------------------
281template <typename Real>
282auto constexpr inv_fps_look_at_matrix(Vec3<Real> const& eye,
283 arithmetic auto const pitch,
284 arithmetic auto const yaw) {
285 return inv_fps_look_at_matrix_left_hand(eye, pitch, yaw);
286}
287//==============================================================================
288template <typename Real>
289auto constexpr frustum_matrix(Real const left, Real const right,
290 Real const bottom, Real const top,
291 Real const near, Real const far) {
292 auto constexpr O = Real(0);
293 auto constexpr I = Real(1);
294
295 auto const n2 = 2 * near;
296 auto const width = right - left;
297 auto const inv_width = 1 / width;
298 auto const xs = n2 * inv_width;
299 auto const xzs = (right + left) * inv_width;
300
301 auto const height = top - bottom;
302 auto const inv_height = 1 / height;
303 auto const ys = n2 * inv_height;
304 auto const yzs = (top + bottom) * inv_height;
305
306 auto const depth = far - near;
307 auto const inv_depth = 1 / depth;
308 auto const zs = -(far + near) * inv_depth;
309 auto const zt = -2 * near * far * inv_depth;
310
311 return Mat4<Real>{
312 {xs, O, xzs, O},
313 { O, ys, yzs, O},
314 { O, O, zs, zt},
315 { O, O, -I, O}};
316}
317//------------------------------------------------------------------------------
318template <typename Real>
319auto constexpr perspective_matrix(Real const fov_angles, Real const aspect_ratio,
320 Real const near, Real const far) {
321 auto constexpr half = Real(1) / Real(2);
322 auto constexpr angles_to_radians_factor = Real(M_PI) / Real(180);
323 auto const fov_radians = fov_angles * angles_to_radians_factor;
324 auto const scale = gcem::tan(fov_radians * half) * near;
325 auto const right = scale * aspect_ratio;
326 auto const left = -right;
327 auto const top = scale;
328 auto const bottom = -top;
329 return frustum_matrix(left, right, bottom, top, near, far);
330 //auto constexpr O = Real(0);
331 //auto constexpr I = Real(1);
332 //auto P = Mat4<Real>{
333 // {2 * near / (right - left), O, (right + left) / (right - left), O},
334 // {O, 2 * near / (top - bottom), (top + bottom) / (top - bottom), O},
335 // {O, O, (far + near) / (far - near), 2 * far * near / (far - near)},
336 // {O, O, -1, O}};
337 //return P;
338}
339//==============================================================================
340} // namespace tatooine::rendering
341//==============================================================================
342#endif
Definition: concepts.h:33
Definition: camera.h:12
auto constexpr fps_look_at_matrix_left_hand(Vec3< Real > const &eye, arithmetic auto const pitch, arithmetic auto const yaw) -> Mat4< Real >
Can be used as transform matrix of an object.
Definition: matrices.h:170
auto constexpr inv_fps_look_at_matrix_left_hand(Vec3< Real > const &eye, arithmetic auto const pitch, arithmetic auto const yaw) -> Mat4< Real >
Can be used as view matrix of a camera.
Definition: matrices.h:196
auto constexpr look_at_matrix_right_hand(Vec3< Real > const &eye, Vec3< Real > const &center, Vec3< Real > const &up={0, 1, 0})
Can be used as transform matrix of an object.
Definition: matrices.h:125
auto constexpr fps_look_at_matrix(Vec3< Real > const &eye, arithmetic auto const pitch, arithmetic auto const yaw) -> Mat4< Real >
Can be used as transform matrix of an object.
Definition: matrices.h:274
auto constexpr rotation_matrix(Real angle, Real u, Real v, Real w) -> Mat4< Real >
Definition: matrices.h:48
auto constexpr inv_look_at_matrix(Vec3< Real > const &eye, Vec3< Real > const &center, Vec3< Real > const &up={0, 1, 0})
Can be used as view matrix of a camera.
Definition: matrices.h:162
auto constexpr look_at_matrix_left_hand(Vec3< Real > const &eye, Vec3< Real > const &center, Vec3< Real > const &up={0, 1, 0}) -> Mat4< Real >
Can be used as transform matrix of an object.
Definition: matrices.h:89
auto constexpr scale_matrix(Real s)
Definition: matrices.h:26
auto constexpr perspective_matrix(Real const fov_angles, Real const aspect_ratio, Real const near, Real const far)
Definition: matrices.h:319
auto constexpr orthographic_matrix(Real const left, Real const right, Real const bottom, Real const top, Real const near, Real const far)
Definition: matrices.h:69
auto constexpr inv_fps_look_at_matrix(Vec3< Real > const &eye, arithmetic auto const pitch, arithmetic auto const yaw)
Can be used as view matrix of a camera.
Definition: matrices.h:282
auto constexpr inv_look_at_matrix_right_hand(Vec3< Real > const &eye, Vec3< Real > const &center, Vec3< Real > const &up={0, 1, 0})
Can be used as view matrix of a camera.
Definition: matrices.h:139
auto constexpr translation_matrix(Real const x, Real const y, Real const z)
Definition: matrices.h:11
auto constexpr inv_fps_look_at_matrix_right_hand(Vec3< Real > const &eye, arithmetic auto const pitch, arithmetic auto const yaw) -> Mat4< Real >
Can be used as view matrix of a camera.
Definition: matrices.h:248
auto constexpr frustum_matrix(Real const left, Real const right, Real const bottom, Real const top, Real const near, Real const far)
Definition: matrices.h:289
auto constexpr look_at_matrix(Vec3< Real > const &eye, Vec3< Real > const &center, Vec3< Real > const &up={0, 1, 0}) -> Mat4< Real >
Definition: matrices.h:155
auto constexpr inv_look_at_matrix_left_hand(Vec3< Real > const &eye, Vec3< Real > const &center, Vec3< Real > const &up={0, 1, 0})
Can be used as view matrix of a camera.
Definition: matrices.h:107
auto constexpr fps_look_at_matrix_right_hand(Vec3< Real > const &eye, arithmetic auto const pitch, arithmetic auto const yaw) -> Mat4< Real >
Can be used as transform matrix of an object.
Definition: matrices.h:222
constexpr auto normalize(base_tensor< Tensor, T, N > const &t_in) -> vec< T, N >
Definition: tensor_operations.h:100
constexpr auto dot(base_tensor< Tensor0, T0, N > const &lhs, base_tensor< Tensor1, T1, N > const &rhs)
Definition: tensor_operations.h:120
constexpr auto angle(base_tensor< Tensor0, T0, N > const &v0, base_tensor< Tensor1, T1, N > const &v1)
Returns the angle of two normalized vectors.
Definition: tensor_operations.h:46
constexpr auto cross(base_tensor< Tensor0, T0, 3 > const &lhs, base_tensor< Tensor1, T1, 3 > const &rhs)
Definition: cross.h:9
Definition: mat.h:14
Definition: vec.h:12
auto constexpr x() const -> auto const &requires(N >=1)
Definition: vec.h:102
auto constexpr z() const -> auto const &requires(N >=3)
Definition: vec.h:122
auto constexpr y() const -> auto const &requires(N >=2)
Definition: vec.h:106