File include/math/matrix/matrix_functions.h changed (mode: 100644) (index e69de29..51f69c3) |
|
1 |
|
#pragma once |
|
2 |
|
|
|
3 |
|
#include "base.h" |
|
4 |
|
#include "../constants.h" |
|
5 |
|
#include "../vector/vector_functions.h" |
|
6 |
|
|
|
7 |
|
#include <math.h> |
|
8 |
|
|
|
9 |
|
namespace math |
|
10 |
|
{ |
|
11 |
|
#define T_IMPL template<typename T> [[nodiscard]] constexpr inline |
|
12 |
|
#define MATRIX(n) matrix<n, n, T> |
|
13 |
|
#define VECTOR(n) vector<n, T> |
|
14 |
|
#define VEC_ARG(n) const vector<n, T>& |
|
15 |
|
#define MATRIXN_IMP \ |
|
16 |
|
template<unsigned int size, typename T> [[nodiscard]] constexpr inline \ |
|
17 |
|
matrix<size, size, T> |
|
18 |
|
|
|
19 |
|
MATRIXN_IMP scale(T scale) |
|
20 |
|
{ |
|
21 |
|
matrix<size, size, T> m{}; |
|
22 |
|
for (unsigned int i = 0; i < size; ++i) |
|
23 |
|
m._[i][i] = scale; |
|
24 |
|
return m; |
|
25 |
|
} |
|
26 |
|
MATRIXN_IMP scale(T n_scale[size]) |
|
27 |
|
{ |
|
28 |
|
matrix<size, size, T> m{}; |
|
29 |
|
for (unsigned int i = 0; i < size; ++i) |
|
30 |
|
m._[i][i] = n_scale[i]; |
|
31 |
|
} |
|
32 |
|
T_IMPL MATRIX(4) |
|
33 |
|
matrix_3x4(VEC_ARG(3) x, VEC_ARG(3) y, VEC_ARG(3) z, VEC_ARG(3) w = {}) { |
|
34 |
|
return {{{ x.x, y.x, z.x, 0 }, |
|
35 |
|
{ x.y, y.y, z.y, 0 }, |
|
36 |
|
{ x.z, y.z, z.z, 0 }, |
|
37 |
|
{ w.x, w.y, w.z, 1 }}}; |
|
38 |
|
} |
|
39 |
|
T_IMPL MATRIX(4) // x, y, z are normalized axis-directions |
|
40 |
|
look_at(VEC_ARG(3) x, VEC_ARG(3) y, VEC_ARG(3) z, VEC_ARG(3) pos = {}) { |
|
41 |
|
const VECTOR(3) w = { - dot(x, pos), - dot(y, pos), - dot(z, pos) }; |
|
42 |
|
return matrix_3x4(x, y, z, w); |
|
43 |
|
} |
|
44 |
|
T_IMPL MATRIX(4) |
|
45 |
|
translation(VEC_ARG(3) pos) { |
|
46 |
|
auto mat = scale<4, T>(1); |
|
47 |
|
mat[3].template part<0,3>() = pos; |
|
48 |
|
return mat; |
|
49 |
|
} |
|
50 |
|
T_IMPL MATRIX(3) |
|
51 |
|
rotation(const vector<3, vector<3, T>> &axis) { |
|
52 |
|
return rotation(axis.x, axis.y, axis.z); |
|
53 |
|
} |
|
54 |
|
T_IMPL MATRIX(4) |
|
55 |
|
projection(const vector<2, T> scale, T z_near, T z_far) { |
|
56 |
|
const T z_scale = z_far / (z_far - z_near); |
|
57 |
|
const T z_shift = - z_scale * z_near; |
|
58 |
|
return {{{ scale.x, 0, 0, 0 }, |
|
59 |
|
{ 0, scale.y, 0, 0 }, |
|
60 |
|
{ 0, 0, z_scale, 1 }, |
|
61 |
|
{ 0, 0, z_shift, 0 }}}; |
|
62 |
|
} |
|
63 |
|
T_IMPL MATRIX(4) |
|
64 |
|
projection_fov_y(T fov_y, T aspect_x_to_y, T z_near, T z_far) { |
|
65 |
|
const T y_scale = 1 / std::tan(fov_y / 2); |
|
66 |
|
const T x_scale = y_scale / aspect_x_to_y; |
|
67 |
|
return projection({x_scale, y_scale}, z_near, z_far); |
|
68 |
|
} |
|
69 |
|
T_IMPL MATRIX(4) |
|
70 |
|
projection_fov_x(T fov_x, T aspect_x_to_y, T z_near, T z_far) { |
|
71 |
|
const T x_scale = 1 / std::tan(fov_x / 2); |
|
72 |
|
const T y_scale = x_scale * aspect_x_to_y; |
|
73 |
|
return projection({x_scale, y_scale}, z_near, z_far); |
|
74 |
|
} |
|
75 |
|
T_IMPL MATRIX(4) |
|
76 |
|
projection_fov_xy(T fov_x, T fov_y, T z_near, T z_far) { |
|
77 |
|
const T x_scale = 1 / std::tan(fov_x / 2); |
|
78 |
|
const T y_scale = 1 / std::tan(fov_y / 2); |
|
79 |
|
return projection({x_scale, y_scale}, z_near, z_far); |
|
80 |
|
} |
|
81 |
|
|
|
82 |
|
T_IMPL MATRIX(3) |
|
83 |
|
rotation(const VECTOR(3)& unit, T radians) |
|
84 |
|
{ |
|
85 |
|
auto &x = unit._[0], &y = unit._[1], &z = unit._[2]; |
|
86 |
|
auto c = gcem::cos(radians), s = gcem::sin(radians), t = math::one<T> - c; |
|
87 |
|
return {{{ t*x*x + c, t*x*y - s*z, t*x*z + s*y }, |
|
88 |
|
{ t*x*y + s*z, t*y*y + c, t*y*z - s*x }, |
|
89 |
|
{ t*x*z - s*y, t*y*z + s*x, t*z*z + c }}}; |
|
90 |
|
} |
|
91 |
|
T_IMPL MATRIX(3) |
|
92 |
|
rotation(T x_angle, T y_angle, T z_angle) |
|
93 |
|
{ |
|
94 |
|
T cosX = gcem::cos<T>(x_angle), sinX = gcem::sin<T>(x_angle); |
|
95 |
|
T cosY = gcem::cos<T>(y_angle), sinY = gcem::sin<T>(y_angle); |
|
96 |
|
T cosZ = gcem::cos<T>(z_angle), sinZ = gcem::sin<T>(z_angle); |
|
97 |
|
|
|
98 |
|
return {{{ cosY*cosZ, -cosX*sinZ + sinX*sinY*cosZ, sinX*sinZ + cosX*sinY*cosZ }, |
|
99 |
|
{ cosY*sinZ, cosX*cosZ + sinX*sinY*sinZ, -sinX*cosZ + cosX*sinY*sinZ }, |
|
100 |
|
{ -sinY, sinX*cosY, cosX*cosY }}}; |
|
101 |
|
} |
|
102 |
|
|
|
103 |
|
#undef MATRIXN_IMP |
|
104 |
|
#undef T_IMPL |
|
105 |
|
#undef VECTOR |
|
106 |
|
#undef MATRIX |
|
107 |
|
} |
File include/math/matrix/matrix_functions.hpp deleted (index 51f69c3..0000000) |
1 |
|
#pragma once |
|
2 |
|
|
|
3 |
|
#include "base.h" |
|
4 |
|
#include "../constants.h" |
|
5 |
|
#include "../vector/vector_functions.h" |
|
6 |
|
|
|
7 |
|
#include <math.h> |
|
8 |
|
|
|
9 |
|
namespace math |
|
10 |
|
{ |
|
11 |
|
#define T_IMPL template<typename T> [[nodiscard]] constexpr inline |
|
12 |
|
#define MATRIX(n) matrix<n, n, T> |
|
13 |
|
#define VECTOR(n) vector<n, T> |
|
14 |
|
#define VEC_ARG(n) const vector<n, T>& |
|
15 |
|
#define MATRIXN_IMP \ |
|
16 |
|
template<unsigned int size, typename T> [[nodiscard]] constexpr inline \ |
|
17 |
|
matrix<size, size, T> |
|
18 |
|
|
|
19 |
|
MATRIXN_IMP scale(T scale) |
|
20 |
|
{ |
|
21 |
|
matrix<size, size, T> m{}; |
|
22 |
|
for (unsigned int i = 0; i < size; ++i) |
|
23 |
|
m._[i][i] = scale; |
|
24 |
|
return m; |
|
25 |
|
} |
|
26 |
|
MATRIXN_IMP scale(T n_scale[size]) |
|
27 |
|
{ |
|
28 |
|
matrix<size, size, T> m{}; |
|
29 |
|
for (unsigned int i = 0; i < size; ++i) |
|
30 |
|
m._[i][i] = n_scale[i]; |
|
31 |
|
} |
|
32 |
|
T_IMPL MATRIX(4) |
|
33 |
|
matrix_3x4(VEC_ARG(3) x, VEC_ARG(3) y, VEC_ARG(3) z, VEC_ARG(3) w = {}) { |
|
34 |
|
return {{{ x.x, y.x, z.x, 0 }, |
|
35 |
|
{ x.y, y.y, z.y, 0 }, |
|
36 |
|
{ x.z, y.z, z.z, 0 }, |
|
37 |
|
{ w.x, w.y, w.z, 1 }}}; |
|
38 |
|
} |
|
39 |
|
T_IMPL MATRIX(4) // x, y, z are normalized axis-directions |
|
40 |
|
look_at(VEC_ARG(3) x, VEC_ARG(3) y, VEC_ARG(3) z, VEC_ARG(3) pos = {}) { |
|
41 |
|
const VECTOR(3) w = { - dot(x, pos), - dot(y, pos), - dot(z, pos) }; |
|
42 |
|
return matrix_3x4(x, y, z, w); |
|
43 |
|
} |
|
44 |
|
T_IMPL MATRIX(4) |
|
45 |
|
translation(VEC_ARG(3) pos) { |
|
46 |
|
auto mat = scale<4, T>(1); |
|
47 |
|
mat[3].template part<0,3>() = pos; |
|
48 |
|
return mat; |
|
49 |
|
} |
|
50 |
|
T_IMPL MATRIX(3) |
|
51 |
|
rotation(const vector<3, vector<3, T>> &axis) { |
|
52 |
|
return rotation(axis.x, axis.y, axis.z); |
|
53 |
|
} |
|
54 |
|
T_IMPL MATRIX(4) |
|
55 |
|
projection(const vector<2, T> scale, T z_near, T z_far) { |
|
56 |
|
const T z_scale = z_far / (z_far - z_near); |
|
57 |
|
const T z_shift = - z_scale * z_near; |
|
58 |
|
return {{{ scale.x, 0, 0, 0 }, |
|
59 |
|
{ 0, scale.y, 0, 0 }, |
|
60 |
|
{ 0, 0, z_scale, 1 }, |
|
61 |
|
{ 0, 0, z_shift, 0 }}}; |
|
62 |
|
} |
|
63 |
|
T_IMPL MATRIX(4) |
|
64 |
|
projection_fov_y(T fov_y, T aspect_x_to_y, T z_near, T z_far) { |
|
65 |
|
const T y_scale = 1 / std::tan(fov_y / 2); |
|
66 |
|
const T x_scale = y_scale / aspect_x_to_y; |
|
67 |
|
return projection({x_scale, y_scale}, z_near, z_far); |
|
68 |
|
} |
|
69 |
|
T_IMPL MATRIX(4) |
|
70 |
|
projection_fov_x(T fov_x, T aspect_x_to_y, T z_near, T z_far) { |
|
71 |
|
const T x_scale = 1 / std::tan(fov_x / 2); |
|
72 |
|
const T y_scale = x_scale * aspect_x_to_y; |
|
73 |
|
return projection({x_scale, y_scale}, z_near, z_far); |
|
74 |
|
} |
|
75 |
|
T_IMPL MATRIX(4) |
|
76 |
|
projection_fov_xy(T fov_x, T fov_y, T z_near, T z_far) { |
|
77 |
|
const T x_scale = 1 / std::tan(fov_x / 2); |
|
78 |
|
const T y_scale = 1 / std::tan(fov_y / 2); |
|
79 |
|
return projection({x_scale, y_scale}, z_near, z_far); |
|
80 |
|
} |
|
81 |
|
|
|
82 |
|
T_IMPL MATRIX(3) |
|
83 |
|
rotation(const VECTOR(3)& unit, T radians) |
|
84 |
|
{ |
|
85 |
|
auto &x = unit._[0], &y = unit._[1], &z = unit._[2]; |
|
86 |
|
auto c = gcem::cos(radians), s = gcem::sin(radians), t = math::one<T> - c; |
|
87 |
|
return {{{ t*x*x + c, t*x*y - s*z, t*x*z + s*y }, |
|
88 |
|
{ t*x*y + s*z, t*y*y + c, t*y*z - s*x }, |
|
89 |
|
{ t*x*z - s*y, t*y*z + s*x, t*z*z + c }}}; |
|
90 |
|
} |
|
91 |
|
T_IMPL MATRIX(3) |
|
92 |
|
rotation(T x_angle, T y_angle, T z_angle) |
|
93 |
|
{ |
|
94 |
|
T cosX = gcem::cos<T>(x_angle), sinX = gcem::sin<T>(x_angle); |
|
95 |
|
T cosY = gcem::cos<T>(y_angle), sinY = gcem::sin<T>(y_angle); |
|
96 |
|
T cosZ = gcem::cos<T>(z_angle), sinZ = gcem::sin<T>(z_angle); |
|
97 |
|
|
|
98 |
|
return {{{ cosY*cosZ, -cosX*sinZ + sinX*sinY*cosZ, sinX*sinZ + cosX*sinY*cosZ }, |
|
99 |
|
{ cosY*sinZ, cosX*cosZ + sinX*sinY*sinZ, -sinX*cosZ + cosX*sinY*sinZ }, |
|
100 |
|
{ -sinY, sinX*cosY, cosX*cosY }}}; |
|
101 |
|
} |
|
102 |
|
|
|
103 |
|
#undef MATRIXN_IMP |
|
104 |
|
#undef T_IMPL |
|
105 |
|
#undef VECTOR |
|
106 |
|
#undef MATRIX |
|
107 |
|
} |
|