diff options
Diffstat (limited to 'src/Math')
| -rw-r--r-- | src/Math/MVP.cpp | 82 | ||||
| -rw-r--r-- | src/Math/MVP.hpp | 11 | ||||
| -rw-r--r-- | src/Math/Math.hpp | 3 | ||||
| -rw-r--r-- | src/Math/Matrix.hpp | 46 | ||||
| -rw-r--r-- | src/Math/Rotation.hpp | 31 | ||||
| -rw-r--r-- | src/Math/Vector.hpp | 29 |
6 files changed, 193 insertions, 9 deletions
diff --git a/src/Math/MVP.cpp b/src/Math/MVP.cpp new file mode 100644 index 0000000..37675b4 --- /dev/null +++ b/src/Math/MVP.cpp @@ -0,0 +1,82 @@ +#include <cmath> +#include <glm/glm.hpp> +#include <glm/gtc/matrix_transform.hpp> +#include <glm/gtc/type_ptr.hpp> +#include <glm/gtx/string_cast.hpp> +#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; +} + +} diff --git a/src/Math/MVP.hpp b/src/Math/MVP.hpp new file mode 100644 index 0000000..c3fb64f --- /dev/null +++ b/src/Math/MVP.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "Math.hpp" + +namespace Math::MVP { + +Matrix<4, 4> model(Vector<3> position, Rotation angles); +Matrix<4, 4> view(Vector<3> position, Rotation angles); +Matrix<4, 4> projection(float aspect, float fov, float near, float far); + +} diff --git a/src/Math/Math.hpp b/src/Math/Math.hpp index 8204728..b8b61a1 100644 --- a/src/Math/Math.hpp +++ b/src/Math/Math.hpp @@ -1,4 +1,5 @@ #pragma once #include "Vector.hpp" -#include "Matrix.hpp" \ No newline at end of file +#include "Matrix.hpp" +#include "Rotation.hpp" \ No newline at end of file diff --git a/src/Math/Matrix.hpp b/src/Math/Matrix.hpp index adc34a9..9a6b7e6 100644 --- a/src/Math/Matrix.hpp +++ b/src/Math/Matrix.hpp @@ -1,7 +1,7 @@ #pragma once #include <sstream> -#include <stddef.h> +#include <cstddef> #include <iostream> template <size_t R, size_t C, typename T = float> @@ -9,8 +9,24 @@ struct Matrix { public: Matrix<R, C, T>() : elements{} {}; + Matrix<R, C, T>(T scalar) { + std::fill(elements, elements + R * C, scalar); + }; + template<typename ...Args> - explicit Matrix<R, C, T>(Args... args): elements{ args... } {}; + Matrix<R, C, T>(Args... args): elements{ args... } {}; + + Matrix<R, C, T>(T values[R * C]) { + std::copy(values, values + R * C, elements); + }; + + static Matrix<R, R, T> identity() { + Matrix<R, R, T> result{}; + for (int i = 0; i < R; i++) { + result(i, i) = 1; + } + return result; + } Vector<C, T> row(size_t index) { return { &elements[index * C] }; @@ -24,6 +40,22 @@ public: return result; } + Matrix<R, C, T> operator+(Matrix<R, C, T> other) { + Matrix<R, C, T> result{}; + for (int i = 0; i < R * C; i++) { + result.elements[i] = elements[i] + other.elements[i]; + } + return result; + } + + Matrix<R, C, T> operator*(float scalar) { + Matrix<R, C, T> result{}; + for (int i = 0; i < R * C; i++) { + result.elements[i] = elements[i] * scalar; + } + return result; + } + template<size_t N> Matrix<R, N, T> operator*(Matrix<C, N, T> other) { Matrix<R, N, T> result{}; @@ -34,16 +66,18 @@ public: auto dot = r * c; - std::cout << x << ", " << y << ": " - << "(" << r.string() << ", " << c.string() << ")" - << dot << std::endl; - result(x, y) = dot; } } return result; } + Vector<R, T> operator*(Vector<R, T> vector) { + Matrix<R, 1, T> matrix(vector.elements); + matrix = this->operator*(matrix); + return { matrix.elements }; + } + auto& operator()(size_t x, size_t y) { return elements[y * C + x]; } diff --git a/src/Math/Rotation.hpp b/src/Math/Rotation.hpp new file mode 100644 index 0000000..334ede2 --- /dev/null +++ b/src/Math/Rotation.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include <cmath> +#include "Vector.hpp" + +struct Rotation { +public: + Rotation() : vector{} {}; + + Rotation(Vector<3> vector) : vector{ wrap(vector) } {}; + + Rotation(float angles[3]) : Rotation(angles[0], angles[1], angles[2]) {}; + + Rotation(float x, float y, float z) { + vector = wrap({ x, y, z }); + }; + + Rotation operator+(Rotation other) const { + return wrap(vector + other.vector); + } + + std::string string() const { + return vector.string(); + } + + static Vector<3> wrap(Vector<3> v) { + return v.apply([=](float a) -> float { return fmod(a, 360.0f); }); + } + + Vector<3> vector; +}; \ No newline at end of file diff --git a/src/Math/Vector.hpp b/src/Math/Vector.hpp index 0145b58..2e97217 100644 --- a/src/Math/Vector.hpp +++ b/src/Math/Vector.hpp @@ -1,6 +1,6 @@ #pragma once -#include <stddef.h> +#include <cstddef> #include <sstream> #include <iostream> #include <iterator> @@ -17,10 +17,35 @@ public: std::copy(values, values + S, elements); }; + Vector<S, T>(Vector<S - 1, T> vector, T scalar) { + std::copy(vector.elements, vector.elements + S - 1, elements); + elements[S - 1] = scalar; + } + + Vector<S, T> apply(T f(T)) { + return apply(static_cast<std::function<T(T)>>(f)); + } + + Vector<S, T> apply(std::function<T(T)> f) { + Vector<S, T> result{}; + for (int i = 0; i < S; i++) { + result[i] = f(elements[i]); + } + return result; + } + T& operator[](size_t index) { return elements[index]; } + Vector<S, T> operator+(Vector<S, T> other) const { + Vector<S, T> result{}; + for (int i = 0; i < S; i++) { + result[i] = elements[i] + other[i]; + } + return result; + } + Vector<S, T> operator*(T scalar) const { Vector<S, T> result; for (size_t index; index < S; index++) { @@ -57,7 +82,7 @@ public: return elements[3]; } - std::string string() { + std::string string() const { std::stringstream str{}; str << "[ "; |
