matrix4x4.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. /*
  2. Copyright (c) 2013 Daniele Bartolini, Michele Rossi
  3. Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
  4. Permission is hereby granted, free of charge, to any person
  5. obtaining a copy of this software and associated documentation
  6. files (the "Software"), to deal in the Software without
  7. restriction, including without limitation the rights to use,
  8. copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. copies of the Software, and to permit persons to whom the
  10. Software is furnished to do so, subject to the following
  11. conditions:
  12. The above copyright notice and this permission notice shall be
  13. included in all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  16. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  19. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21. OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. #pragma once
  24. #include "math_types.h"
  25. #include "matrix3x3.h"
  26. #include "quaternion.h"
  27. #include "vector4.h"
  28. #include "types.h"
  29. namespace crown
  30. {
  31. /// Adds the matrix @a a to @a b and returns the result.
  32. Matrix4x4 operator+(Matrix4x4 a, const Matrix4x4& b);
  33. /// Subtracts the matrix @a b from @a a and returns the result.
  34. Matrix4x4 operator-(Matrix4x4 a, const Matrix4x4& b);
  35. /// Multiplies the matrix @a a by the scalar @a k and returns the result.
  36. Matrix4x4 operator*(Matrix4x4 a, float k);
  37. /// @copydoc operator*(Matrix4x4, float)
  38. Matrix4x4 operator*(float k, Matrix4x4 a);
  39. /// Divides the matrix @a a by the scalar @a k and returns the result.
  40. Matrix4x4 operator/(Matrix4x4 a, float k);
  41. /// Multiplies the matrix @a a by the vector @a v and returns the result.
  42. Vector3 operator*(const Matrix4x4& a, const Vector3& v);
  43. /// Multiplies the matrix @a by the vector @a v and returns the result.
  44. Vector4 operator*(const Matrix4x4& a, const Vector4& v);
  45. /// Multiplies the matrix @a a by @a b and returns the result. (i.e. transforms first by @a b then by @a a)
  46. Matrix4x4 operator*(Matrix4x4 a, const Matrix4x4& b);
  47. /// Functions to manipulate Matrix4x4.
  48. ///
  49. /// @ingroup Math
  50. namespace matrix4x4
  51. {
  52. const Matrix4x4 IDENTITY = Matrix4x4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
  53. /// Sets the rotation portion of the matrix @a m.
  54. void set_rotation(Matrix4x4& m, const Quaternion& rot);
  55. /// Sets the rotation portion of the matrix @a m.
  56. void set_rotation(Matrix4x4& m, const Matrix3x3& rot);
  57. /// Sets the matrix @a m to perspective. (Right-Handed coordinate systems)
  58. void set_perspective_rh(Matrix4x4& m, float fovy, float aspect, float near, float far);
  59. /// Sets the matrix @a m to orthographic. (Right-Handed coordinate systems)
  60. void set_orthographic_rh(Matrix4x4& m, float left, float right, float bottom, float top, float near, float far);
  61. /// Sets the matrix @a m to look. (Right-Handed coordinate systems)
  62. void set_look_rh(Matrix4x4& m, const Vector3& pos, const Vector3& target, const Vector3& up);
  63. /// Transposes the matrix @a m and returns the result.
  64. Matrix4x4& transpose(Matrix4x4& m);
  65. /// Returns the transposed of the matrix @a m.
  66. Matrix4x4 get_transposed(Matrix4x4 m);
  67. /// Returns the determinant of the matrix @a m.
  68. float determinant(const Matrix4x4& m);
  69. /// Inverts the matrix @a m and returns the result.
  70. Matrix4x4& invert(Matrix4x4& m);
  71. /// Returns the inverse of the matrix @a m.
  72. Matrix4x4 get_inverted(Matrix4x4 m);
  73. /// Sets the matrix @a m to identity.
  74. void set_identity(Matrix4x4& m);
  75. /// Returns the x asis of the matrix @a m.
  76. Vector3 x(const Matrix4x4& m);
  77. /// Returns the y axis of the matrix @a m.
  78. Vector3 y(const Matrix4x4& m);
  79. /// Returns the z axis of the matrix @a m.
  80. Vector3 z(const Matrix4x4& m);
  81. /// Sets the x axis of the matrix @a m.
  82. void set_x(Matrix4x4& m, const Vector3& x);
  83. /// Sets the y axis of the matrix @a m.
  84. void set_y(Matrix4x4& m, const Vector3& y);
  85. /// Sets the z axis of the matrix @a m.
  86. void set_z(Matrix4x4& m, const Vector3& z);
  87. /// Returns the translation portion of the matrix @a m.
  88. Vector3 translation(const Matrix4x4& m);
  89. /// Sets the translation portion of the matrix @a m.
  90. void set_translation(Matrix4x4& m, const Vector3& trans);
  91. /// Returns the pointer to the matrix's data
  92. float* to_float_ptr(Matrix4x4& m);
  93. /// Returns the pointer to the first elemento of the matrix @a m.
  94. const float* to_float_ptr(const Matrix4x4& m);
  95. /// Returns the rotation portion of the matrix @a m as a Matrix3x3.
  96. Matrix3x3 to_matrix3x3(const Matrix4x4& m);
  97. /// Returns the rotation portion of the matrix @a m as a Quaternion.
  98. Quaternion to_quaternion(const Matrix4x4& m);
  99. } // namespace matrix4x4
  100. inline Matrix4x4 operator+(Matrix4x4 a, const Matrix4x4& b)
  101. {
  102. a += b;
  103. return a;
  104. }
  105. inline Matrix4x4 operator-(Matrix4x4 a, const Matrix4x4& b)
  106. {
  107. a -= b;
  108. return a;
  109. }
  110. inline Matrix4x4 operator*(Matrix4x4 a, float k)
  111. {
  112. a *= k;
  113. return a;
  114. }
  115. inline Matrix4x4 operator*(float k, Matrix4x4 a)
  116. {
  117. a *= k;
  118. return a;
  119. }
  120. inline Matrix4x4 operator/(Matrix4x4 a, float k)
  121. {
  122. a /= k;
  123. return a;
  124. }
  125. inline Vector3 operator*(const Matrix4x4& a, const Vector3& v)
  126. {
  127. Vector3 tmp;
  128. tmp.x = a.x.x * v.x + a.y.x * v.y + a.z.x * v.z + a.t.x;
  129. tmp.y = a.x.y * v.x + a.y.y * v.y + a.z.y * v.z + a.t.y;
  130. tmp.z = a.x.z * v.x + a.y.z * v.y + a.z.z * v.z + a.t.z;
  131. return tmp;
  132. }
  133. inline Vector4 operator*(const Matrix4x4& a, const Vector4& v)
  134. {
  135. Vector4 tmp;
  136. tmp.x = a.x.x * v.x + a.y.x * v.y + a.z.x * v.z + a.t.x * v.w;
  137. tmp.y = a.x.y * v.x + a.y.y * v.y + a.z.y * v.z + a.t.y * v.w;
  138. tmp.z = a.x.z * v.x + a.y.z * v.y + a.z.z * v.z + a.t.z * v.w;
  139. tmp.w = a.x.w * v.x + a.y.w * v.y + a.z.w * v.z + a.t.w * v.w;
  140. return tmp;
  141. }
  142. inline Matrix4x4 operator*(Matrix4x4 a, const Matrix4x4& b)
  143. {
  144. a *= b;
  145. return a;
  146. }
  147. namespace matrix4x4
  148. {
  149. //-----------------------------------------------------------------------------
  150. inline void set_rotation(Matrix4x4& m, const Quaternion& rot)
  151. {
  152. set_rotation(m, quaternion::to_matrix3x3(rot));
  153. }
  154. //-----------------------------------------------------------------------------
  155. inline void set_rotation(Matrix4x4& m, const Matrix3x3& rot)
  156. {
  157. m.x.x = rot.x.x;
  158. m.x.y = rot.x.y;
  159. m.x.z = rot.x.z;
  160. m.y.x = rot.y.x;
  161. m.y.y = rot.y.y;
  162. m.y.y = rot.y.z;
  163. m.z.x = rot.z.x;
  164. m.z.y = rot.z.y;
  165. m.z.z = rot.z.z;
  166. }
  167. //-----------------------------------------------------------------------------
  168. inline void set_perspective_rh(Matrix4x4& m, float fovy, float aspect, float near, float far)
  169. {
  170. const float height = 1.0f / math::tan(fovy * ((float) math::PI / 180.0f) * 0.5f);
  171. const float width = height * 1.0f / aspect;
  172. const float aa = far / (far - near);
  173. const float bb = -near * aa;
  174. m.x = Vector4(width, 0, 0, 0);
  175. m.y = Vector4(0, height, 0, 0);
  176. m.z = Vector4(0, 0, aa, 1.0f);
  177. m.t = Vector4(0, 0, bb, 0);
  178. }
  179. //-----------------------------------------------------------------------------
  180. inline void set_orthographic_rh(Matrix4x4& m, float left, float right, float bottom, float top, float near, float far)
  181. {
  182. m.x = Vector4(2.0f / (right - left), 0, 0, 0);
  183. m.y = Vector4(0, 2.0f / (top - bottom), 0, 0);
  184. m.z = Vector4(0, 0, 1.0f / (far - near), 0);
  185. m.t = Vector4((left + right) / (left - right), (top + bottom) / (bottom - top), near / (near - far), 1.0f);
  186. }
  187. //-----------------------------------------------------------------------------
  188. inline Matrix4x4& transpose(Matrix4x4& m)
  189. {
  190. float tmp;
  191. tmp = m.x.y;
  192. m.x.y = m.y.x;
  193. m.y.x = tmp;
  194. tmp = m.x.z;
  195. m.x.z = m.z.x;
  196. m.z.x = tmp;
  197. tmp = m.x.w;
  198. m.x.w = m.t.x;
  199. m.t.x = tmp;
  200. tmp = m.y.z;
  201. m.y.z = m.z.y;
  202. m.z.y = tmp;
  203. tmp = m.y.w;
  204. m.y.w = m.t.y;
  205. m.t.y = tmp;
  206. tmp = m.z.w;
  207. m.z.w = m.t.z;
  208. m.t.z = tmp;
  209. return m;
  210. }
  211. //-----------------------------------------------------------------------------
  212. inline Matrix4x4 get_transposed(Matrix4x4 m)
  213. {
  214. transpose(m);
  215. return m;
  216. }
  217. //-----------------------------------------------------------------------------
  218. inline void set_look_rh(Matrix4x4& m, const Vector3& pos, const Vector3& target, const Vector3& up)
  219. {
  220. Vector3 zAxis = pos - target;
  221. vector3::normalize(zAxis);
  222. const Vector3 xAxis = vector3::cross(up, zAxis);
  223. const Vector3 yAxis = vector3::cross(zAxis, xAxis);
  224. m.x.x= xAxis.x;
  225. m.x.y= yAxis.x;
  226. m.x.z= zAxis.x;
  227. m.x.w= 0;
  228. m.y.x= xAxis.y;
  229. m.y.y= yAxis.y;
  230. m.y.z= zAxis.y;
  231. m.y.w= 0;
  232. m.z.x= xAxis.z;
  233. m.z.y= yAxis.z;
  234. m.z.z= zAxis.z;
  235. m.z.w= 0;
  236. m.t.x= -vector3::dot(pos, xAxis);
  237. m.t.y= -vector3::dot(pos, yAxis);
  238. m.t.z= -vector3::dot(pos, zAxis);
  239. m.t.w= 1;
  240. }
  241. //-----------------------------------------------------------------------------
  242. inline float determinant(const Matrix4x4& m)
  243. {
  244. const float m02m07_m06m03 = m.x.z * m.y.w - m.y.z * m.x.w;
  245. const float m02m11_m10m03 = m.x.z * m.z.w - m.z.z * m.x.w;
  246. const float m02m15_m14m03 = m.x.z * m.t.w - m.t.z * m.x.w;
  247. const float m06m11_m10m07 = m.y.z * m.z.w - m.z.z * m.y.w;
  248. const float m06m15_m14m07 = m.y.z * m.t.w - m.t.z * m.y.w;
  249. const float m10m15_m14m11 = m.z.z * m.t.w - m.t.z * m.z.w;
  250. return + m.x.x * (m.y.y * m10m15_m14m11 - m.z.y * m06m15_m14m07 + m.t.y * m06m11_m10m07)
  251. - m.y.x * (m.x.y * m10m15_m14m11 - m.z.y * m02m15_m14m03 + m.t.y * m02m11_m10m03)
  252. + m.z.x * (m.x.y * m06m15_m14m07 - m.y.y * m02m15_m14m03 + m.t.y * m02m07_m06m03)
  253. - m.t.x * (m.x.y * m06m11_m10m07 - m.y.y * m02m11_m10m03 + m.z.y * m02m07_m06m03);
  254. }
  255. //-----------------------------------------------------------------------------
  256. inline Matrix4x4& invert(Matrix4x4& m)
  257. {
  258. Matrix4x4 mat;
  259. const float m01m06_m05m02 = m.x.y * m.y.z - m.y.y * m.x.z;
  260. const float m01m07_m05m03 = m.x.y * m.y.w - m.y.y * m.x.w;
  261. const float m01m10_m09m02 = m.x.y * m.z.z - m.z.y * m.x.z;
  262. const float m01m11_m09m03 = m.x.y * m.z.w - m.z.y * m.x.w;
  263. const float m01m14_m13m02 = m.x.y * m.t.z - m.t.y * m.x.z;
  264. const float m01m15_m13m03 = m.x.y * m.t.w - m.t.y * m.x.w;
  265. const float m02m07_m06m03 = m.x.z * m.y.w - m.y.z * m.x.w;
  266. const float m02m11_m10m03 = m.x.z * m.z.w - m.z.z * m.x.w;
  267. const float m02m15_m14m03 = m.x.z * m.t.w - m.t.z * m.x.w;
  268. const float m05m10_m09m06 = m.y.y * m.z.z - m.z.y * m.y.z;
  269. const float m05m11_m09m07 = m.y.y * m.z.w - m.z.y * m.y.w;
  270. const float m05m14_m13m06 = m.y.y * m.t.z - m.t.y * m.y.z;
  271. const float m05m15_m13m07 = m.y.y * m.t.w - m.t.y * m.y.w;
  272. const float m06m11_m10m07 = m.y.z * m.z.w - m.z.z * m.y.w;
  273. const float m06m15_m14m07 = m.y.z * m.t.w - m.t.z * m.y.w;
  274. const float m09m14_m13m10 = m.z.y * m.t.z - m.t.y * m.z.z;
  275. const float m09m15_m13m11 = m.z.y * m.t.w - m.t.y * m.z.w;
  276. const float m10m15_m14m11 = m.z.z * m.t.w - m.t.z * m.z.w;
  277. mat.x.x = (+ m.y.y * m10m15_m14m11 - m.z.y * m06m15_m14m07 + m.t.y * m06m11_m10m07);
  278. mat.x.y = (+ m.x.y * m10m15_m14m11 - m.z.y * m02m15_m14m03 + m.t.y * m02m11_m10m03);
  279. mat.x.z = (+ m.x.y * m06m15_m14m07 - m.y.y * m02m15_m14m03 + m.t.y * m02m07_m06m03);
  280. mat.x.w = (+ m.x.y * m06m11_m10m07 - m.y.y * m02m11_m10m03 + m.z.y * m02m07_m06m03);
  281. const float inv_det = 1.0f / (m.x.x * mat.x.x - m.y.x * mat.x.y + m.z.x * mat.x.z - m.t.x * mat.x.w);
  282. mat.y.x = (+ m.y.x * m10m15_m14m11 - m.z.x * m06m15_m14m07 + m.t.x * m06m11_m10m07);
  283. mat.y.y = (+ m.x.x * m10m15_m14m11 - m.z.x * m02m15_m14m03 + m.t.x * m02m11_m10m03);
  284. mat.y.z = (+ m.x.x * m06m15_m14m07 - m.y.x * m02m15_m14m03 + m.t.x * m02m07_m06m03);
  285. mat.y.w = (+ m.x.x * m06m11_m10m07 - m.y.x * m02m11_m10m03 + m.z.x * m02m07_m06m03);
  286. mat.z.x = (+ m.y.x * m09m15_m13m11 - m.z.x * m05m15_m13m07 + m.t.x * m05m11_m09m07);
  287. mat.z.y = (+ m.x.x * m09m15_m13m11 - m.z.x * m01m15_m13m03 + m.t.x * m01m11_m09m03);
  288. mat.z.z = (+ m.x.x * m05m15_m13m07 - m.y.x * m01m15_m13m03 + m.t.x * m01m07_m05m03);
  289. mat.z.w = (+ m.x.x * m05m11_m09m07 - m.y.x * m01m11_m09m03 + m.z.x * m01m07_m05m03);
  290. mat.t.x = (+ m.y.x * m09m14_m13m10 - m.z.x * m05m14_m13m06 + m.t.x * m05m10_m09m06);
  291. mat.t.y = (+ m.x.x * m09m14_m13m10 - m.z.x * m01m14_m13m02 + m.t.x * m01m10_m09m02);
  292. mat.t.z = (+ m.x.x * m05m14_m13m06 - m.y.x * m01m14_m13m02 + m.t.x * m01m06_m05m02);
  293. mat.t.w = (+ m.x.x * m05m10_m09m06 - m.y.x * m01m10_m09m02 + m.z.x * m01m06_m05m02);
  294. m.x.x = + mat.x.x * inv_det;
  295. m.x.y = - mat.x.y * inv_det;
  296. m.x.z = + mat.x.z * inv_det;
  297. m.x.w = - mat.x.w * inv_det;
  298. m.y.x = - mat.y.x * inv_det;
  299. m.y.y = + mat.y.y * inv_det;
  300. m.y.z = - mat.y.z * inv_det;
  301. m.y.w = + mat.y.w * inv_det;
  302. m.z.x = + mat.z.x * inv_det;
  303. m.z.y = - mat.z.y * inv_det;
  304. m.z.z = + mat.z.z * inv_det;
  305. m.z.w = - mat.z.w * inv_det;
  306. m.t.x = - mat.t.x * inv_det;
  307. m.t.y = + mat.t.y * inv_det;
  308. m.t.z = - mat.t.z * inv_det;
  309. m.t.w = + mat.t.w * inv_det;
  310. return m;
  311. }
  312. //-----------------------------------------------------------------------------
  313. inline Matrix4x4 get_inverted(Matrix4x4 m)
  314. {
  315. invert(m);
  316. return m;
  317. }
  318. //-----------------------------------------------------------------------------
  319. inline void set_identity(Matrix4x4& m)
  320. {
  321. m.x = Vector4(1, 0, 0, 0);
  322. m.y = Vector4(0, 1, 0, 0);
  323. m.z = Vector4(0, 0, 1, 0);
  324. m.t = Vector4(0, 0, 0, 1);
  325. }
  326. //-----------------------------------------------------------------------------
  327. inline Vector3 x(const Matrix4x4& m)
  328. {
  329. return Vector3(m.x.x, m.x.y, m.x.z);
  330. }
  331. //-----------------------------------------------------------------------------
  332. inline Vector3 y(const Matrix4x4& m)
  333. {
  334. return Vector3(m.y.x, m.y.y, m.y.z);
  335. }
  336. //-----------------------------------------------------------------------------
  337. inline Vector3 z(const Matrix4x4& m)
  338. {
  339. return Vector3(m.z.x, m.z.y, m.z.z);
  340. }
  341. //-----------------------------------------------------------------------------
  342. inline void set_x(Matrix4x4& m, const Vector3& x)
  343. {
  344. m.x.x = x.x;
  345. m.x.y = x.y;
  346. m.x.z = x.z;
  347. }
  348. //-----------------------------------------------------------------------------
  349. inline void set_y(Matrix4x4& m, const Vector3& y)
  350. {
  351. m.y.x = y.x;
  352. m.y.y = y.y;
  353. m.y.z = y.z;
  354. }
  355. //-----------------------------------------------------------------------------
  356. inline void set_z(Matrix4x4& m, const Vector3& z)
  357. {
  358. m.z.x = z.x;
  359. m.z.y = z.y;
  360. m.z.z = z.z;
  361. }
  362. //-----------------------------------------------------------------------------
  363. inline Vector3 translation(const Matrix4x4& m)
  364. {
  365. return Vector3(m.t.x, m.t.y, m.t.z);
  366. }
  367. //-----------------------------------------------------------------------------
  368. inline void set_translation(Matrix4x4& m, const Vector3& trans)
  369. {
  370. m.t.x = trans.x;
  371. m.t.y = trans.y;
  372. m.t.z = trans.z;
  373. }
  374. //-----------------------------------------------------------------------------
  375. inline float* to_float_ptr(Matrix4x4& m)
  376. {
  377. return vector4::to_float_ptr(m.x);
  378. }
  379. //-----------------------------------------------------------------------------
  380. inline const float* to_float_ptr(const Matrix4x4& m)
  381. {
  382. return vector4::to_float_ptr(m.x);
  383. }
  384. //-----------------------------------------------------------------------------
  385. inline Matrix3x3 to_matrix3x3(const Matrix4x4& m)
  386. {
  387. return Matrix3x3(x(m), y(m), z(m));
  388. }
  389. //-----------------------------------------------------------------------------
  390. inline Quaternion to_quaternion(const Matrix4x4& m)
  391. {
  392. return matrix3x3::to_quaternion(to_matrix3x3(m));
  393. }
  394. } // namespace matrix4x4
  395. //-----------------------------------------------------------------------------
  396. inline Matrix4x4::Matrix4x4()
  397. {
  398. // Do not initialize
  399. }
  400. inline Matrix4x4::Matrix4x4(const Vector3& x, const Vector3& y, const Vector3& z, const Vector3& t)
  401. : x(x, 0), y(y, 0), z(z, 0), t(t, 1)
  402. {
  403. }
  404. //-----------------------------------------------------------------------------
  405. inline Matrix4x4::Matrix4x4(float r1c1, float r2c1, float r3c1, float r4c1,
  406. float r1c2, float r2c2, float r3c2, float r4c2,
  407. float r1c3, float r2c3, float r3c3, float r4c3,
  408. float r1c4, float r2c4, float r3c4, float r4c4)
  409. : x(r1c1, r2c1, r3c1, r4c1)
  410. , y(r1c2, r2c2, r3c2, r4c2)
  411. , z(r1c3, r2c3, r3c3, r4c3)
  412. , t(r1c4, r2c4, r3c4, r4c4)
  413. {
  414. }
  415. //-----------------------------------------------------------------------------
  416. inline Matrix4x4::Matrix4x4(const Quaternion& r, const Vector3& p)
  417. : x(1.0f - 2.0f * r.y * r.y - 2.0f * r.z * r.z, 2.0f * r.x * r.y + 2.0f * r.w * r.z, 2.0f * r.x * r.z - 2.0f * r.w * r.y, 0)
  418. , y(2.0f * r.x * r.y - 2.0f * r.w * r.z, 1.0f - 2.0f * r.x * r.x - 2.0f * r.z * r.z, 2.0f * r.y * r.z + 2.0f * r.w * r.x, 0)
  419. , z(2.0f * r.x * r.z + 2.0f * r.w * r.y, 2.0f * r.y * r.z - 2.0f * r.w * r.x, 1.0f - 2.0f * r.x * r.x - 2.0f * r.y * r.y, 0)
  420. , t(p, 1)
  421. {
  422. }
  423. //-----------------------------------------------------------------------------
  424. inline Matrix4x4::Matrix4x4(const Matrix3x3& m)
  425. : x(m.x, 0)
  426. , y(m.y, 0)
  427. , z(m.z, 0)
  428. , t(0, 0, 0, 1)
  429. {
  430. }
  431. //-----------------------------------------------------------------------------
  432. inline Matrix4x4::Matrix4x4(const float v[16])
  433. : x(v[0], v[1], v[2], v[3])
  434. , y(v[4], v[5], v[6], v[7])
  435. , z(v[8], v[9], v[10], v[11])
  436. , t(v[12], v[13], v[14], v[15])
  437. {
  438. }
  439. //-----------------------------------------------------------------------------
  440. inline float& Matrix4x4::operator[](uint32_t i)
  441. {
  442. CE_ASSERT(i < 16, "Index out of bounds");
  443. return vector4::to_float_ptr(x)[i];
  444. }
  445. //-----------------------------------------------------------------------------
  446. inline const float& Matrix4x4::operator[](uint32_t i) const
  447. {
  448. CE_ASSERT(i < 16, "Index out of bounds");
  449. return vector4::to_float_ptr(x)[i];
  450. }
  451. //-----------------------------------------------------------------------------
  452. inline Matrix4x4& Matrix4x4::operator+=(const Matrix4x4& a)
  453. {
  454. x += a.x;
  455. y += a.y;
  456. z += a.z;
  457. t += a.t;
  458. return *this;
  459. }
  460. //-----------------------------------------------------------------------------
  461. inline Matrix4x4& Matrix4x4::operator-=(const Matrix4x4& a)
  462. {
  463. x -= a.x;
  464. y -= a.y;
  465. z -= a.z;
  466. t -= a.t;
  467. return *this;
  468. }
  469. //-----------------------------------------------------------------------------
  470. inline Matrix4x4& Matrix4x4::operator*=(float k)
  471. {
  472. x *= k;
  473. y *= k;
  474. z *= k;
  475. t *= k;
  476. return *this;
  477. }
  478. //-----------------------------------------------------------------------------
  479. inline Matrix4x4& Matrix4x4::operator/=(float k)
  480. {
  481. const float inv_k = 1.0f / k;
  482. x *= inv_k;
  483. y *= inv_k;
  484. z *= inv_k;
  485. t *= inv_k;
  486. return *this;
  487. }
  488. //-----------------------------------------------------------------------------
  489. inline Matrix4x4& Matrix4x4::operator*=(const Matrix4x4& a)
  490. {
  491. Matrix4x4 tmp;
  492. tmp.x.x = x.x * a.x.x + y.x * a.x.y + z.x * a.x.z + t.x * a.x.w;
  493. tmp.x.y = x.y * a.x.x + y.y * a.x.y + z.y * a.x.z + t.y * a.x.w;
  494. tmp.x.z = x.z * a.x.x + y.z * a.x.y + z.z * a.x.z + t.z * a.x.w;
  495. tmp.x.w = x.w * a.x.x + y.w * a.x.y + z.w * a.x.z + t.w * a.x.w;
  496. tmp.y.x = x.x * a.y.x + y.x * a.y.y + z.x * a.y.z + t.x * a.y.w;
  497. tmp.y.y = x.y * a.y.x + y.y * a.y.y + z.y * a.y.z + t.y * a.y.w;
  498. tmp.y.z = x.z * a.y.x + y.z * a.y.y + z.z * a.y.z + t.z * a.y.w;
  499. tmp.y.w = x.w * a.y.x + y.w * a.y.y + z.w * a.y.z + t.w * a.y.w;
  500. tmp.z.x = x.x * a.z.x + y.x * a.z.y + z.x * a.z.z + t.x * a.z.w;
  501. tmp.z.y = x.y * a.z.x + y.y * a.z.y + z.y * a.z.z + t.y * a.z.w;
  502. tmp.z.z = x.z * a.z.x + y.z * a.z.y + z.z * a.z.z + t.z * a.z.w;
  503. tmp.z.w = x.w * a.z.x + y.w * a.z.y + z.w * a.z.z + t.w * a.z.w;
  504. tmp.t.x = x.x * a.t.x + y.x * a.t.y + z.x * a.t.z + t.x * a.t.w;
  505. tmp.t.y = x.y * a.t.x + y.y * a.t.y + z.y * a.t.z + t.y * a.t.w;
  506. tmp.t.z = x.z * a.t.x + y.z * a.t.y + z.z * a.t.z + t.z * a.t.w;
  507. tmp.t.w = x.w * a.t.x + y.w * a.t.y + z.w * a.t.z + t.w * a.t.w;
  508. *this = tmp;
  509. return *this;
  510. }
  511. } // namespace crown