summary refs log tree commit diff
path: root/src/Math/MVP.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Math/MVP.hpp')
-rw-r--r--src/Math/MVP.hpp59
1 files changed, 55 insertions, 4 deletions
diff --git a/src/Math/MVP.hpp b/src/Math/MVP.hpp
index af4fbbc..4046a50 100644
--- a/src/Math/MVP.hpp
+++ b/src/Math/MVP.hpp
@@ -4,9 +4,60 @@
 
 namespace Math::MVP {
 
-Matrix<4, 4> model(Vector<3> position, Rotation angles);
-Matrix<4, 4> view(Vector<3> position, Rotation angles);
-Matrix<4, 4> perspective_projection(float aspect, float fov, float near, float far);
-Matrix<4, 4> orthographic_projection(float width, float height, float near, float far);
+template<typename T = Real>
+Matrix<4, 4, T> model(Vector<3> position, Rotation angles) {
+    auto transformation = Matrix<4, 4, T>::transformation(position);
+    auto rotation = Matrix<4, 4, T>::rotation(angles);
+
+    return transformation * rotation;
+}
+
+template<typename T = Real>
+Matrix<4, 4, T> view(Vector<3> position, Rotation angles) {
+    auto rotation = Matrix<4, 4, T>::rotation(angles);
+    auto transformation = Matrix<4, 4, T>::transformation(-position);
+
+    return rotation * transformation;
+}
+
+template<typename T = Real>
+Matrix<4, 4, T> perspective_projection(Real aspect, Real fov, Real near, Real far) {
+    auto fov_radians = radians(fov);
+
+    Real x_scale = 1.0 / (tan(fov_radians / 2.0) * aspect);
+    Real y_scale = 1.0 / tan(fov_radians / 2.0);
+
+    Real frustum_length = far - near;
+    Real z_near = -(far + near) / frustum_length;
+    Real z_far = -(2 * far * near) / frustum_length;
+
+    Matrix<4, 4, T> projection{
+        x_scale, 0.0f,    0.0f,   0.0f,
+        0.0f,    y_scale, 0.0f,   0.0f,
+        0.0f,    0.0f,    z_near, z_far,
+        0.0f,    0.0f,    -1.0f,   0.0f,
+    };
+
+    return projection;
+}
+
+template<typename T = Real>
+Matrix<4, 4, T> orthographic_projection(Real width, Real height, Real near, Real far) {
+    Real x_scale = 2.0f / width;
+    Real y_scale = 2.0f / -height;
+
+    Real frustum_length = far - near;
+    Real z_near = -(far + near) / frustum_length;
+    Real z_far = -2 / frustum_length;
+
+    Matrix<4, 4, T> projection{
+        x_scale, 0.0f,    0.0f,   -1.0f,
+        0.0f,    y_scale, 0.0f,   1.0f,
+        0.0f,    0.0f,    z_near, z_far,
+        0.0f,    0.0f,    0.0f,   1.0f,
+    };
+
+    return projection;
+}
 
 }