Don't assert for unexpected FX slot IDs
[openal-soft.git] / common / vecmat.h
blob90b5d14691744e49ec6e45bb4e3f5bbcefedd0c1
1 #ifndef COMMON_VECMAT_H
2 #define COMMON_VECMAT_H
4 #include <algorithm>
5 #include <array>
6 #include <cmath>
7 #include <cstddef>
8 #include <limits>
10 #include "alspan.h"
13 namespace alu {
15 class Vector {
16 alignas(16) std::array<float,4> mVals{};
18 public:
19 constexpr Vector() noexcept = default;
20 constexpr Vector(const Vector&) noexcept = default;
21 constexpr Vector(Vector&&) noexcept = default;
22 constexpr explicit Vector(float a, float b, float c, float d) noexcept : mVals{{a,b,c,d}} { }
24 constexpr auto operator=(const Vector&) noexcept -> Vector& = default;
25 constexpr auto operator=(Vector&&) noexcept -> Vector& = default;
27 [[nodiscard]] constexpr
28 auto operator[](std::size_t idx) noexcept -> float& { return mVals[idx]; }
29 [[nodiscard]] constexpr
30 auto operator[](std::size_t idx) const noexcept -> const float& { return mVals[idx]; }
32 constexpr auto operator+=(const Vector &rhs) noexcept -> Vector&
34 mVals[0] += rhs.mVals[0];
35 mVals[1] += rhs.mVals[1];
36 mVals[2] += rhs.mVals[2];
37 mVals[3] += rhs.mVals[3];
38 return *this;
41 [[nodiscard]] constexpr
42 auto operator-(const Vector &rhs) const noexcept -> Vector
44 return Vector{mVals[0] - rhs.mVals[0], mVals[1] - rhs.mVals[1],
45 mVals[2] - rhs.mVals[2], mVals[3] - rhs.mVals[3]};
48 constexpr auto normalize(float limit = std::numeric_limits<float>::epsilon()) -> float
50 limit = std::max(limit, std::numeric_limits<float>::epsilon());
51 const auto length_sqr = float{mVals[0]*mVals[0] + mVals[1]*mVals[1] + mVals[2]*mVals[2]};
52 if(length_sqr > limit*limit)
54 const auto length = float{std::sqrt(length_sqr)};
55 auto inv_length = float{1.0f / length};
56 mVals[0] *= inv_length;
57 mVals[1] *= inv_length;
58 mVals[2] *= inv_length;
59 return length;
61 mVals[0] = mVals[1] = mVals[2] = 0.0f;
62 return 0.0f;
65 [[nodiscard]] constexpr auto cross_product(const Vector &rhs) const noexcept -> Vector
67 return Vector{
68 mVals[1]*rhs.mVals[2] - mVals[2]*rhs.mVals[1],
69 mVals[2]*rhs.mVals[0] - mVals[0]*rhs.mVals[2],
70 mVals[0]*rhs.mVals[1] - mVals[1]*rhs.mVals[0],
71 0.0f};
74 [[nodiscard]] constexpr auto dot_product(const Vector &rhs) const noexcept -> float
75 { return mVals[0]*rhs.mVals[0] + mVals[1]*rhs.mVals[1] + mVals[2]*rhs.mVals[2]; }
78 class Matrix {
79 alignas(16) std::array<float,16> mVals{};
81 public:
82 constexpr Matrix() noexcept = default;
83 constexpr Matrix(const Matrix&) noexcept = default;
84 constexpr Matrix(Matrix&&) noexcept = default;
85 constexpr explicit Matrix(
86 float aa, float ab, float ac, float ad,
87 float ba, float bb, float bc, float bd,
88 float ca, float cb, float cc, float cd,
89 float da, float db, float dc, float dd) noexcept
90 : mVals{{aa,ab,ac,ad, ba,bb,bc,bd, ca,cb,cc,cd, da,db,dc,dd}}
91 { }
93 constexpr auto operator=(const Matrix&) noexcept -> Matrix& = default;
94 constexpr auto operator=(Matrix&&) noexcept -> Matrix& = default;
96 [[nodiscard]] constexpr auto operator[](std::size_t idx) noexcept
97 { return al::span<float,4>{&mVals[idx*4], 4}; }
98 [[nodiscard]] constexpr auto operator[](std::size_t idx) const noexcept
99 { return al::span<const float,4>{&mVals[idx*4], 4}; }
101 [[nodiscard]] static constexpr auto Identity() noexcept -> Matrix
103 return Matrix{
104 1.0f, 0.0f, 0.0f, 0.0f,
105 0.0f, 1.0f, 0.0f, 0.0f,
106 0.0f, 0.0f, 1.0f, 0.0f,
107 0.0f, 0.0f, 0.0f, 1.0f};
110 [[nodiscard]] friend constexpr
111 auto operator*(const Matrix &mtx, const Vector &vec) noexcept -> Vector
113 return Vector{
114 vec[0]*mtx[0][0] + vec[1]*mtx[1][0] + vec[2]*mtx[2][0] + vec[3]*mtx[3][0],
115 vec[0]*mtx[0][1] + vec[1]*mtx[1][1] + vec[2]*mtx[2][1] + vec[3]*mtx[3][1],
116 vec[0]*mtx[0][2] + vec[1]*mtx[1][2] + vec[2]*mtx[2][2] + vec[3]*mtx[3][2],
117 vec[0]*mtx[0][3] + vec[1]*mtx[1][3] + vec[2]*mtx[2][3] + vec[3]*mtx[3][3]};
121 } // namespace alu
123 #endif /* COMMON_VECMAT_H */