Files
eden/src/common/vector_math.h
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

135 lines
4.6 KiB
C++
Raw Normal View History

2026-08-31 19:26:09 +00:00
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
2022-04-28 18:24:11 +02:00
// SPDX-FileCopyrightText: 2014 Tony Wasserka
// SPDX-FileCopyrightText: 2014 Dolphin Emulator Project
// SPDX-License-Identifier: BSD-3-Clause AND GPL-2.0-or-later
#pragma once
#include <cmath>
#include <type_traits>
namespace Common {
2026-09-01 05:56:47 +00:00
template <typename T, size_t N>
class Vec {
public:
2026-09-01 05:56:47 +00:00
std::array<T, N> elems{};
2026-09-01 05:56:47 +00:00
constexpr Vec() = default;
constexpr Vec(T e0) noexcept : elems{e0} {}
constexpr Vec(T e0, T e1) noexcept : elems{e0, e1} {}
constexpr Vec(T e0, T e1, T e2) noexcept : elems{e0, e1, e2} {}
constexpr Vec(T e0, T e1, T e2, T e4) noexcept : elems{e0, e1, e2, e4} {}
//explicit constexpr Vec(const std::initializer_list<T> elems_) noexcept : elems{elems_} {}
2026-09-01 05:56:47 +00:00
[[nodiscard]] constexpr Vec<decltype(T{} + T{}), N> operator+(const Vec o) const noexcept {
Vec<decltype(T{} + T{}), N> r{};
for (size_t i = 0; i < N; ++i)
r.elems[i] = elems[i] + o.elems[i];
return r;
}
2026-09-01 05:56:47 +00:00
constexpr Vec<T, N> operator+=(const Vec<T, N> o) noexcept { return *this = *this + o; }
2026-09-01 05:56:47 +00:00
[[nodiscard]] constexpr Vec<decltype(T{} - T{}), N> operator-(const Vec o) const noexcept {
Vec<decltype(T{} - T{}), N> r{};
for (size_t i = 0; i < N; ++i)
r.elems[i] = elems[i] - o.elems[i];
return r;
}
2026-09-01 05:56:47 +00:00
constexpr Vec<T, N> operator-=(const Vec<T, N> o) noexcept { return *this = *this - o; }
2017-07-11 19:51:29 +03:00
template <typename U = T>
2026-09-01 05:56:47 +00:00
[[nodiscard]] constexpr Vec<std::enable_if_t<std::is_signed_v<U>, U>, N> operator-() const noexcept {
Vec<U, N> r{};
for (size_t i = 0; i < N; ++i)
r.elems[i] = -elems[i];
return r;
}
2026-09-01 05:56:47 +00:00
[[nodiscard]] constexpr Vec<decltype(T{} * T{}), N> operator*(const Vec o) const noexcept {
Vec<decltype(T{} * T{}), N> r{};
for (size_t i = 0; i < N; ++i)
r.elems[i] = elems[i] * o.elems[i];
return r;
}
2016-09-18 09:38:01 +09:00
template <typename V>
2026-09-01 05:56:47 +00:00
[[nodiscard]] constexpr Vec<decltype(T{} * V{}), N> operator*(const V f) const noexcept {
using TV = decltype(T{} * V{});
using C = std::common_type_t<T, V>;
2026-09-01 05:56:47 +00:00
Vec<TV, N> r{};
for (size_t i = 0; i < N; ++i)
r.elems[i] = TV(C(elems[i]) * C(f));
return r;
}
2016-09-18 09:38:01 +09:00
template <typename V>
2026-09-01 05:56:47 +00:00
constexpr Vec<T, N> operator*=(const V f) noexcept { return *this = *this * f; }
2016-09-18 09:38:01 +09:00
template <typename V>
2026-09-01 05:56:47 +00:00
[[nodiscard]] constexpr Vec<decltype(T{} / V{}), N> operator/(const V f) const noexcept {
using TV = decltype(T{} / V{});
using C = std::common_type_t<T, V>;
2026-09-01 05:56:47 +00:00
Vec<TV, N> r{};
for (size_t i = 0; i < N; ++i)
r.elems[i] = TV(C(elems[i]) / C(f));
return r;
}
2016-09-18 09:38:01 +09:00
template <typename V>
2026-09-01 05:56:47 +00:00
constexpr Vec<T, N> operator/=(const V f) noexcept { return *this = *this / f; }
2026-08-31 19:26:09 +00:00
[[nodiscard]] constexpr T Length2() const noexcept {
2026-09-01 05:56:47 +00:00
T r{};
for (size_t i = 0; i < N; ++i)
r += elems[i] * elems[i];
return r;
}
// Only implemented for T=float
2026-09-01 05:56:47 +00:00
[[nodiscard]] T Length() const { return T(std::sqrt(float(Length2()))); }
[[nodiscard]] Vec<T, N> Normalized() const { return *this / Length(); }
[[nodiscard]] constexpr T& operator[](std::size_t i) noexcept { return elems[i]; }
[[nodiscard]] constexpr const T& operator[](std::size_t i) const noexcept { return elems[i]; }
2026-08-31 19:26:09 +00:00
[[nodiscard]] std::array<decltype(-T{}), 16> ToMatrix() const {
2026-09-01 05:56:47 +00:00
const T x2 = elems[0] * elems[0];
const T y2 = elems[1] * elems[1];
const T z2 = elems[2] * elems[2];
const T xy = elems[0] * elems[1];
const T wz = elems[3] * elems[2];
const T xz = elems[0] * elems[2];
const T wy = elems[3] * elems[1];
const T yz = elems[1] * elems[2];
const T wx = elems[3] * elems[0];
return {
2026-08-31 19:26:09 +00:00
1.0f - 2.0f * (y2 + z2),
2.0f * (xy + wz),
2.0f * (xz - wy),
0.0f,
2.0f * (xy - wz),
1.0f - 2.0f * (x2 + z2),
2.0f * (yz + wx),
0.0f,
2.0f * (xz + wy),
2.0f * (yz - wx),
1.0f - 2.0f * (x2 + y2),
0.0f,
0.0f,
0.0f,
0.0f,
1.0f
};
}
};
2026-09-01 05:56:47 +00:00
template <typename T, size_t N, typename V>
[[nodiscard]] constexpr Vec<T, N> operator*(const V f, const Vec<T, N> v) noexcept {
using C = std::common_type_t<T, V>;
Vec<T, N> r{};
for (size_t i = 0; i < N; ++i)
r.elems[i] = T(C(f) * C(v.elems[i]));
return r;
}
} // namespace Common