aboutsummaryrefslogtreecommitdiffstats
path: root/common/vecmat.h
diff options
context:
space:
mode:
Diffstat (limited to 'common/vecmat.h')
-rw-r--r--common/vecmat.h109
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