Matrix.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. // Copyright 2019 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <cmath>
  6. #include <functional>
  7. #include <type_traits>
  8. // Tiny matrix/vector library.
  9. // Used for things like Free-Look in the gfx backend.
  10. namespace Common
  11. {
  12. template <typename T>
  13. union TVec3
  14. {
  15. constexpr TVec3() = default;
  16. constexpr TVec3(T _x, T _y, T _z) : data{_x, _y, _z} {}
  17. template <typename OtherT>
  18. constexpr explicit TVec3(const TVec3<OtherT>& other) : TVec3(other.x, other.y, other.z)
  19. {
  20. }
  21. constexpr bool operator==(const TVec3& other) const
  22. {
  23. return x == other.x && y == other.y && z == other.z;
  24. }
  25. constexpr TVec3 Cross(const TVec3& rhs) const
  26. {
  27. return {(y * rhs.z) - (rhs.y * z), (z * rhs.x) - (rhs.z * x), (x * rhs.y) - (rhs.x * y)};
  28. }
  29. constexpr T Dot(const TVec3& other) const { return x * other.x + y * other.y + z * other.z; }
  30. constexpr T LengthSquared() const { return Dot(*this); }
  31. T Length() const { return std::sqrt(LengthSquared()); }
  32. TVec3 Normalized() const { return *this / Length(); }
  33. constexpr TVec3& operator+=(const TVec3& rhs)
  34. {
  35. x += rhs.x;
  36. y += rhs.y;
  37. z += rhs.z;
  38. return *this;
  39. }
  40. constexpr TVec3& operator-=(const TVec3& rhs)
  41. {
  42. x -= rhs.x;
  43. y -= rhs.y;
  44. z -= rhs.z;
  45. return *this;
  46. }
  47. constexpr TVec3& operator*=(const TVec3& rhs)
  48. {
  49. x *= rhs.x;
  50. y *= rhs.y;
  51. z *= rhs.z;
  52. return *this;
  53. }
  54. constexpr TVec3& operator/=(const TVec3& rhs)
  55. {
  56. x /= rhs.x;
  57. y /= rhs.y;
  58. z /= rhs.z;
  59. return *this;
  60. }
  61. constexpr TVec3 operator-() const { return {-x, -y, -z}; }
  62. // Apply function to each element and return the result.
  63. template <typename F>
  64. auto Map(F&& f) const -> TVec3<decltype(f(T{}))>
  65. {
  66. return {f(x), f(y), f(z)};
  67. }
  68. template <typename F, typename T2>
  69. auto Map(F&& f, const TVec3<T2>& t) const -> TVec3<decltype(f(T{}, t.x))>
  70. {
  71. return {f(x, t.x), f(y, t.y), f(z, t.z)};
  72. }
  73. template <typename F, typename T2>
  74. auto Map(F&& f, T2 scalar) const -> TVec3<decltype(f(T{}, scalar))>
  75. {
  76. return {f(x, scalar), f(y, scalar), f(z, scalar)};
  77. }
  78. std::array<T, 3> data = {};
  79. struct
  80. {
  81. T x;
  82. T y;
  83. T z;
  84. };
  85. };
  86. template <typename T>
  87. TVec3<bool> operator<(const TVec3<T>& lhs, const TVec3<T>& rhs)
  88. {
  89. return lhs.Map(std::less<T>{}, rhs);
  90. }
  91. constexpr TVec3<bool> operator!(const TVec3<bool>& vec)
  92. {
  93. return {!vec.x, !vec.y, !vec.z};
  94. }
  95. template <typename T>
  96. auto operator+(const TVec3<T>& lhs, const TVec3<T>& rhs) -> TVec3<decltype(lhs.x + rhs.x)>
  97. {
  98. return lhs.Map(std::plus<decltype(lhs.x + rhs.x)>{}, rhs);
  99. }
  100. template <typename T>
  101. auto operator-(const TVec3<T>& lhs, const TVec3<T>& rhs) -> TVec3<decltype(lhs.x - rhs.x)>
  102. {
  103. return lhs.Map(std::minus<decltype(lhs.x - rhs.x)>{}, rhs);
  104. }
  105. template <typename T1, typename T2>
  106. auto operator*(const TVec3<T1>& lhs, const TVec3<T2>& rhs) -> TVec3<decltype(lhs.x * rhs.x)>
  107. {
  108. return lhs.Map(std::multiplies<decltype(lhs.x * rhs.x)>{}, rhs);
  109. }
  110. template <typename T>
  111. auto operator/(const TVec3<T>& lhs, const TVec3<T>& rhs) -> TVec3<decltype(lhs.x / rhs.x)>
  112. {
  113. return lhs.Map(std::divides<decltype(lhs.x / rhs.x)>{}, rhs);
  114. }
  115. template <typename T1, typename T2>
  116. auto operator*(const TVec3<T1>& lhs, T2 scalar) -> TVec3<decltype(lhs.x * scalar)>
  117. {
  118. return lhs.Map(std::multiplies<decltype(lhs.x * scalar)>{}, scalar);
  119. }
  120. template <typename T1, typename T2>
  121. auto operator/(const TVec3<T1>& lhs, T2 scalar) -> TVec3<decltype(lhs.x / scalar)>
  122. {
  123. return lhs.Map(std::divides<decltype(lhs.x / scalar)>{}, scalar);
  124. }
  125. using Vec3 = TVec3<float>;
  126. using DVec3 = TVec3<double>;
  127. template <typename T>
  128. union TVec4
  129. {
  130. constexpr TVec4() = default;
  131. constexpr TVec4(TVec3<T> _vec, T _w) : TVec4{_vec.x, _vec.y, _vec.z, _w} {}
  132. constexpr TVec4(T _x, T _y, T _z, T _w) : data{_x, _y, _z, _w} {}
  133. constexpr bool operator==(const TVec4& other) const
  134. {
  135. return x == other.x && y == other.y && z == other.z && w == other.w;
  136. }
  137. constexpr T Dot(const TVec4& other) const
  138. {
  139. return x * other.x + y * other.y + z * other.z + w * other.w;
  140. }
  141. constexpr TVec4& operator*=(const TVec4& rhs)
  142. {
  143. x *= rhs.x;
  144. y *= rhs.y;
  145. z *= rhs.z;
  146. w *= rhs.w;
  147. return *this;
  148. }
  149. constexpr TVec4& operator/=(const TVec4& rhs)
  150. {
  151. x /= rhs.x;
  152. y /= rhs.y;
  153. z /= rhs.z;
  154. w /= rhs.w;
  155. return *this;
  156. }
  157. constexpr TVec4& operator*=(T scalar) { return *this *= TVec4{scalar, scalar, scalar, scalar}; }
  158. constexpr TVec4& operator/=(T scalar) { return *this /= TVec4{scalar, scalar, scalar, scalar}; }
  159. std::array<T, 4> data = {};
  160. struct
  161. {
  162. T x;
  163. T y;
  164. T z;
  165. T w;
  166. };
  167. };
  168. template <typename T>
  169. constexpr TVec4<T> operator*(TVec4<T> lhs, std::common_type_t<T> scalar)
  170. {
  171. return lhs *= scalar;
  172. }
  173. template <typename T>
  174. constexpr TVec4<T> operator/(TVec4<T> lhs, std::common_type_t<T> scalar)
  175. {
  176. return lhs /= scalar;
  177. }
  178. using Vec4 = TVec4<float>;
  179. using DVec4 = TVec4<double>;
  180. template <typename T>
  181. union TVec2
  182. {
  183. constexpr TVec2() = default;
  184. constexpr TVec2(T _x, T _y) : data{_x, _y} {}
  185. template <typename OtherT>
  186. constexpr explicit TVec2(const TVec2<OtherT>& other) : TVec2(other.x, other.y)
  187. {
  188. }
  189. constexpr bool operator==(const TVec2& other) const { return x == other.x && y == other.y; }
  190. constexpr T Cross(const TVec2& rhs) const { return (x * rhs.y) - (y * rhs.x); }
  191. constexpr T Dot(const TVec2& rhs) const { return (x * rhs.x) + (y * rhs.y); }
  192. constexpr T LengthSquared() const { return Dot(*this); }
  193. T Length() const { return std::sqrt(LengthSquared()); }
  194. TVec2 Normalized() const { return *this / Length(); }
  195. constexpr TVec2& operator+=(const TVec2& rhs)
  196. {
  197. x += rhs.x;
  198. y += rhs.y;
  199. return *this;
  200. }
  201. constexpr TVec2& operator-=(const TVec2& rhs)
  202. {
  203. x -= rhs.x;
  204. y -= rhs.y;
  205. return *this;
  206. }
  207. constexpr TVec2& operator*=(const TVec2& rhs)
  208. {
  209. x *= rhs.x;
  210. y *= rhs.y;
  211. return *this;
  212. }
  213. constexpr TVec2& operator/=(const TVec2& rhs)
  214. {
  215. x /= rhs.x;
  216. y /= rhs.y;
  217. return *this;
  218. }
  219. constexpr TVec2& operator*=(T scalar)
  220. {
  221. x *= scalar;
  222. y *= scalar;
  223. return *this;
  224. }
  225. constexpr TVec2& operator/=(T scalar)
  226. {
  227. x /= scalar;
  228. y /= scalar;
  229. return *this;
  230. }
  231. constexpr TVec2 operator-() const { return {-x, -y}; }
  232. std::array<T, 2> data = {};
  233. struct
  234. {
  235. T x;
  236. T y;
  237. };
  238. };
  239. template <typename T>
  240. constexpr TVec2<bool> operator<(const TVec2<T>& lhs, const TVec2<T>& rhs)
  241. {
  242. return {lhs.x < rhs.x, lhs.y < rhs.y};
  243. }
  244. constexpr TVec2<bool> operator!(const TVec2<bool>& vec)
  245. {
  246. return {!vec.x, !vec.y};
  247. }
  248. template <typename T>
  249. constexpr TVec2<T> operator+(TVec2<T> lhs, const TVec2<T>& rhs)
  250. {
  251. return lhs += rhs;
  252. }
  253. template <typename T>
  254. constexpr TVec2<T> operator-(TVec2<T> lhs, const TVec2<T>& rhs)
  255. {
  256. return lhs -= rhs;
  257. }
  258. template <typename T>
  259. constexpr TVec2<T> operator*(TVec2<T> lhs, const TVec2<T>& rhs)
  260. {
  261. return lhs *= rhs;
  262. }
  263. template <typename T>
  264. constexpr TVec2<T> operator/(TVec2<T> lhs, const TVec2<T>& rhs)
  265. {
  266. return lhs /= rhs;
  267. }
  268. template <typename T, typename T2>
  269. constexpr auto operator*(TVec2<T> lhs, T2 scalar)
  270. {
  271. return TVec2<decltype(lhs.x * scalar)>(lhs) *= scalar;
  272. }
  273. template <typename T, typename T2>
  274. constexpr auto operator/(TVec2<T> lhs, T2 scalar)
  275. {
  276. return TVec2<decltype(lhs.x / scalar)>(lhs) /= scalar;
  277. }
  278. using Vec2 = TVec2<float>;
  279. using DVec2 = TVec2<double>;
  280. class Matrix33;
  281. class Quaternion
  282. {
  283. public:
  284. static Quaternion Identity();
  285. static Quaternion RotateX(float rad);
  286. static Quaternion RotateY(float rad);
  287. static Quaternion RotateZ(float rad);
  288. // Returns a quaternion with rotations about each axis simulatenously (e.g processing gyroscope
  289. // input)
  290. static Quaternion RotateXYZ(const Vec3& rads);
  291. static Quaternion Rotate(float rad, const Vec3& axis);
  292. Quaternion() = default;
  293. Quaternion(float w, float x, float y, float z);
  294. float Norm() const;
  295. Quaternion Normalized() const;
  296. Quaternion Conjugate() const;
  297. Quaternion Inverted() const;
  298. Quaternion& operator*=(const Quaternion& rhs);
  299. Vec4 data;
  300. };
  301. Quaternion operator*(Quaternion lhs, const Quaternion& rhs);
  302. Vec3 operator*(const Quaternion& lhs, const Vec3& rhs);
  303. Vec3 FromQuaternionToEuler(const Quaternion& q);
  304. class Matrix33
  305. {
  306. public:
  307. static Matrix33 Identity();
  308. static Matrix33 FromQuaternion(const Quaternion&);
  309. // Return a rotation matrix around the x,y,z axis
  310. static Matrix33 RotateX(float rad);
  311. static Matrix33 RotateY(float rad);
  312. static Matrix33 RotateZ(float rad);
  313. static Matrix33 Rotate(float rad, const Vec3& axis);
  314. static Matrix33 Scale(const Vec3& vec);
  315. // set result = a x b
  316. static void Multiply(const Matrix33& a, const Matrix33& b, Matrix33* result);
  317. static void Multiply(const Matrix33& a, const Vec3& vec, Vec3* result);
  318. Matrix33 Inverted() const;
  319. float Determinant() const;
  320. Matrix33& operator*=(const Matrix33& rhs)
  321. {
  322. Multiply(*this, rhs, this);
  323. return *this;
  324. }
  325. // Note: Row-major storage order.
  326. std::array<float, 9> data;
  327. };
  328. inline Matrix33 operator*(Matrix33 lhs, const Matrix33& rhs)
  329. {
  330. return lhs *= rhs;
  331. }
  332. inline Vec3 operator*(const Matrix33& lhs, Vec3 rhs)
  333. {
  334. Matrix33::Multiply(lhs, rhs, &rhs);
  335. return rhs;
  336. }
  337. class Matrix44
  338. {
  339. public:
  340. static Matrix44 Identity();
  341. static Matrix44 FromMatrix33(const Matrix33& m33);
  342. static Matrix44 FromQuaternion(const Quaternion& q);
  343. static Matrix44 FromArray(const std::array<float, 16>& arr);
  344. static Matrix44 Translate(const Vec3& vec);
  345. static Matrix44 Shear(const float a, const float b = 0);
  346. static Matrix44 Perspective(float fov_y, float aspect_ratio, float z_near, float z_far);
  347. static void Multiply(const Matrix44& a, const Matrix44& b, Matrix44* result);
  348. static void Multiply(const Matrix44& a, const Vec4& vec, Vec4* result);
  349. // For when a vec4 isn't needed a multiplication function that takes a Vec3 and w:
  350. Vec3 Transform(const Vec3& point, float w) const;
  351. float Determinant() const;
  352. Matrix44& operator*=(const Matrix44& rhs)
  353. {
  354. Multiply(*this, rhs, this);
  355. return *this;
  356. }
  357. // Note: Row-major storage order.
  358. std::array<float, 16> data;
  359. };
  360. inline Matrix44 operator*(Matrix44 lhs, const Matrix44& rhs)
  361. {
  362. return lhs *= rhs;
  363. }
  364. inline Vec4 operator*(const Matrix44& lhs, Vec4 rhs)
  365. {
  366. Matrix44::Multiply(lhs, rhs, &rhs);
  367. return rhs;
  368. }
  369. } // namespace Common