matrix4x4.inl - Engine C API Reference

matrix4x4.inl
  1. #include "vector3.h"
  2. namespace stingray_plugin_foundation {
  3. enum Elements {
  4. xx, xy, xz, xw,
  5. yx, yy, yz, yw,
  6. zx, zy, zz, zw,
  7. tx, ty, tz, tw
  8. };
  9. // Operators
  10. __forceinline Matrix4x4 operator *(const Matrix4x4& lhs, const Matrix4x4 &rhs) {
  11. Matrix4x4 m = {{
  12. lhs.v[xx]*rhs.v[xx] + lhs.v[xy]*rhs.v[yx] + lhs.v[xz]*rhs.v[zx] + lhs.v[xw]*rhs.v[tx],
  13. lhs.v[xx]*rhs.v[xy] + lhs.v[xy]*rhs.v[yy] + lhs.v[xz]*rhs.v[zy] + lhs.v[xw]*rhs.v[ty],
  14. lhs.v[xx]*rhs.v[xz] + lhs.v[xy]*rhs.v[yz] + lhs.v[xz]*rhs.v[zz] + lhs.v[xw]*rhs.v[tz],
  15. lhs.v[xx]*rhs.v[xw] + lhs.v[xy]*rhs.v[yw] + lhs.v[xz]*rhs.v[zw] + lhs.v[xw]*rhs.v[tw],
  16. lhs.v[yx]*rhs.v[xx] + lhs.v[yy]*rhs.v[yx] + lhs.v[yz]*rhs.v[zx] + lhs.v[yw]*rhs.v[tx],
  17. lhs.v[yx]*rhs.v[xy] + lhs.v[yy]*rhs.v[yy] + lhs.v[yz]*rhs.v[zy] + lhs.v[yw]*rhs.v[ty],
  18. lhs.v[yx]*rhs.v[xz] + lhs.v[yy]*rhs.v[yz] + lhs.v[yz]*rhs.v[zz] + lhs.v[yw]*rhs.v[tz],
  19. lhs.v[yx]*rhs.v[xw] + lhs.v[yy]*rhs.v[yw] + lhs.v[yz]*rhs.v[zw] + lhs.v[yw]*rhs.v[tw],
  20. lhs.v[zx]*rhs.v[xx] + lhs.v[zy]*rhs.v[yx] + lhs.v[zz]*rhs.v[zx] + lhs.v[zw]*rhs.v[tx],
  21. lhs.v[zx]*rhs.v[xy] + lhs.v[zy]*rhs.v[yy] + lhs.v[zz]*rhs.v[zy] + lhs.v[zw]*rhs.v[ty],
  22. lhs.v[zx]*rhs.v[xz] + lhs.v[zy]*rhs.v[yz] + lhs.v[zz]*rhs.v[zz] + lhs.v[zw]*rhs.v[tz],
  23. lhs.v[zx]*rhs.v[xw] + lhs.v[zy]*rhs.v[yw] + lhs.v[zz]*rhs.v[zw] + lhs.v[zw]*rhs.v[tw],
  24. lhs.v[tx]*rhs.v[xx] + lhs.v[ty]*rhs.v[yx] + lhs.v[tz]*rhs.v[zx] + lhs.v[tw]*rhs.v[tx],
  25. lhs.v[tx]*rhs.v[xy] + lhs.v[ty]*rhs.v[yy] + lhs.v[tz]*rhs.v[zy] + lhs.v[tw]*rhs.v[ty],
  26. lhs.v[tx]*rhs.v[xz] + lhs.v[ty]*rhs.v[yz] + lhs.v[tz]*rhs.v[zz] + lhs.v[tw]*rhs.v[tz],
  27. lhs.v[tx]*rhs.v[xw] + lhs.v[ty]*rhs.v[yw] + lhs.v[tz]*rhs.v[zw] + lhs.v[tw]*rhs.v[tw]
  28. }};
  29. return m;
  30. }
  31. __forceinline Matrix4x4 operator +(const Matrix4x4& lhs, const Matrix4x4 &rhs) {
  32. Matrix4x4 m = {{
  33. lhs.v[xx] + rhs.v[xx], lhs.v[xy] + rhs.v[xy], lhs.v[xz] + rhs.v[xz], lhs.v[xw] + rhs.v[xw],
  34. lhs.v[yx] + rhs.v[yx], lhs.v[yy] + rhs.v[yy], lhs.v[yz] + rhs.v[yz], lhs.v[yw] + rhs.v[yw],
  35. lhs.v[zx] + rhs.v[zx], lhs.v[zy] + rhs.v[zy], lhs.v[zz] + rhs.v[zz], lhs.v[zw] + rhs.v[zw],
  36. lhs.v[tx] + rhs.v[tx], lhs.v[ty] + rhs.v[ty], lhs.v[tz] + rhs.v[tz], lhs.v[tw] + rhs.v[tw]
  37. }};
  38. return m;
  39. }
  40. __forceinline Matrix4x4 operator -(const Matrix4x4& lhs, const Matrix4x4 &rhs) {
  41. Matrix4x4 m = {{
  42. lhs.v[xx] - rhs.v[xx], lhs.v[xy] - rhs.v[xy], lhs.v[xz] - rhs.v[xz], lhs.v[xw] - rhs.v[xw],
  43. lhs.v[yx] - rhs.v[yx], lhs.v[yy] - rhs.v[yy], lhs.v[yz] - rhs.v[yz], lhs.v[yw] - rhs.v[yw],
  44. lhs.v[zx] - rhs.v[zx], lhs.v[zy] - rhs.v[zy], lhs.v[zz] - rhs.v[zz], lhs.v[zw] - rhs.v[zw],
  45. lhs.v[tx] - rhs.v[tx], lhs.v[ty] - rhs.v[ty], lhs.v[tz] - rhs.v[tz], lhs.v[tw] - rhs.v[tw]
  46. }};
  47. return m;
  48. }
  49. __forceinline void operator *=(Matrix4x4& lhs, const Matrix4x4 &rhs) {
  50. Matrix4x4 tmp = lhs * rhs;
  51. lhs = tmp;
  52. }
  53. __forceinline void operator +=(Matrix4x4& lhs, const Matrix4x4 &rhs) {
  54. lhs.v[xx] += rhs.v[xx]; lhs.v[xy] += rhs.v[xy]; lhs.v[xz] += rhs.v[xz]; lhs.v[xw] += rhs.v[xw];
  55. lhs.v[yx] += rhs.v[yx]; lhs.v[yy] += rhs.v[yy]; lhs.v[yz] += rhs.v[yz]; lhs.v[yw] += rhs.v[yw];
  56. lhs.v[zx] += rhs.v[zx]; lhs.v[zy] += rhs.v[zy]; lhs.v[zz] += rhs.v[zz]; lhs.v[zw] += rhs.v[zw];
  57. lhs.v[tx] += rhs.v[tx]; lhs.v[ty] += rhs.v[ty]; lhs.v[tz] += rhs.v[tz]; lhs.v[tw] += rhs.v[tw];
  58. }
  59. __forceinline void operator -=(Matrix4x4& lhs, const Matrix4x4 &rhs) {
  60. lhs.v[xx] -= rhs.v[xx]; lhs.v[xy] -= rhs.v[xy]; lhs.v[xz] -= rhs.v[xz]; lhs.v[xw] -= rhs.v[xw];
  61. lhs.v[yx] -= rhs.v[yx]; lhs.v[yy] -= rhs.v[yy]; lhs.v[yz] -= rhs.v[yz]; lhs.v[yw] -= rhs.v[yw];
  62. lhs.v[zx] -= rhs.v[zx]; lhs.v[zy] -= rhs.v[zy]; lhs.v[zz] -= rhs.v[zz]; lhs.v[zw] -= rhs.v[zw];
  63. lhs.v[tx] -= rhs.v[tx]; lhs.v[ty] -= rhs.v[ty]; lhs.v[tz] -= rhs.v[tz]; lhs.v[tw] -= rhs.v[tw];
  64. }
  65. __forceinline Matrix4x4 operator *(const Matrix4x4& lhs, float rhs) {
  66. Matrix4x4 m = {{
  67. lhs.v[xx] * rhs, lhs.v[xy] * rhs, lhs.v[xz] * rhs, lhs.v[xw] * rhs,
  68. lhs.v[yx] * rhs, lhs.v[yy] * rhs, lhs.v[yz] * rhs, lhs.v[yw] * rhs,
  69. lhs.v[zx] * rhs, lhs.v[zy] * rhs, lhs.v[zz] * rhs, lhs.v[zw] * rhs,
  70. lhs.v[tx] * rhs, lhs.v[ty] * rhs, lhs.v[tz] * rhs, lhs.v[tw] * rhs
  71. }};
  72. return m;
  73. }
  74. __forceinline Matrix4x4 operator *(float lhs, const Matrix4x4 &rhs) {
  75. return rhs * lhs;
  76. }
  77. __forceinline bool operator==(const Matrix4x4 &lhs, const Matrix4x4 &rhs)
  78. {
  79. for (int i=0; i<16; ++i)
  80. if (lhs.v[i] != rhs.v[i])
  81. return false;
  82. return true;
  83. }
  84. __forceinline bool operator!=(const Matrix4x4 &lhs, const Matrix4x4 &rhs)
  85. {
  86. return !(lhs == rhs);
  87. }
  88. // Methods
  89. __forceinline void set_to_zero_matrix(Matrix4x4 &m)
  90. {
  91. m.v[xx]=m.v[xy]=m.v[xz]=m.v[xw]=0.f;
  92. m.v[yx]=m.v[yy]=m.v[yz]=m.v[yw]=0.f;
  93. m.v[zx]=m.v[zy]=m.v[zz]=m.v[zw]=0.f;
  94. m.v[tx]=m.v[ty]=m.v[tz]=m.v[tw]=0.f;
  95. }
  96. __forceinline void set_to_identity_matrix(Matrix4x4 &m)
  97. {
  98. m = matrix4x4_identity();
  99. }
  100. __forceinline const Matrix4x4 &matrix4x4_zero()
  101. {
  102. static Matrix4x4 zero = {{
  103. 0.f, 0.f, 0.f, 0.f,
  104. 0.f, 0.f, 0.f, 0.f,
  105. 0.f, 0.f, 0.f, 0.f,
  106. 0.f, 0.f, 0.f, 0.f
  107. }};
  108. return zero;
  109. }
  110. __forceinline const Matrix4x4 &matrix4x4_identity()
  111. {
  112. static Matrix4x4 id = {{
  113. 1.f, 0.f, 0.f, 0.f,
  114. 0.f, 1.f, 0.f, 0.f,
  115. 0.f, 0.f, 1.f, 0.f,
  116. 0.f, 0.f, 0.f, 1.f
  117. }};
  118. return id;
  119. }
  120. __forceinline void set_to_scale_matrix(Matrix4x4 &m, const Vector3 &s)
  121. {
  122. set_to_identity_matrix(m);
  123. m.v[xx] = s.x;
  124. m.v[yy] = s.y;
  125. m.v[zz] = s.z;
  126. }
  127. __forceinline void set_to_translation_matrix(Matrix4x4 &m, const Vector3 &t)
  128. {
  129. set_to_identity_matrix(m);
  130. m.v[tx] = t.x;
  131. m.v[ty] = t.y;
  132. m.v[tz] = t.z;
  133. }
  134. __forceinline void normalize(Matrix4x4 &m) {
  135. Vector3 &x = x_axis(m);
  136. Vector3 &y = y_axis(m);
  137. Vector3 &z = z_axis(m);
  138. x = normalize(x);
  139. y -= x*dot(x, y);
  140. y = normalize(y);
  141. z = cross(x,y);
  142. }
  143. __forceinline float determinant(const Matrix4x4 &m) {
  144. // return m.v[xx]*m.v[yy]*m.v[zz] + m.v[xy]*m.v[yz]*m.v[zx] + m.v[xz]*m.v[yx]*m.v[zy] -
  145. // m.v[xz]*m.v[yy]*m.v[zx] - m.v[xy]*m.v[yx]*m.v[zz] - m.v[xx]*m.v[yz]*m.v[zy];
  146. return
  147. m.v[3] * m.v[6] * m.v[ 9] * m.v[12] - m.v[2] * m.v[7] * m.v[ 9] * m.v[12] - m.v[3] * m.v[5] * m.v[10] * m.v[12] + m.v[1] * m.v[7] * m.v[10] * m.v[12] +
  148. m.v[2] * m.v[5] * m.v[11] * m.v[12] - m.v[1] * m.v[6] * m.v[11] * m.v[12] - m.v[3] * m.v[6] * m.v[ 8] * m.v[13] + m.v[2] * m.v[7] * m.v[ 8] * m.v[13] +
  149. m.v[3] * m.v[4] * m.v[10] * m.v[13] - m.v[0] * m.v[7] * m.v[10] * m.v[13] - m.v[2] * m.v[4] * m.v[11] * m.v[13] + m.v[0] * m.v[6] * m.v[11] * m.v[13] +
  150. m.v[3] * m.v[5] * m.v[ 8] * m.v[14] - m.v[1] * m.v[7] * m.v[ 8] * m.v[14] - m.v[3] * m.v[4] * m.v[ 9] * m.v[14] + m.v[0] * m.v[7] * m.v[ 9] * m.v[14] +
  151. m.v[1] * m.v[4] * m.v[11] * m.v[14] - m.v[0] * m.v[5] * m.v[11] * m.v[14] - m.v[2] * m.v[5] * m.v[ 8] * m.v[15] + m.v[1] * m.v[6] * m.v[ 8] * m.v[15] +
  152. m.v[2] * m.v[4] * m.v[ 9] * m.v[15] - m.v[0] * m.v[6] * m.v[ 9] * m.v[15] - m.v[1] * m.v[4] * m.v[10] * m.v[15] + m.v[0] * m.v[5] * m.v[10] * m.v[15];
  153. }
  154. __forceinline bool has_mirroring(const Matrix4x4 &m) {
  155. return (determinant(m) < 0.0f);
  156. }
  157. __forceinline float & element(Matrix4x4 &m, int i, int j)
  158. {
  159. return m.v[i*4 + j];
  160. }
  161. __forceinline const float & element(const Matrix4x4 &m, int i, int j)
  162. {
  163. return m.v[i*4 + j];
  164. }
  165. __forceinline void transpose(Matrix4x4 &m)
  166. {
  167. #define SWAP(a,b) {float temp = a; a = b; b = temp;}
  168. SWAP(m.v[1], m.v[4]);
  169. SWAP(m.v[2], m.v[8]);
  170. SWAP(m.v[3], m.v[12]);
  171. SWAP(m.v[6], m.v[9]);
  172. SWAP(m.v[7], m.v[13]);
  173. SWAP(m.v[11], m.v[14]);
  174. #undef SWAP
  175. }
  176. // Vector3 helper access
  177. __forceinline Vector3 &translation(Matrix4x4 &m) {
  178. return *reinterpret_cast<Vector3 *>(&m.v[tx]);
  179. }
  180. __forceinline Vector3 &x_axis(Matrix4x4 &m) {
  181. return *reinterpret_cast<Vector3 *>(&m.v[xx]);
  182. }
  183. __forceinline Vector3 &y_axis(Matrix4x4 &m) {
  184. return *reinterpret_cast<Vector3 *>(&m.v[yx]);
  185. }
  186. __forceinline Vector3 &z_axis(Matrix4x4 &m) {
  187. return *reinterpret_cast<Vector3 *>(&m.v[zx]);
  188. }
  189. __forceinline const Vector3 &translation(const Matrix4x4 &m) {
  190. return *reinterpret_cast<const Vector3 *>(&m.v[tx]);
  191. }
  192. __forceinline const Vector3 &x_axis(const Matrix4x4 &m){
  193. return *reinterpret_cast<const Vector3 *>(&m.v[xx]);
  194. }
  195. __forceinline const Vector3 &y_axis(const Matrix4x4 &m){
  196. return *reinterpret_cast<const Vector3 *>(&m.v[yx]);
  197. }
  198. __forceinline const Vector3 &z_axis(const Matrix4x4 &m){
  199. return *reinterpret_cast<const Vector3 *>(&m.v[zx]);
  200. }
  201. __forceinline Vector3 &forward_axis(Matrix4x4 &m) {
  202. return y_axis(m);
  203. }
  204. __forceinline Vector3 &up_axis(Matrix4x4 &m) {
  205. return z_axis(m);
  206. }
  207. __forceinline Vector3 &right_axis(Matrix4x4 &m) {
  208. return x_axis(m);
  209. }
  210. __forceinline const Vector3 &forward_axis(const Matrix4x4 &m){
  211. return y_axis(m);
  212. }
  213. __forceinline const Vector3 &up_axis(const Matrix4x4 &m){
  214. return z_axis(m);
  215. }
  216. __forceinline const Vector3 &right_axis(const Matrix4x4 &m){
  217. return x_axis(m);
  218. }
  219. __forceinline Vector3 &axis(Matrix4x4 &m, int i)
  220. {
  221. return *reinterpret_cast<Vector3 *>(&m.v[xx] + i*4);
  222. }
  223. __forceinline const Vector3 &axis(const Matrix4x4 &m, int i)
  224. {
  225. return *reinterpret_cast<const Vector3 *>(&m.v[xx] + i*4);
  226. }
  227. __forceinline Vector4 &row(Matrix4x4 &m, int i)
  228. {
  229. return *reinterpret_cast<Vector4 *>(&m.v[xx] + i*4);
  230. }
  231. __forceinline const Vector4 &row(const Matrix4x4 &m, int i)
  232. {
  233. return *reinterpret_cast<const Vector4 *>(&m.v[xx] + i*4);
  234. }
  235. __forceinline void set_translation(Matrix4x4 &m, const Vector3 &t)
  236. {
  237. translation(m) = t;
  238. }
  239. __forceinline Vector3 transform(const Matrix4x4 &m, const Vector3 &p)
  240. {
  241. Vector3 pt;
  242. pt.x = m.v[xx] * p.x + m.v[yx] * p.y + m.v[zx] * p.z + m.v[tx];
  243. pt.y = m.v[xy] * p.x + m.v[yy] * p.y + m.v[zy] * p.z + m.v[ty];
  244. pt.z = m.v[xz] * p.x + m.v[yz] * p.y + m.v[zz] * p.z + m.v[tz];
  245. return pt;
  246. }
  247. __forceinline Vector3 transform_without_translation(const Matrix4x4 &m, const Vector3 &p)
  248. {
  249. Vector3 pt;
  250. pt.x = m.v[xx] * p.x + m.v[yx] * p.y + m.v[zx] * p.z;
  251. pt.y = m.v[xy] * p.x + m.v[yy] * p.y + m.v[zy] * p.z;
  252. pt.z = m.v[xz] * p.x + m.v[yz] * p.y + m.v[zz] * p.z;
  253. return pt;
  254. }
  255. __forceinline Vector4 transform(const Matrix4x4 &m, const Vector4 &p)
  256. {
  257. Vector4 pt;
  258. pt.x = m.v[xx] * p.x + m.v[yx] * p.y + m.v[zx] * p.z + p.w * m.v[tx];
  259. pt.y = m.v[xy] * p.x + m.v[yy] * p.y + m.v[zy] * p.z + p.w * m.v[ty];
  260. pt.z = m.v[xz] * p.x + m.v[yz] * p.y + m.v[zz] * p.z + p.w * m.v[tz];
  261. pt.w = m.v[xw] * p.x + m.v[yw] * p.y + m.v[zw] * p.z + p.w * m.v[tw];
  262. return pt;
  263. }
  264. __forceinline Matrix4x4 rotation(const Matrix4x4 &m)
  265. {
  266. Matrix4x4 out = m;
  267. out.v[xw] = out.v[yw] = out.v[zw] = out.v[tx] = out.v[ty] = out.v[tz] = 0;
  268. out.v[tw] = 1;
  269. return out;
  270. }
  271. __forceinline void set_rotation(Matrix4x4 &m, const Matrix4x4 &rot)
  272. {
  273. x_axis(m) = x_axis(rot);
  274. y_axis(m) = y_axis(rot);
  275. z_axis(m) = z_axis(rot);
  276. }
  277. __forceinline Vector3 scale(const Matrix4x4 &m)
  278. {
  279. Vector3 s;
  280. s.x = length(x_axis(m));
  281. s.y = length(y_axis(m));
  282. s.z = length(z_axis(m));
  283. return s;
  284. }
  285. __forceinline void set_scale(Matrix4x4 &m, const Vector3 &s)
  286. {
  287. Vector3 p = scale(m);
  288. x_axis(m) *= s.x / p.x;
  289. y_axis(m) *= s.y / p.y;
  290. z_axis(m) *= s.z / p.z;
  291. }
  292. inline Matrix4x4 inverse(const Matrix4x4 &m)
  293. {
  294. Matrix4x4 inv = matrix4x4_identity();
  295. Matrix4x4 temp = m;
  296. int i, j, k, swap;
  297. float *v = (float *)&temp.v[xx];
  298. float *v2 = (float *)&inv.v[xx];
  299. for(i=0; i!=4; ++i) {
  300. swap=i;
  301. for(j=i+1; j!=4; ++j) {
  302. if(fabs(v[(j<<2)+i]) > fabs(v[(swap<<2)+i]))
  303. swap = j;
  304. }
  305. if (swap != i) {
  306. for(k=0; k!=4; ++k) {
  307. const float t = v[(i<<2)+k];
  308. v[(i<<2)+k] = v[(swap<<2)+k];
  309. v[(swap<<2)+k] = t;
  310. const float t2 = v2[(i<<2)+k];
  311. v2[(i<<2)+k] = v2[(swap<<2)+k];
  312. v2[(swap<<2)+k] = t2;
  313. }
  314. }
  315. if (v[(i<<2)+i] == 0)
  316. return inv;
  317. const float t = v[(i<<2)+i];
  318. for (k=0; k!=4; ++k) {
  319. v[(i<<2)+k] /= t;
  320. v2[(i<<2)+k] /= t;
  321. }
  322. for (j=0; j!=4; ++j) {
  323. if(j!=i) {
  324. const float t = v[(j<<2)+i];
  325. for(k=0; k<4; k++) {
  326. v[(j<<2)+k] -= v[(i<<2)+k]*t;
  327. v2[(j<<2)+k] -= v2[(i<<2)+k]*t;
  328. }
  329. }
  330. }
  331. }
  332. return inv;
  333. }
  334. }