aboutsummaryrefslogtreecommitdiff
path: root/src/math
diff options
context:
space:
mode:
Diffstat (limited to 'src/math')
-rw-r--r--src/math/mat4.hpp1
-rw-r--r--src/math/quat.hpp26
-rw-r--r--src/math/utils.hpp24
-rw-r--r--src/math/vector.hpp26
4 files changed, 65 insertions, 12 deletions
diff --git a/src/math/mat4.hpp b/src/math/mat4.hpp
index 6a215d3..b25dbd4 100644
--- a/src/math/mat4.hpp
+++ b/src/math/mat4.hpp
@@ -4,6 +4,7 @@
#include <array>
#include <cmath>
#include "math/vector.hpp"
+#include "math/quat.hpp"
namespace engine::math {
diff --git a/src/math/quat.hpp b/src/math/quat.hpp
index 51392e7..9687c98 100644
--- a/src/math/quat.hpp
+++ b/src/math/quat.hpp
@@ -2,6 +2,7 @@
#define MATH_QUAT_HPP
#include <cmath>
+#include "math/vector.hpp"
namespace engine::math {
@@ -30,6 +31,23 @@ struct Quaternion {
return {std::cos(a / 2.f), 0.f, std::sin(a / 2.f), 0.f};
}
+ static constexpr Quaternion look_towards(const Vector3& dir, const Vector3& up) {
+ // TODO: extract common code between Matrix4::look_at and this. We should have something
+ // similar to a function returning a 3x3 matrix which does:
+ // e_x -> up.cross(-dir).normalize()
+ // e_y -> (-dir).cross(e_x).normalize()
+ // e_z -> (-dir).normalize()
+ Vector3 new_x = up.cross(-dir).normalize();
+ Vector3 new_y = (-dir).cross(new_x).normalize();
+ Vector3 new_z = (-dir).normalize();
+ return {
+ std::sqrt(std::max(0.f, new_x.x + new_y.y + new_z.z + 1.f)) / 2.f,
+ std::copysign(std::sqrt(std::max(0.f, new_x.x - new_y.y - new_z.z + 1.f)) / 2.f, new_y.z - new_z.y),
+ std::copysign(std::sqrt(std::max(0.f, -new_x.x + new_y.y - new_z.z + 1.f)) / 2.f, new_z.x - new_x.z),
+ std::copysign(std::sqrt(std::max(0.f, -new_x.x - new_y.y + new_z.z + 1.f)) / 2.f, new_x.y - new_y.x),
+ };
+ }
+
float w, x, y, z;
constexpr Quaternion() {}
@@ -71,6 +89,14 @@ struct Quaternion {
constexpr Quaternion conjugate() const & {
return {w, -x, -y, -z};
}
+
+ constexpr Vector3 rot(const Vector3& v) const & {
+ return {
+ (2.f * (w * w + x * x) - 1.f) * v.x + (2.f * (x * y - w * z) ) * v.y + (2.f * (x * z + w * y) ) * v.z,
+ (2.f * (x * y + w * z) ) * v.x + (2.f * (w * w + y * y) - 1.f) * v.y + (2.f * (y * z - w * x) ) * v.z,
+ (2.f * (x * z - w * y) ) * v.x + (2.f * (y * z + w * x) ) * v.y + (2.f * (w * w + z * z) - 1.f) * v.z,
+ };
+ }
};
}
diff --git a/src/math/utils.hpp b/src/math/utils.hpp
new file mode 100644
index 0000000..5ec5959
--- /dev/null
+++ b/src/math/utils.hpp
@@ -0,0 +1,24 @@
+#ifndef MATH_UTILS_HPP
+#define MATH_UTILS_HPP
+
+#include <array>
+#include <utility>
+#include "math/vector.hpp"
+
+namespace engine::math::utils {
+
+template<size_t size> struct Vector;
+template<> struct Vector<2> { using type = engine::math::Vector2; };
+template<> struct Vector<3> { using type = engine::math::Vector3; };
+template<> struct Vector<4> { using type = engine::math::Vector4; };
+
+template<size_t vector_size>
+constexpr Vector<vector_size>::type array_to_vec(const std::array<float, vector_size>& coords) {
+ return [&]<size_t... i>(std::index_sequence<i...>) constexpr -> Vector<vector_size>::type {
+ return { coords[i] ... };
+ }(std::make_index_sequence<vector_size>());
+}
+
+}
+
+#endif // MATH_UTILS_HPP
diff --git a/src/math/vector.hpp b/src/math/vector.hpp
index e836e0d..471f30d 100644
--- a/src/math/vector.hpp
+++ b/src/math/vector.hpp
@@ -2,11 +2,20 @@
#define MATH_VECTOR_HPP
#include <cmath>
-#include "math/quat.hpp"
namespace engine::math {
+struct Vector2;
+constexpr Vector2 operator*(float n, const Vector2& other);
+constexpr Vector2 operator/(const Vector2& other, float n);
+
struct Vector2 {
+ static constexpr size_t size = 2;
+
+ static constexpr Vector2 bilerp(const Vector2& v1, const Vector2& v2, const Vector2& v3, float b0, float b1) {
+ return b0 * v1 + b1 * v2 + (1.f - b0 - b1) * v3;
+ }
+
float x, y;
constexpr bool operator==(const Vector2& other) const & {
@@ -77,6 +86,8 @@ constexpr Vector3 operator*(float n, const Vector3& other);
constexpr Vector3 operator/(const Vector3& other, float n);
struct Vector3 {
+ static constexpr size_t size = 3;
+
static constexpr Vector3 bilerp(const Vector3& v1, const Vector3& v2, const Vector3& v3, float b0, float b1) {
return b0 * v1 + b1 * v2 + (1.f - b0 - b1) * v3;
}
@@ -126,14 +137,6 @@ struct Vector3 {
};
}
- constexpr Vector3 rot(const Quaternion& q) const & {
- return {
- (2.f * (q.w * q.w + q.x * q.x) - 1.f) * x + (2.f * (q.x * q.y - q.w * q.z) ) * y + (2.f * (q.x * q.z + q.w * q.y) ) * z,
- (2.f * (q.x * q.y + q.w * q.z) ) * x + (2.f * (q.w * q.w + q.y * q.y) - 1.f) * y + (2.f * (q.y * q.z - q.w * q.x) ) * z,
- (2.f * (q.x * q.z - q.w * q.y) ) * x + (2.f * (q.y * q.z + q.w * q.x) ) * y + (2.f * (q.w * q.w + q.z * q.z) - 1.f) * z,
- };
- }
-
constexpr float dot(const Vector3& other) const & {
return x * other.x + y * other.y + z * other.z;
}
@@ -168,15 +171,14 @@ constexpr Vector3 operator/(const Vector3& other, float n) {
}
struct Vector4 {
+ static constexpr size_t size = 4;
+
float x, y, z, w;
constexpr Vector4() {}
constexpr Vector4(float x, float y, float z, float w) : x{x}, y{y}, z{z}, w{w} {}
- constexpr Vector4(float x, float y, float z) : x{x}, y{y}, z{z}, w{1.f} {}
constexpr Vector4(const Vector2& v, float z, float w) : x{v.x}, y{v.y}, z{z}, w{w} {}
- constexpr Vector4(const Vector2& v, float z) : x{v.x}, y{v.y}, z{z}, w{1.f} {}
constexpr Vector4(const Vector3& v, float w) : x{v.x}, y{v.y}, z{v.z}, w{w} {}
- constexpr Vector4(const Vector3& v) : x{v.x}, y{v.y}, z{v.z}, w{1.f} {}
constexpr bool operator==(const Vector4& other) const & {
return x == other.x && y == other.y && z == other.z && w == other.w;