Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
prism/engine/math/include/vector.hpp

242 lines
9.4 KiB
C++
Raw Normal View History

2020-08-11 12:07:21 -04:00
#pragma once
#include <array>
2020-08-11 12:07:21 -04:00
#include <cmath>
#include <type_traits>
#include <typeinfo>
2021-05-12 09:56:44 -04:00
namespace prism {
#define DEFINE_OPERATORS(Size) \
constexpr Vector(const T scalar = T(0)) { \
for (std::size_t i = 0; i < (Size); i++) \
data[i] = scalar; \
} \
constexpr T& operator[](const size_t index) { return data[index]; } \
constexpr T operator[](const size_t index) const { return data[index]; } \
constexpr Vector& operator+=(const Vector rhs) { \
for (std::size_t i = 0; i < (Size); i++) \
data[i] += rhs[i]; \
return *this; \
} \
constexpr Vector& operator-=(const Vector rhs) { \
for (std::size_t i = 0; i < (Size); i++) \
data[i] -= rhs[i]; \
return *this; \
} \
constexpr Vector& operator*=(const Vector rhs) { \
for (std::size_t i = 0; i < (Size); i++) \
data[i] *= rhs[i]; \
return *this; \
} \
constexpr Vector& operator/=(const T scalar) { \
for (std::size_t i = 0; i < (Size); i++) \
data[i] /= scalar; \
return *this; \
} \
constexpr T* ptr() const { return data.data(); } \
constexpr T* ptr() { return data.data(); } \
constexpr Vector operator-() const { \
Vector vec; \
for (std::size_t i = 0; i < (Size); i++) \
vec[i] = -data[i]; \
return vec; \
2020-08-11 12:07:21 -04:00
}
2021-05-12 09:56:44 -04:00
template<std::size_t N, class T> struct Vector { std::array<T, N> data; };
2020-08-11 12:07:21 -04:00
template<class T> struct Vector<2, T> {
2021-05-12 09:56:44 -04:00
constexpr Vector(const T x_, const T y_) {
x = x_;
y = y_;
}
DEFINE_OPERATORS(2)
union {
std::array<T, 2> data;
struct {
T x, y;
};
2020-08-11 12:07:21 -04:00
};
};
2021-05-12 09:56:44 -04:00
template<class T> struct Vector<3, T> {
2021-05-12 09:56:44 -04:00
constexpr Vector(const T x_, const T y_, const T z_) {
x = x_;
y = y_;
z = z_;
}
DEFINE_OPERATORS(3)
union {
std::array<T, 3> data;
struct {
T x, y, z;
};
2020-08-11 12:07:21 -04:00
};
2021-05-12 09:56:44 -04:00
};
template<class T> struct alignas(16) Vector<4, T> {
2021-05-12 09:56:44 -04:00
constexpr Vector(const T x_, const T y_, const T z_, const T w_) {
x = x_;
y = y_;
z = z_;
w = w_;
}
constexpr Vector(const Vector<3, T>& v, const float w = 0.0f) : x(v.x), y(v.y), z(v.z), w(w) {}
2021-05-12 09:56:44 -04:00
DEFINE_OPERATORS(4)
union {
std::array<T, 4> data;
struct {
T x, y, z, w;
};
struct {
Vector<3, T> xyz;
T padding_xyz;
};
2020-08-11 12:07:21 -04:00
};
};
2021-05-12 09:56:44 -04:00
using float2 = Vector<2, float>;
using float3 = Vector<3, float>;
using float4 = Vector<4, float>;
template<std::size_t N, class T> constexpr inline T dot(const Vector<N, T> lhs, const Vector<N, T> rhs) {
2021-05-12 09:56:44 -04:00
T product = T(0.0);
for (std::size_t i = 0; i < N; i++)
product += lhs[i] * rhs[i];
return product;
}
template<std::size_t N, class T> constexpr inline T length(const Vector<N, T> vec) {
2021-05-12 09:56:44 -04:00
return sqrtf(dot(vec, vec));
}
template<std::size_t N, class T>
constexpr inline Vector<N, T> lerp(const Vector<N, T> a, const Vector<N, T> b, const T t) {
Vector<N, T> vec;
for (std::size_t i = 0; i < N; i++)
vec[i] = (T(1) - t) * a[i] + t * b[i];
return vec;
}
template<std::size_t N, class T> constexpr inline Vector<N, T> normalize(const Vector<N, T> vec) {
2021-05-12 09:56:44 -04:00
Vector<N, T> result;
const float len = length(vec);
for (std::size_t i = 0; i < N; i++)
result[i] = vec[i] / len;
return result;
}
constexpr inline float3 cross(const float3 u, const float3 v) {
return float3(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x);
}
inline float distance(const float3 lhs, const float3 rhs) {
const float diffX = lhs.x - rhs.x;
const float diffY = lhs.y - rhs.y;
const float diffZ = lhs.z - rhs.z;
return std::sqrt((diffX * diffX) + (diffY * diffY) + (diffZ * diffZ));
}
template<std::size_t N, class T> constexpr inline T norm(const Vector<N, T> vec) {
2021-05-12 09:56:44 -04:00
T val = T(0);
for (std::size_t i = 0; i < N; i++)
val += abs(vec[i]);
return sqrtf(dot(vec, vec));
}
} // namespace prism
2020-08-11 12:07:21 -04:00
template<std::size_t N, class T>
2021-05-12 09:56:44 -04:00
constexpr inline bool operator==(const prism::Vector<N, T> lhs, const prism::Vector<N, T> rhs) {
2020-08-11 12:07:21 -04:00
bool is_equal = true;
2021-05-12 09:56:44 -04:00
for (std::size_t i = 0; i < N; i++) {
if (lhs[i] != rhs[i])
2020-08-11 12:07:21 -04:00
is_equal = false;
}
2021-05-12 09:56:44 -04:00
2020-08-11 12:07:21 -04:00
return is_equal;
}
template<std::size_t N, class T>
2021-05-12 09:56:44 -04:00
constexpr inline bool operator!=(const prism::Vector<N, T> lhs, const prism::Vector<N, T> rhs) {
2020-08-11 12:07:21 -04:00
return !(lhs == rhs);
}
template<std::size_t N, class T>
2021-05-12 09:56:44 -04:00
constexpr inline prism::Vector<N, T> operator-(const prism::Vector<N, T> lhs, const prism::Vector<N, T> rhs) {
prism::Vector<N, T> vec;
for (std::size_t i = 0; i < N; i++)
2020-08-11 12:07:21 -04:00
vec[i] = lhs[i] - rhs[i];
2021-05-12 09:56:44 -04:00
2020-08-11 12:07:21 -04:00
return vec;
}
template<std::size_t N, class T>
2021-05-12 09:56:44 -04:00
constexpr inline prism::Vector<N, T> operator+(const prism::Vector<N, T> lhs, const prism::Vector<N, T> rhs) {
prism::Vector<N, T> vec;
for (std::size_t i = 0; i < N; i++)
2020-08-11 12:07:21 -04:00
vec[i] = lhs[i] + rhs[i];
2021-05-12 09:56:44 -04:00
2020-08-11 12:07:21 -04:00
return vec;
}
template<std::size_t N, class T>
2021-05-12 09:56:44 -04:00
constexpr inline prism::Vector<N, T> operator*(const prism::Vector<N, T> lhs, const prism::Vector<N, T> rhs) {
prism::Vector<N, T> vec;
for (std::size_t i = 0; i < N; i++)
2020-08-11 12:07:21 -04:00
vec[i] = lhs[i] * rhs[i];
2021-05-12 09:56:44 -04:00
2020-08-11 12:07:21 -04:00
return vec;
}
template<std::size_t N, class T>
2021-05-12 09:56:44 -04:00
constexpr inline prism::Vector<N, T> operator+(const prism::Vector<N, T> lhs, const T scalar) {
prism::Vector<N, T> vec;
for (std::size_t i = 0; i < N; i++)
vec[i] = lhs[i] + scalar;
2021-05-12 09:56:44 -04:00
return vec;
}
2020-08-11 12:07:21 -04:00
template<std::size_t N, class T>
2021-05-12 09:56:44 -04:00
constexpr inline prism::Vector<N, T> operator*(const prism::Vector<N, T> lhs, const T scalar) {
prism::Vector<N, T> vec;
for (std::size_t i = 0; i < N; i++)
2020-08-11 12:07:21 -04:00
vec[i] = lhs[i] * scalar;
2021-05-12 09:56:44 -04:00
2020-08-11 12:07:21 -04:00
return vec;
}
template<std::size_t N, class T>
2021-05-12 09:56:44 -04:00
constexpr inline prism::Vector<N, T> operator/(const prism::Vector<N, T> lhs, const prism::Vector<N, T> rhs) {
prism::Vector<N, T> vec;
for (std::size_t i = 0; i < N; i++)
2020-08-11 12:07:21 -04:00
vec[i] = lhs[i] / rhs[i];
return vec;
}
template<std::size_t N, class T>
2021-05-12 09:56:44 -04:00
constexpr inline prism::Vector<N, T> operator/(const prism::Vector<N, T> lhs, const T scalar) {
prism::Vector<N, T> vec;
for (std::size_t i = 0; i < N; i++)
vec[i] = lhs[i] / scalar;
2020-08-11 12:07:21 -04:00
return vec;
2021-05-12 09:56:44 -04:00
}