summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-10-05 18:27:19 +0200
committerMel <einebeere@gmail.com>2022-10-05 18:27:19 +0200
commitf66811b772c81fc182e353308b1c1a3667201e9b (patch)
treecae289545b06c032060508352ae2ffc53daea9ed
parent0631fb666d2a28a6eb9b8d1578675699b41a5de6 (diff)
downloadmeowcraft-f66811b772c81fc182e353308b1c1a3667201e9b.tar.zst
meowcraft-f66811b772c81fc182e353308b1c1a3667201e9b.zip
Non-camera relative movement
-rw-r--r--src/Math/MVP.cpp51
-rw-r--r--src/Math/Matrix.hpp38
-rw-r--r--src/Math/Rotation.hpp2
-rw-r--r--src/Math/Vector.hpp80
-rw-r--r--src/main.cpp15
5 files changed, 109 insertions, 77 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];
}
diff --git a/src/main.cpp b/src/main.cpp
index 16eda51..32d3b4b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -71,7 +71,7 @@ void run() {
auto mesh = MC::Binder::load(shape);
MC::Camera camera{};
- camera.set_position({0.0f, 0.0f, -3.0f});
+ camera.set_position({0.0f, 0.0f, 3.0f});
MC::ShaderProgram program(MC::Shader::create_fragment(), MC::Shader::create_vertex());
@@ -124,16 +124,17 @@ void process_input(MC::Window& window, MC::Camera& camera) {
auto key = [&](int key) -> float { return window.key(key, GLFW_PRESS); };
- float forward = key(GLFW_KEY_W) - key(GLFW_KEY_S);
- float side = key(GLFW_KEY_D) - key(GLFW_KEY_A);
+ float x = key(GLFW_KEY_D) - key(GLFW_KEY_A);
+ float y = key(GLFW_KEY_SPACE) - key(GLFW_KEY_LEFT_SHIFT);
+ float z = key(GLFW_KEY_S) - key(GLFW_KEY_W);
- float vertical = key(GLFW_KEY_UP) - key(GLFW_KEY_DOWN);
- float horizontal = key(GLFW_KEY_LEFT) - key(GLFW_KEY_RIGHT);
+ float rx = key(GLFW_KEY_DOWN) - key(GLFW_KEY_UP);
+ float ry = key(GLFW_KEY_RIGHT) - key(GLFW_KEY_LEFT);
auto speed = 0.05f;
- camera.move({side * speed, forward * speed, 0.0f});
- camera.rotate({vertical * speed, horizontal * speed, 0.0f});
+ camera.move({x * speed, y * speed, z * speed});
+ camera.rotate({rx * speed, ry * speed, 0.0f});
}
void setup_gl() {