diff options
Diffstat (limited to 'src/Math')
| -rw-r--r-- | src/Math/MVP.cpp | 51 | ||||
| -rw-r--r-- | src/Math/Matrix.hpp | 38 | ||||
| -rw-r--r-- | src/Math/Rotation.hpp | 2 | ||||
| -rw-r--r-- | src/Math/Vector.hpp | 80 |
4 files changed, 101 insertions, 70 deletions
diff --git a/src/Math/MVP.cpp b/src/Math/MVP.cpp index 37675b4..146b208 100644 --- a/src/Math/MVP.cpp +++ b/src/Math/MVP.cpp @@ -1,62 +1,21 @@ #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); + auto transformation = Matrix<4, 4>::transformation(position); + auto rotation = Matrix<4, 4>::rotation(angles); return transformation * rotation; } Matrix<4, 4> view(Vector<3> position, Rotation angles) { - auto transformation = transformation_matrix(position); - auto rotation = rotation_matrix(angles); + auto rotation = Matrix<4, 4>::rotation(angles); + auto transformation = Matrix<4, 4>::transformation(-position); - return transformation * rotation; + return rotation * transformation; } Matrix<4, 4> projection(float aspect, float fov, float near, float far) { diff --git a/src/Math/Matrix.hpp b/src/Math/Matrix.hpp index 9a6b7e6..43f0721 100644 --- a/src/Math/Matrix.hpp +++ b/src/Math/Matrix.hpp @@ -3,6 +3,7 @@ #include <sstream> #include <cstddef> #include <iostream> +#include "Rotation.hpp" template <size_t R, size_t C, typename T = float> struct Matrix { @@ -28,6 +29,43 @@ public: return result; } + static Matrix<4, 4> transformation(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 + }; + } + + static Matrix<4, 4> rotation(Rotation angles) { + auto c = angles.vector.map([](auto a) { return cos(a); }); + auto s = angles.vector.map([](auto a) { return sin(a); }); + + 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; + } + Vector<C, T> row(size_t index) { return { &elements[index * C] }; } diff --git a/src/Math/Rotation.hpp b/src/Math/Rotation.hpp index 334ede2..73a8219 100644 --- a/src/Math/Rotation.hpp +++ b/src/Math/Rotation.hpp @@ -24,7 +24,7 @@ public: } static Vector<3> wrap(Vector<3> v) { - return v.apply([=](float a) -> float { return fmod(a, 360.0f); }); + return v.map([](auto a) { return fmod(a, 360.0f); }); } Vector<3> vector; diff --git a/src/Math/Vector.hpp b/src/Math/Vector.hpp index 2e97217..b6690ef 100644 --- a/src/Math/Vector.hpp +++ b/src/Math/Vector.hpp @@ -4,6 +4,7 @@ #include <sstream> #include <iostream> #include <iterator> +#include <cmath> template <size_t S, typename T = float> struct Vector { @@ -22,62 +23,95 @@ public: elements[S - 1] = scalar; } - Vector<S, T> apply(T f(T)) { - return apply(static_cast<std::function<T(T)>>(f)); + Vector<S, T> map(std::function<T(T)> f) const { + Vector<S, T> result{}; + for (int i = 0; i < S; i++) { + result[i] = f(elements[i]); + } + return result; } - Vector<S, T> apply(std::function<T(T)> f) { + Vector<S, T> map(std::function<T(size_t, T)> f) const { Vector<S, T> result{}; for (int i = 0; i < S; i++) { - result[i] = f(elements[i]); + result[i] = f(i, elements[i]); } return result; } + T reduce(std::function<T(T, T)> f) const { + T result = elements[0]; + for (int i = 1; i < S; i++) { + result = f(result, elements[i]); + } + return result; + } + + T sum() const { + return reduce([](auto x, auto y) { return x + y; }); + } + + T magnitude() const { + return sqrt(map([](auto x) { return x * x;}).sum()); + } + + Vector<S, T> normalize() const { + auto m = magnitude(); + return map([=](auto x) { return x / m; }); + } + + Vector<3, T> cross(Vector<3, T> other) const { + return { + y() * other.z() - z() * other.y(), + z() * other.x() - x() * other.z(), + x() * other.y() - y() * other.x(), + }; + } + + T operator[](size_t index) const { + return elements[index]; + } + 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; + return map([&](auto i, auto x) { return x + other[i]; }); } Vector<S, T> operator*(T scalar) const { - Vector<S, T> result; - for (size_t index; index < S; index++) { - result = this[index] * scalar; - } - return result; + return map([=](auto x) { return x * scalar; }); } T operator*(Vector<S, T> other) const { - T result = 0; - for (size_t index = 0; index < S; index++) { - result += this->elements[index] * other[index]; - } - return result; + return map([&](auto i, auto x) { return x * other[i]; }).sum(); + } + + Vector<S, T> operator-(Vector<S, T> other) const { + return map([&](auto i, auto x) { return x - other[i]; }); + } + + Vector<S, T> operator-() const { + return map([](T x) -> T { return -x; }); } - T x() { + T x() const { static_assert(S > 0); return elements[0]; } - T y() { + T y() const { static_assert(S > 1); return elements[1]; } - T z() { + T z() const { static_assert(S > 2); return elements[2]; } - T w() { + T w() const { static_assert(S > 3); return elements[3]; } |
