diff options
author | Chris Robinson <[email protected]> | 2020-11-13 23:33:40 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-11-13 23:33:40 -0800 |
commit | e64c52ce8c3552452b78e951966bbef589cf0e97 (patch) | |
tree | 03777940d721d60e37731b3c6d61473cd16dbb0f /common/vecmat.h | |
parent | 417d8da6f4baf727e1a4b55ff17189bf2d1a3447 (diff) |
Use doubles to calculate the listener matrix translation
To help stablize sources near the listener, when away from origin. Also clean
up some related methods and move them to more appropriate places.
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 |