vecmat.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #ifndef COMMON_VECMAT_H
  2. #define COMMON_VECMAT_H
  3. #include <algorithm>
  4. #include <array>
  5. #include <cmath>
  6. #include <cstddef>
  7. #include <limits>
  8. #include "alspan.h"
  9. namespace alu {
  10. class Vector {
  11. alignas(16) std::array<float,4> mVals{};
  12. public:
  13. constexpr Vector() noexcept = default;
  14. constexpr Vector(const Vector&) noexcept = default;
  15. constexpr Vector(Vector&&) noexcept = default;
  16. constexpr explicit Vector(float a, float b, float c, float d) noexcept : mVals{{a,b,c,d}} { }
  17. constexpr auto operator=(const Vector&) noexcept -> Vector& = default;
  18. constexpr auto operator=(Vector&&) noexcept -> Vector& = default;
  19. [[nodiscard]] constexpr
  20. auto operator[](std::size_t idx) noexcept -> float& { return mVals[idx]; }
  21. [[nodiscard]] constexpr
  22. auto operator[](std::size_t idx) const noexcept -> const float& { return mVals[idx]; }
  23. constexpr auto operator+=(const Vector &rhs) noexcept -> Vector&
  24. {
  25. mVals[0] += rhs.mVals[0];
  26. mVals[1] += rhs.mVals[1];
  27. mVals[2] += rhs.mVals[2];
  28. mVals[3] += rhs.mVals[3];
  29. return *this;
  30. }
  31. [[nodiscard]] constexpr
  32. auto operator-(const Vector &rhs) const noexcept -> Vector
  33. {
  34. return Vector{mVals[0] - rhs.mVals[0], mVals[1] - rhs.mVals[1],
  35. mVals[2] - rhs.mVals[2], mVals[3] - rhs.mVals[3]};
  36. }
  37. constexpr auto normalize(float limit = std::numeric_limits<float>::epsilon()) -> float
  38. {
  39. limit = std::max(limit, std::numeric_limits<float>::epsilon());
  40. const auto length_sqr = float{mVals[0]*mVals[0] + mVals[1]*mVals[1] + mVals[2]*mVals[2]};
  41. if(length_sqr > limit*limit)
  42. {
  43. const auto length = float{std::sqrt(length_sqr)};
  44. auto inv_length = float{1.0f / length};
  45. mVals[0] *= inv_length;
  46. mVals[1] *= inv_length;
  47. mVals[2] *= inv_length;
  48. return length;
  49. }
  50. mVals[0] = mVals[1] = mVals[2] = 0.0f;
  51. return 0.0f;
  52. }
  53. [[nodiscard]] constexpr auto cross_product(const Vector &rhs) const noexcept -> Vector
  54. {
  55. return Vector{
  56. mVals[1]*rhs.mVals[2] - mVals[2]*rhs.mVals[1],
  57. mVals[2]*rhs.mVals[0] - mVals[0]*rhs.mVals[2],
  58. mVals[0]*rhs.mVals[1] - mVals[1]*rhs.mVals[0],
  59. 0.0f};
  60. }
  61. [[nodiscard]] constexpr auto dot_product(const Vector &rhs) const noexcept -> float
  62. { return mVals[0]*rhs.mVals[0] + mVals[1]*rhs.mVals[1] + mVals[2]*rhs.mVals[2]; }
  63. };
  64. class Matrix {
  65. alignas(16) std::array<float,16> mVals{};
  66. public:
  67. constexpr Matrix() noexcept = default;
  68. constexpr Matrix(const Matrix&) noexcept = default;
  69. constexpr Matrix(Matrix&&) noexcept = default;
  70. constexpr explicit Matrix(
  71. float aa, float ab, float ac, float ad,
  72. float ba, float bb, float bc, float bd,
  73. float ca, float cb, float cc, float cd,
  74. float da, float db, float dc, float dd) noexcept
  75. : mVals{{aa,ab,ac,ad, ba,bb,bc,bd, ca,cb,cc,cd, da,db,dc,dd}}
  76. { }
  77. constexpr auto operator=(const Matrix&) noexcept -> Matrix& = default;
  78. constexpr auto operator=(Matrix&&) noexcept -> Matrix& = default;
  79. [[nodiscard]] constexpr auto operator[](std::size_t idx) noexcept
  80. { return al::span<float,4>{&mVals[idx*4], 4}; }
  81. [[nodiscard]] constexpr auto operator[](std::size_t idx) const noexcept
  82. { return al::span<const float,4>{&mVals[idx*4], 4}; }
  83. [[nodiscard]] static constexpr auto Identity() noexcept -> Matrix
  84. {
  85. return Matrix{
  86. 1.0f, 0.0f, 0.0f, 0.0f,
  87. 0.0f, 1.0f, 0.0f, 0.0f,
  88. 0.0f, 0.0f, 1.0f, 0.0f,
  89. 0.0f, 0.0f, 0.0f, 1.0f};
  90. }
  91. [[nodiscard]] friend constexpr
  92. auto operator*(const Matrix &mtx, const Vector &vec) noexcept -> Vector
  93. {
  94. return Vector{
  95. vec[0]*mtx[0][0] + vec[1]*mtx[1][0] + vec[2]*mtx[2][0] + vec[3]*mtx[3][0],
  96. vec[0]*mtx[0][1] + vec[1]*mtx[1][1] + vec[2]*mtx[2][1] + vec[3]*mtx[3][1],
  97. vec[0]*mtx[0][2] + vec[1]*mtx[1][2] + vec[2]*mtx[2][2] + vec[3]*mtx[3][2],
  98. vec[0]*mtx[0][3] + vec[1]*mtx[1][3] + vec[2]*mtx[2][3] + vec[3]*mtx[3][3]};
  99. }
  100. };
  101. } // namespace alu
  102. #endif /* COMMON_VECMAT_H */