diff options
Diffstat (limited to 'common/vecmat.h')
-rw-r--r-- | common/vecmat.h | 109 |
1 files changed, 70 insertions, 39 deletions
diff --git a/common/vecmat.h b/common/vecmat.h index cdf47125..5a61ad14 100644 --- a/common/vecmat.h +++ b/common/vecmat.h @@ -6,22 +6,26 @@ #include <cstddef> #include <limits> +#include "alspan.h" + namespace alu { -class Vector { - alignas(16) std::array<float,4> mVals; +template<typename T, std::enable_if_t<std::is_floating_point<T>::value, bool> = true> +class VectorR { + alignas(16) std::array<T,4> mVals; public: - Vector() noexcept = default; - constexpr Vector(float a, float b, float c, float d) noexcept - : mVals{{a, b, c, d}} - { } + constexpr VectorR() noexcept = default; + constexpr VectorR(const VectorR&) noexcept = default; + constexpr VectorR(T a, T b, T c, T d) noexcept : mVals{{a, b, c, d}} { } + + constexpr VectorR& operator=(const VectorR&) noexcept = default; - float& operator[](size_t idx) noexcept { return mVals[idx]; } - constexpr const float& operator[](size_t idx) const noexcept { return mVals[idx]; } + T& operator[](size_t idx) noexcept { return mVals[idx]; } + constexpr const T& operator[](size_t idx) const noexcept { return mVals[idx]; } - Vector& operator+=(const Vector &rhs) noexcept + VectorR& operator+=(const VectorR &rhs) noexcept { mVals[0] += rhs.mVals[0]; mVals[1] += rhs.mVals[1]; @@ -30,55 +34,82 @@ public: return *this; } - float normalize() + T normalize() { - const float length{std::sqrt(mVals[0]*mVals[0] + mVals[1]*mVals[1] + mVals[2]*mVals[2])}; - if(length > std::numeric_limits<float>::epsilon()) + const T length{std::sqrt(mVals[0]*mVals[0] + mVals[1]*mVals[1] + mVals[2]*mVals[2])}; + if(length > std::numeric_limits<T>::epsilon()) { - float inv_length = 1.0f/length; + T inv_length{T{1}/length}; mVals[0] *= inv_length; mVals[1] *= inv_length; mVals[2] *= inv_length; return length; } - mVals[0] = mVals[1] = mVals[2] = 0.0f; - return 0.0f; + mVals[0] = mVals[1] = mVals[2] = T{0}; + return T{0}; + } + + constexpr VectorR cross_product(const alu::VectorR<T> &rhs) const + { + return VectorR{ + (*this)[1]*rhs[2] - (*this)[2]*rhs[1], + (*this)[2]*rhs[0] - (*this)[0]*rhs[2], + (*this)[0]*rhs[1] - (*this)[1]*rhs[0], + T{0}}; } + + constexpr T dot_product(const alu::VectorR<T> &rhs) const + { return (*this)[0]*rhs[0] + (*this)[1]*rhs[1] + (*this)[2]*rhs[2]; } }; +using Vector = VectorR<float>; -class Matrix { - alignas(16) std::array<std::array<float,4>,4> mVals; +template<typename T, std::enable_if_t<std::is_floating_point<T>::value, bool> = true> +class MatrixR { + alignas(16) std::array<T,16> mVals; public: - Matrix() noexcept = default; - constexpr Matrix(float aa, float ab, float ac, float ad, - float ba, float bb, float bc, float bd, - float ca, float cb, float cc, float cd, - float da, float db, float dc, float dd) noexcept - : mVals{{{{aa, ab, ac, ad}}, {{ba, bb, bc, bd}}, {{ca, cb, cc, cd}}, {{da, db, dc, dd}}}} + constexpr MatrixR() noexcept = default; + constexpr MatrixR(const MatrixR&) noexcept = default; + constexpr MatrixR(T aa, T ab, T ac, T ad, + T ba, T bb, T bc, T bd, + T ca, T cb, T cc, T cd, + T da, T db, T dc, T dd) noexcept + : mVals{{aa,ab,ac,ad, ba,bb,bc,bd, ca,cb,cc,cd, da,db,dc,dd}} { } - std::array<float,4>& operator[](size_t idx) noexcept { return mVals[idx]; } - constexpr const std::array<float,4>& operator[](size_t idx) const noexcept { return mVals[idx]; } + constexpr MatrixR& operator=(const MatrixR&) noexcept = default; - void setRow(size_t idx, float a, float b, float c, float d) noexcept - { - mVals[idx][0] = a; - mVals[idx][1] = b; - mVals[idx][2] = c; - mVals[idx][3] = d; - } + auto operator[](size_t idx) noexcept { return al::span<T,4>{&mVals[idx*4], 4}; } + constexpr auto operator[](size_t idx) const noexcept + { return al::span<const T,4>{&mVals[idx*4], 4}; } - static constexpr Matrix Identity() noexcept + static constexpr MatrixR Identity() noexcept { - return Matrix{ - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; + return MatrixR{ + T{1}, T{0}, T{0}, T{0}, + T{0}, T{1}, T{0}, T{0}, + T{0}, T{0}, T{1}, T{0}, + T{0}, T{0}, T{0}, T{1}}; } }; +using Matrix = MatrixR<float>; + +template<typename T> +inline VectorR<T> operator*(const MatrixR<T> &mtx, const VectorR<T> &vec) noexcept +{ + return VectorR<T>{ + vec[0]*mtx[0][0] + vec[1]*mtx[1][0] + vec[2]*mtx[2][0] + vec[3]*mtx[3][0], + vec[0]*mtx[0][1] + vec[1]*mtx[1][1] + vec[2]*mtx[2][1] + vec[3]*mtx[3][1], + vec[0]*mtx[0][2] + vec[1]*mtx[1][2] + vec[2]*mtx[2][2] + vec[3]*mtx[3][2], + vec[0]*mtx[0][3] + vec[1]*mtx[1][3] + vec[2]*mtx[2][3] + vec[3]*mtx[3][3]}; +} + +template<typename U, typename T> +inline VectorR<U> cast_to(const VectorR<T> &vec) noexcept +{ + return VectorR<U>{static_cast<U>(vec[0]), static_cast<U>(vec[1]), + static_cast<U>(vec[2]), static_cast<U>(vec[3])}; +} } // namespace alu |