aboutsummaryrefslogtreecommitdiff
path: root/src/math
diff options
context:
space:
mode:
Diffstat (limited to 'src/math')
-rw-r--r--src/math/utils.hpp16
-rw-r--r--src/math/vector.hpp205
2 files changed, 218 insertions, 3 deletions
diff --git a/src/math/utils.hpp b/src/math/utils.hpp
index 5ec5959..5c8c62d 100644
--- a/src/math/utils.hpp
+++ b/src/math/utils.hpp
@@ -5,6 +5,14 @@
#include <utility>
#include "math/vector.hpp"
+namespace engine::math {
+
+struct Vector2;
+struct Vector3;
+struct Vector4;
+
+}
+
namespace engine::math::utils {
template<size_t size> struct Vector;
@@ -19,6 +27,14 @@ constexpr Vector<vector_size>::type array_to_vec(const std::array<float, vector_
}(std::make_index_sequence<vector_size>());
}
+constexpr float lerp(float a, float b, float t) {
+ return a + t * (b - a);
+}
+
+constexpr float map(float x, float from1, float from2, float to1, float to2) {
+ return to1 + (x - from1) * (to2 - to1) / (from2 - from1);
+}
+
}
#endif // MATH_UTILS_HPP
diff --git a/src/math/vector.hpp b/src/math/vector.hpp
index 471f30d..def469b 100644
--- a/src/math/vector.hpp
+++ b/src/math/vector.hpp
@@ -5,7 +5,122 @@
namespace engine::math {
+namespace vector_coords {
+
+enum class VectorCoord { x, y, z, w };
+
+template<VectorCoord id1, VectorCoord id2>
+struct transpose { template<VectorCoord input> static constexpr VectorCoord id(); };
+
+template<> struct transpose<VectorCoord::x, VectorCoord::x> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::x, VectorCoord::y> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::x, VectorCoord::z> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::x, VectorCoord::w> { template<VectorCoord input> static constexpr VectorCoord id(); };
+
+template<> struct transpose<VectorCoord::y, VectorCoord::x> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::y, VectorCoord::y> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::y, VectorCoord::z> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::y, VectorCoord::w> { template<VectorCoord input> static constexpr VectorCoord id(); };
+
+template<> struct transpose<VectorCoord::z, VectorCoord::x> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::z, VectorCoord::y> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::z, VectorCoord::z> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::z, VectorCoord::w> { template<VectorCoord input> static constexpr VectorCoord id(); };
+
+template<> struct transpose<VectorCoord::w, VectorCoord::x> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::w, VectorCoord::y> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::w, VectorCoord::z> { template<VectorCoord input> static constexpr VectorCoord id(); };
+template<> struct transpose<VectorCoord::w, VectorCoord::w> { template<VectorCoord input> static constexpr VectorCoord id(); };
+
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::x>::id<VectorCoord::x>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::x>::id<VectorCoord::y>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::x>::id<VectorCoord::z>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::x>::id<VectorCoord::w>() { return VectorCoord::w; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::y>::id<VectorCoord::x>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::y>::id<VectorCoord::y>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::y>::id<VectorCoord::z>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::y>::id<VectorCoord::w>() { return VectorCoord::w; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::z>::id<VectorCoord::x>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::z>::id<VectorCoord::y>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::z>::id<VectorCoord::z>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::z>::id<VectorCoord::w>() { return VectorCoord::w; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::w>::id<VectorCoord::x>() { return VectorCoord::w; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::w>::id<VectorCoord::y>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::w>::id<VectorCoord::z>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::x, VectorCoord::w>::id<VectorCoord::w>() { return VectorCoord::x; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::x>::id<VectorCoord::x>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::x>::id<VectorCoord::y>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::x>::id<VectorCoord::z>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::x>::id<VectorCoord::w>() { return VectorCoord::w; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::y>::id<VectorCoord::x>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::y>::id<VectorCoord::y>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::y>::id<VectorCoord::z>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::y>::id<VectorCoord::w>() { return VectorCoord::w; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::z>::id<VectorCoord::x>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::z>::id<VectorCoord::y>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::z>::id<VectorCoord::z>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::z>::id<VectorCoord::w>() { return VectorCoord::w; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::w>::id<VectorCoord::x>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::w>::id<VectorCoord::y>() { return VectorCoord::w; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::w>::id<VectorCoord::z>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::y, VectorCoord::w>::id<VectorCoord::w>() { return VectorCoord::y; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::x>::id<VectorCoord::x>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::x>::id<VectorCoord::y>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::x>::id<VectorCoord::z>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::x>::id<VectorCoord::w>() { return VectorCoord::w; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::y>::id<VectorCoord::x>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::y>::id<VectorCoord::y>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::y>::id<VectorCoord::z>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::y>::id<VectorCoord::w>() { return VectorCoord::w; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::z>::id<VectorCoord::x>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::z>::id<VectorCoord::y>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::z>::id<VectorCoord::z>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::z>::id<VectorCoord::w>() { return VectorCoord::w; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::w>::id<VectorCoord::x>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::w>::id<VectorCoord::y>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::w>::id<VectorCoord::z>() { return VectorCoord::w; }
+template<> constexpr VectorCoord transpose<VectorCoord::z, VectorCoord::w>::id<VectorCoord::w>() { return VectorCoord::z; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::x>::id<VectorCoord::x>() { return VectorCoord::w; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::x>::id<VectorCoord::y>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::x>::id<VectorCoord::z>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::x>::id<VectorCoord::w>() { return VectorCoord::x; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::y>::id<VectorCoord::x>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::y>::id<VectorCoord::y>() { return VectorCoord::w; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::y>::id<VectorCoord::z>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::y>::id<VectorCoord::w>() { return VectorCoord::y; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::z>::id<VectorCoord::x>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::z>::id<VectorCoord::y>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::z>::id<VectorCoord::z>() { return VectorCoord::w; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::z>::id<VectorCoord::w>() { return VectorCoord::z; }
+
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::w>::id<VectorCoord::x>() { return VectorCoord::x; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::w>::id<VectorCoord::y>() { return VectorCoord::y; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::w>::id<VectorCoord::z>() { return VectorCoord::z; }
+template<> constexpr VectorCoord transpose<VectorCoord::w, VectorCoord::w>::id<VectorCoord::w>() { return VectorCoord::w; }
+
+}
+
struct Vector2;
+struct Vector3;
+struct Vector4;
+
+template<typename T>
+concept VectorTypeConcept = std::is_same_v<T, Vector2> || std::is_same_v<T, Vector3> || std::is_same_v<T, Vector4>;
+
constexpr Vector2 operator*(float n, const Vector2& other);
constexpr Vector2 operator/(const Vector2& other, float n);
@@ -18,6 +133,25 @@ struct Vector2 {
float x, y;
+ constexpr Vector2() {}
+ constexpr Vector2(float x, float y) : x { x }, y { y } {}
+
+ template<vector_coords::VectorCoord id>
+ constexpr float& v() &
+ requires (id == vector_coords::VectorCoord::x || id == vector_coords::VectorCoord::y)
+ {
+ if constexpr (id == vector_coords::VectorCoord::x) return x;
+ else return y;
+ }
+
+ template<vector_coords::VectorCoord id>
+ constexpr const float& v() const &
+ requires (id == vector_coords::VectorCoord::x || id == vector_coords::VectorCoord::y)
+ {
+ if constexpr (id == vector_coords::VectorCoord::x) return x;
+ else return y;
+ }
+
constexpr bool operator==(const Vector2& other) const & {
return x == other.x && y == other.y;
}
@@ -59,6 +193,13 @@ struct Vector2 {
constexpr Vector2 mul_term(const Vector2& other) const & {
return { x * other.x, y * other.y };
}
+
+ constexpr Vector2 map(const Vector2& from1, const Vector2& from2, const Vector2& to1, const Vector2& to2) {
+ return {
+ to1.x + (x - from1.x) * (to2.x - to1.x) / (from2.x - from1.x),
+ to1.y + (y - from1.y) * (to2.y - to1.y) / (from2.y - from1.y),
+ };
+ }
};
constexpr Vector2 operator*(float n, const Vector2& other) {
@@ -81,7 +222,6 @@ constexpr Vector2 operator-(const Vector2& other, float n) {
return { other.x - n, other.y - n };
}
-struct Vector3;
constexpr Vector3 operator*(float n, const Vector3& other);
constexpr Vector3 operator/(const Vector3& other, float n);
@@ -94,6 +234,28 @@ struct Vector3 {
float x, y, z;
+ constexpr Vector3() {}
+ constexpr Vector3(float x, float y, float z) : x { x }, y { y }, z { z } {}
+ constexpr Vector3(const Vector2& v, float z) : x { v.x }, y { v.y }, z { z } {}
+
+ template<vector_coords::VectorCoord id>
+ constexpr float& v() &
+ requires (id == vector_coords::VectorCoord::x || id == vector_coords::VectorCoord::y || id == vector_coords::VectorCoord::z)
+ {
+ if constexpr (id == vector_coords::VectorCoord::x) return x;
+ else if constexpr (id == vector_coords::VectorCoord::y) return y;
+ else return z;
+ }
+
+ template<vector_coords::VectorCoord id>
+ constexpr const float& v() const &
+ requires (id == vector_coords::VectorCoord::x || id == vector_coords::VectorCoord::y || id == vector_coords::VectorCoord::z)
+ {
+ if constexpr (id == vector_coords::VectorCoord::x) return x;
+ else if constexpr (id == vector_coords::VectorCoord::y) return y;
+ else return z;
+ }
+
constexpr bool operator==(const Vector3& other) const & {
return x == other.x && y == other.y && z == other.z;
}
@@ -125,6 +287,10 @@ struct Vector3 {
return *this;
}
+ constexpr Vector2 xy() const & {
+ return { x, y };
+ }
+
constexpr Vector3 round() {
return { std::round(x), std::round(y), std::round(z) };
}
@@ -152,6 +318,14 @@ struct Vector3 {
constexpr Vector3 normalize() const & {
return *this / length();
}
+
+ constexpr Vector3 map(const Vector3& from1, const Vector3& from2, const Vector3& to1, const Vector3& to2) {
+ return {
+ to1.x + (x - from1.x) * (to2.x - to1.x) / (from2.x - from1.x),
+ to1.y + (y - from1.y) * (to2.y - to1.y) / (from2.y - from1.y),
+ to1.z + (z - from1.z) * (to2.z - to1.z) / (from2.z - from1.z),
+ };
+ }
};
constexpr Vector3 operator*(float n, const Vector3& other) {
@@ -175,6 +349,22 @@ struct Vector4 {
float x, y, z, w;
+ template<vector_coords::VectorCoord id>
+ constexpr float& v() & {
+ if constexpr (id == vector_coords::VectorCoord::x) return x;
+ else if constexpr (id == vector_coords::VectorCoord::y) return y;
+ else if constexpr (id == vector_coords::VectorCoord::z) return z;
+ else return w;
+ }
+
+ template<vector_coords::VectorCoord id>
+ constexpr const float& v() const & {
+ if constexpr (id == vector_coords::VectorCoord::x) return x;
+ else if constexpr (id == vector_coords::VectorCoord::y) return y;
+ else if constexpr (id == vector_coords::VectorCoord::z) return z;
+ else return w;
+ }
+
constexpr Vector4() {}
constexpr Vector4(float x, float y, float z, float w) : x{x}, y{y}, z{z}, w{w} {}
constexpr Vector4(const Vector2& v, float z, float w) : x{v.x}, y{v.y}, z{z}, w{w} {}
@@ -216,8 +406,17 @@ struct Vector4 {
return { x, y, z };
}
- constexpr Vector4 div_by_w() const & {
- return {x / w, y / w, z / w, w};
+ constexpr Vector3 div_by_w() const & {
+ return { x / w, y / w, w };
+ }
+
+ constexpr Vector4 map(const Vector4& from1, const Vector4& from2, const Vector4& to1, const Vector4& to2) {
+ return {
+ to1.x + (x - from1.x) * (to2.x - to1.x) / (from2.x - from1.x),
+ to1.y + (y - from1.y) * (to2.y - to1.y) / (from2.y - from1.y),
+ to1.z + (z - from1.z) * (to2.z - to1.z) / (from2.z - from1.z),
+ to1.w + (w - from1.w) * (to2.w - to1.w) / (from2.w - from1.w),
+ };
}
};