#include #include #include #include #include #include "MVP.hpp" #include "Math.hpp" namespace Math::MVP { Matrix<4, 4> transformation_matrix(Vector<3> position) { return { 1.0f, 0.0f, 0.0f, position.x(), 0.0f, 1.0f, 0.0f, position.y(), 0.0f, 0.0f, 1.0f, position.z(), 0.0f, 0.0f, 0.0f, 1.0f }; } Matrix<4, 4> rotation_matrix(Rotation angles) { auto c = angles.vector.apply(cos); auto s = angles.vector.apply(sin); Matrix<4, 4> rotation_x{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, c.x(), -s.x(), 0.0f, 0.0f, s.x(), c.x(), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; Matrix<4, 4> rotation_y{ c.y(), 0.0f, s.y(), 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -s.y(), 0.0f, c.y(), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; Matrix<4, 4> rotation_z{ c.z(), -s.z(), 0.0f, 0.0f, s.z(), c.z(), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; return rotation_x * rotation_y * rotation_z; } Matrix<4, 4> model(Vector<3> position, Rotation angles) { auto transformation = transformation_matrix(position); auto rotation = rotation_matrix(angles); return transformation * rotation; } Matrix<4, 4> view(Vector<3> position, Rotation angles) { auto transformation = transformation_matrix(position); auto rotation = rotation_matrix(angles); return transformation * rotation; } Matrix<4, 4> projection(float aspect, float fov, float near, float far) { auto fov_radians = (fov * M_PI) / 180.0f; float x_scale = 1.0f / (tan(fov_radians / 2.0f) * aspect); float y_scale = 1.0f / tan(fov_radians / 2.0f); float frustum_length = far - near; float z_near = -(far + near) / frustum_length; float z_far = -(2 * far * near) / frustum_length; Matrix<4, 4> 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; } }