Mathter
A configurable 3D math library for game developers.
PerspectiveBuilder.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 
4 #include "../Matrix/MatrixImpl.hpp"
5 #include "../Vector.hpp"
6 #include "IdentityBuilder.hpp"
7 
8 namespace mathter {
9 
10 
11 template <class T, int Dim, bool Packed>
13  static_assert(!std::is_integral_v<T>);
14 
15 public:
16  PerspectiveBuilder(T fovX, const Vector<T, Dim - 1, Packed>& ratios, T nearPlane, T farPlane, T projNearPlane = 0, T projFarPlane = 1)
17  : fovX(fovX), ratios(ratios), nearPlane(nearPlane), farPlane(farPlane), projNearPlane(projNearPlane), projFarPlane(projFarPlane) {}
19 
20  template <class U, eMatrixOrder Order, eMatrixLayout Layout, bool MPacked>
23  Set(m);
24  return m;
25  }
26 
27 private:
28  template <class U, int Rows, int Columns, eMatrixOrder Order, eMatrixLayout Layout, bool MPacked>
30  assert((nearPlane < 0 && farPlane < nearPlane) || (0 < nearPlane && nearPlane < farPlane));
31 
32  m = Zero();
33  // Layout be like (precede_vector):
34  // w 0 0 0
35  // 0 h 0 0
36  // 0 0 A B
37  // 0 0 C 0
38  auto absFovX = std::abs(fovX);
39  T N = nearPlane;
40  T F = farPlane;
41  T n = projNearPlane;
42  T f = projFarPlane;
43  T C = nearPlane < T(0) ? T(-1) : T(1);
44  T A = C * (f * F - n * N) / (F - N);
45  T B = C * F * N * (n - f) / (F - N);
46  Vector<T, Dim - 1, Packed> adjRatios = ratios(0) / ratios;
47  T w = tan(T(0.5) * absFovX);
48  adjRatios /= w;
49  for (int i = 0; i < adjRatios.Dimension(); ++i) {
50  m(i, i) = adjRatios(i);
51  }
52  m(m.RowCount() - 2, m.ColumnCount() - 2) = A;
53  if (Order == eMatrixOrder::FOLLOW_VECTOR) {
54  std::swap(B, C);
55  }
56  m(m.RowCount() - 2, m.ColumnCount() - 1) = B;
57  m(m.RowCount() - 1, m.ColumnCount() - 2) = C;
58  }
59 
60  const T fovX;
61  const Vector<T, Dim - 1, Packed> ratios;
62  const T nearPlane;
63  const T farPlane;
64  const T projNearPlane = 0;
65  const T projFarPlane = 1;
66 };
67 
68 
77 template <class T, int DimMinus1, bool Packed>
78 auto Perspective(T fovX, const Vector<T, DimMinus1, Packed>& ratios, T nearPlane, T farPlane, T projNearPlane = T(0), T projFarPlane = T(1)) {
79  using NonIntegral = std::conditional_t<std::is_integral_v<T>, float, T>;
80  return PerspectiveBuilder<NonIntegral, DimMinus1 + 1, Packed>{ fovX, ratios, nearPlane, farPlane, projNearPlane, projFarPlane };
81 }
82 
83 
91 template <class T>
92 auto Perspective(T fov, T nearPlane, T farPlane, T projNearPlane = T(0), T projFarPlane = T(1)) {
93  return Perspective(std::abs(fov), Vector<T, 1, false>{ fov < 0 ? -1 : 1 }, nearPlane, farPlane, projNearPlane, projFarPlane);
94 }
95 
96 
105 template <class T>
106 auto Perspective(T fov, T aspectRatio, T nearPlane, T farPlane, T projNearPlane = T(0), T projFarPlane = T(1)) {
107  return Perspective(std::abs(fov), Vector<T, 2, false>{ fov < 0 ? -1 : 1, T(1) / aspectRatio }, nearPlane, farPlane, projNearPlane, projFarPlane);
108 }
109 
110 
111 
112 } // namespace mathter
PerspectiveBuilder & operator=(const PerspectiveBuilder &)=delete
PerspectiveBuilder(T fovX, const Vector< T, Dim - 1, Packed > &ratios, T nearPlane, T farPlane, T projNearPlane=0, T projFarPlane=1)
Definition: PerspectiveBuilder.hpp:16
auto Perspective(T fovX, const Vector< T, DimMinus1, Packed > &ratios, T nearPlane, T farPlane, T projNearPlane=T(0), T projFarPlane=T(1))
Creates a perspective projection matrix.
Definition: PerspectiveBuilder.hpp:78
Definition: Approx.hpp:11
constexpr int ColumnCount() const
Returns the number of columns of the matrix.
Definition: MatrixImpl.hpp:27
Definition: Definitions.hpp:63
constexpr int RowCount() const
Returns the number of rows of the matrix.
Definition: MatrixImpl.hpp:31
Definition: PerspectiveBuilder.hpp:12
auto Zero()
Creates a matrix with all elements zero.
Definition: ZeroBuilder.hpp:34