Use kAudioObjectPropertyElementMaster on macOS for compatibility
[openal-soft.git] / common / vecmat.h
blob9bb5a47d0c5ea6487fb5b6dc898da92bfa23049d
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
50 const auto length_sqr = float{mVals[0]*mVals[0] + mVals[1]*mVals[1] + mVals[2]*mVals[2]};
51 if(length_sqr > std::numeric_limits<float>::epsilon())
53 const auto length = float{std::sqrt(length_sqr)};
54 auto inv_length = float{1.0f / length};
55 mVals[0] *= inv_length;
56 mVals[1] *= inv_length;
57 mVals[2] *= inv_length;
58 return length;
60 mVals[0] = mVals[1] = mVals[2] = 0.0f;
61 return 0.0f;
64 [[nodiscard]] constexpr auto cross_product(const Vector &rhs) const noexcept -> Vector
66 return Vector{
67 mVals[1]*rhs.mVals[2] - mVals[2]*rhs.mVals[1],
68 mVals[2]*rhs.mVals[0] - mVals[0]*rhs.mVals[2],
69 mVals[0]*rhs.mVals[1] - mVals[1]*rhs.mVals[0],
70 0.0f};
73 [[nodiscard]] constexpr auto dot_product(const Vector &rhs) const noexcept -> float
74 { return mVals[0]*rhs.mVals[0] + mVals[1]*rhs.mVals[1] + mVals[2]*rhs.mVals[2]; }
77 class Matrix {
78 alignas(16) std::array<float,16> mVals{};
80 public:
81 constexpr Matrix() noexcept = default;
82 constexpr Matrix(const Matrix&) noexcept = default;
83 constexpr Matrix(Matrix&&) noexcept = default;
84 constexpr explicit Matrix(
85 float aa, float ab, float ac, float ad,
86 float ba, float bb, float bc, float bd,
87 float ca, float cb, float cc, float cd,
88 float da, float db, float dc, float dd) noexcept
89 : mVals{{aa,ab,ac,ad, ba,bb,bc,bd, ca,cb,cc,cd, da,db,dc,dd}}
90 { }
92 constexpr auto operator=(const Matrix&) noexcept -> Matrix& = default;
93 constexpr auto operator=(Matrix&&) noexcept -> Matrix& = default;
95 [[nodiscard]] constexpr auto operator[](std::size_t idx) noexcept
96 { return al::span<float,4>{&mVals[idx*4], 4}; }
97 [[nodiscard]] constexpr auto operator[](std::size_t idx) const noexcept
98 { return al::span<const float,4>{&mVals[idx*4], 4}; }
100 [[nodiscard]] static constexpr auto Identity() noexcept -> Matrix
102 return Matrix{
103 1.0f, 0.0f, 0.0f, 0.0f,
104 0.0f, 1.0f, 0.0f, 0.0f,
105 0.0f, 0.0f, 1.0f, 0.0f,
106 0.0f, 0.0f, 0.0f, 1.0f};
109 [[nodiscard]] friend constexpr
110 auto operator*(const Matrix &mtx, const Vector &vec) noexcept -> Vector
112 return Vector{
113 vec[0]*mtx[0][0] + vec[1]*mtx[1][0] + vec[2]*mtx[2][0] + vec[3]*mtx[3][0],
114 vec[0]*mtx[0][1] + vec[1]*mtx[1][1] + vec[2]*mtx[2][1] + vec[3]*mtx[3][1],
115 vec[0]*mtx[0][2] + vec[1]*mtx[1][2] + vec[2]*mtx[2][2] + vec[3]*mtx[3][2],
116 vec[0]*mtx[0][3] + vec[1]*mtx[1][3] + vec[2]*mtx[2][3] + vec[3]*mtx[3][3]};
120 } // namespace alu
122 #endif /* COMMON_VECMAT_H */