OGLplus  (0.59.0) a C++ wrapper for rendering APIs

matrix_perspective.hpp
Go to the documentation of this file.
1 #ifndef EAGINE_MATH_MATRIX_PERSPECTIVE_HPP
9 #define EAGINE_MATH_MATRIX_PERSPECTIVE_HPP
10 
11 #include "../quantities.hpp"
12 #include "matrix_ctr.hpp"
13 
14 namespace eagine::math {
15 
16 // perspective
17 template <typename X>
18 class perspective;
19 
20 // is_matrix_constructor<perspective>
21 template <typename T, int N, bool RM, bool V>
22 struct is_matrix_constructor<perspective<matrix<T, N, N, RM, V>>>
23  : std::true_type {};
24 
30 template <typename T, bool RM, bool V>
31 class perspective<matrix<T, 4, 4, RM, V>> {
32 public:
33  constexpr perspective(const vect::data_t<T, 6, V>& v) noexcept
34  : _v(v) {}
35 
37  constexpr perspective(
38  T x_left,
39  T x_right,
40  T y_bottom,
41  T y_top,
42  T z_near,
43  T z_far) noexcept
44  : _v{x_left, x_right, y_bottom, y_top, z_near, z_far} {}
45 
47  constexpr auto operator()() const noexcept {
48  return _make(bool_constant<RM>());
49  }
50 
52  static auto x(radians_t<T> xfov, T aspect, T z_near, T z_far) noexcept {
53  EAGINE_ASSERT(aspect > T(0));
54  EAGINE_ASSERT(T(xfov) > T(0));
55 
56  T x_right = z_near * tan(xfov * T(0.5));
57  T x_left = -x_right;
58 
59  T y_bottom = x_left / aspect;
60  T y_top = x_right / aspect;
61 
62  return perspective(x_left, x_right, y_bottom, y_top, z_near, z_far);
63  }
64 
66  static auto y(radians_t<T> yfov, T aspect, T z_near, T z_far) noexcept {
67  EAGINE_ASSERT(aspect > T(0));
68  EAGINE_ASSERT(T(yfov) > T(0));
69 
70  T y_top = z_near * tan(yfov * T(0.5));
71  T y_bottom = -y_top;
72 
73  T x_left = y_bottom * aspect;
74  T x_right = y_top * aspect;
75 
76  return perspective(x_left, x_right, y_bottom, y_top, z_near, z_far);
77  }
78 
80  static auto square(radians_t<T> fov, T z_near, T z_far) noexcept {
81  EAGINE_ASSERT(T(fov) > T(0));
82 
83  T x_right = z_near * tan(fov * T(0.5));
84  T x_left = -x_right;
85 
86  T y_bottom = x_left;
87  T y_top = x_right;
88 
89  return perspective(x_left, x_right, y_bottom, y_top, z_near, z_far);
90  }
91 
92 private:
93  constexpr auto _x_left() const noexcept {
94  return _v[0];
95  }
96 
97  constexpr auto _x_right() const noexcept {
98  return _v[1];
99  }
100 
101  constexpr auto _y_bottom() const noexcept {
102  return _v[2];
103  }
104 
105  constexpr auto _y_top() const noexcept {
106  return _v[3];
107  }
108 
109  constexpr auto _z_near() const noexcept {
110  return _v[4];
111  }
112 
113  constexpr auto _z_far() const noexcept {
114  return _v[5];
115  }
116 
117  constexpr auto _m00() const noexcept {
118  return (T(2) * _z_near()) / (_x_right() - _x_left());
119  }
120 
121  constexpr auto _m11() const noexcept {
122  return (T(2) * _z_near()) / (_y_top() - _y_bottom());
123  }
124 
125  constexpr auto _m22() const noexcept {
126  return -(_z_far() + _z_near()) / (_z_far() - _z_near());
127  }
128 
129  constexpr auto _m20() const noexcept {
130  return (_x_right() + _x_left()) / (_x_right() - _x_left());
131  }
132 
133  constexpr auto _m21() const noexcept {
134  return (_y_top() + _y_bottom()) / (_y_top() - _y_bottom());
135  }
136 
137  constexpr auto _m23() const noexcept {
138  return -T(1);
139  }
140 
141  constexpr auto _m32() const noexcept {
142  return -(T(2) * _z_far() * _z_near()) / (_z_far() - _z_near());
143  }
144 
145  constexpr auto _make(std::true_type) const noexcept {
146  return matrix<T, 4, 4, true, V>{
147  {{_m00(), T(0), _m20(), T(0)},
148  {T(0), _m11(), _m21(), T(0)},
149  {T(0), T(0), _m22(), _m32()},
150  {T(0), T(0), _m23(), T(0)}}};
151  }
152 
153  constexpr auto _make(std::false_type) const noexcept {
154  return matrix<T, 4, 4, false, V>{
155  {{_m00(), T(0), T(0), T(0)},
156  {T(0), _m11(), T(0), T(0)},
157  {_m20(), _m21(), _m22(), _m23()},
158  {T(0), T(0), _m32(), T(0)}}};
159  }
160 
161  using _dT = vect::data_t<T, 6, V>;
162  _dT _v;
163 };
164 
165 // reorder_mat_ctr(perspective)
166 template <typename T, int N, bool RM, bool V>
167 static constexpr auto
168 reorder_mat_ctr(const perspective<matrix<T, N, N, RM, V>>& c) noexcept
169  -> perspective<matrix<T, N, N, !RM, V>> {
170  return {c._v};
171 }
172 
175 template <typename T, bool V>
176 using matrix_perspective =
178 
179 } // namespace eagine::math
180 
181 #endif // EAGINE_MATH_MATRIX_PERSPECTIVE_HPP
constexpr auto operator()() const noexcept
Returns the constructed matrix.
Definition: matrix_perspective.hpp:47
static auto y(radians_t< T > yfov, T aspect, T z_near, T z_far) noexcept
Constructs perspective matrix with y-FOV angle and aspect ratio.
Definition: matrix_perspective.hpp:66
convertible_matrix_constructor< perspective< matrix< T, 4, 4, true, V > >> matrix_perspective
Alias for constructor of perspective projection matrix.
Definition: matrix_perspective.hpp:177
std::integral_constant< bool, B > bool_constant
Alias for boolean constant type.
Definition: int_constant.hpp:20
static auto square(radians_t< T > fov, T z_near, T z_far) noexcept
Constructs perspective matrix with FOV angle and aspect ratio of 1.
Definition: matrix_perspective.hpp:80
Math-related code is placed in this namespace.
Definition: eagine.hpp:48
Helper class used in matrix constructor implementation.
Definition: matrix_ctr.hpp:74
constexpr perspective(T x_left, T x_right, T y_bottom, T y_top, T z_near, T z_far) noexcept
Initialized the matrix constructor.
Definition: matrix_perspective.hpp:37
static auto x(radians_t< T > xfov, T aspect, T z_near, T z_far) noexcept
Constructs perspective matrix with x-FOV angle and aspect ratio.
Definition: matrix_perspective.hpp:52
Value of type T with a specified unit or tag type U.
Definition: tagged_quantity.hpp:27
Basic RxC matrix implementation template.
Definition: fwd.hpp:25

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).