PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/isgl3d/math/Isgl3dMatrix4.h

https://github.com/edwardean/isgl3d
C Header | 845 lines | 697 code | 120 blank | 28 comment | 5 complexity | 464a2b7bbf2398b7a432bfa575b6e2d5 MD5 | raw file
Possible License(s): Unlicense
  1. /*
  2. * iSGL3D: http://isgl3d.com
  3. *
  4. * Copyright (c) 2010-2012 Stuart Caunt
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. *
  24. */
  25. #import <Foundation/Foundation.h>
  26. #import "Isgl3dMathTypes.h"
  27. #import "Isgl3dVector3.h"
  28. #import "Isgl3dVector4.h"
  29. /*
  30. * Use GLKit definitions for iOS >= 5.0 and if no strict ANSI compilation is set (C/C++ language dialect)
  31. * GLKit linkage required in this case
  32. */
  33. #if !(defined(__STRICT_ANSI__)) && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_5_0)
  34. #import <GLKit/GLKMath.h>
  35. #define Isgl3dMatrix4Identity GLKMatrix4Identity
  36. #define Isgl3dMatrix4Matrix GLKMatrix4Make
  37. #define Isgl3dMatrix4MakeAndTranspose GLKMatrix4MakeAndTranspose
  38. #define Isgl3dMatrix4MakeWithArray GLKMatrix4MakeWithArray
  39. #define Isgl3dMatrix4MakeWithArrayAndTranspose GLKMatrix4MakeWithArrayAndTranspose
  40. #define Isgl3dMatrix4MakeWithRows GLKMatrix4MakeWithRows
  41. #define Isgl3dMatrix4MakeWithColumns GLKMatrix4MakeWithColumns
  42. #define Isgl3dMatrix4MakeTranslation GLKMatrix4MakeTranslation
  43. #define Isgl3dMatrix4MakeScale GLKMatrix4MakeScale
  44. #define Isgl3dMatrix4MakeRotation GLKMatrix4MakeRotation
  45. #define Isgl3dMatrix4MakeXRotation GLKMatrix4MakeXRotation
  46. #define Isgl3dMatrix4MakeYRotation GLKMatrix4MakeYRotation
  47. #define Isgl3dMatrix4MakeZRotation GLKMatrix4MakeZRotation
  48. #define Isgl3dMatrix4MakePerspective GLKMatrix4MakePerspective
  49. #define Isgl3dMatrix4MakeFrustum GLKMatrix4MakeFrustum
  50. #define Isgl3dMatrix4MakeOrtho GLKMatrix4MakeOrtho
  51. #define Isgl3dMatrix4MakeLookAt GLKMatrix4MakeLookAt
  52. #define Isgl3dMatrix4GetMatrix3 GLKMatrix4GetMatrix3
  53. #define Isgl3dMatrix4GetMatrix2 GLKMatrix4GetMatrix2
  54. #define Isgl3dMatrix4GetRow GLKMatrix4GetRow
  55. #define Isgl3dMatrix4GetColumn GLKMatrix4GetColumn
  56. #define Isgl3dMatrix4SetRow GLKMatrix4SetRow
  57. #define Isgl3dMatrix4SetColumn GLKMatrix4SetColumn
  58. #define Isgl3dMatrix4Transpose GLKMatrix4Transpose
  59. #define Isgl3dMatrix4Invert GLKMatrix4Invert
  60. #define Isgl3dMatrix4InvertAndTranspose GLKMatrix4InvertAndTranspose
  61. #define Isgl3dMatrix4Multiply GLKMatrix4Multiply
  62. #define Isgl3dMatrix4Add GLKMatrix4Add
  63. #define Isgl3dMatrix4Subtract GLKMatrix4Subtract
  64. #define Isgl3dMatrix4Translate GLKMatrix4Translate
  65. #define Isgl3dMatrix4TranslateWithVector3 GLKMatrix4TranslateWithVector3
  66. #define Isgl3dMatrix4TranslateWithVector4 GLKMatrix4TranslateWithVector4
  67. #define Isgl3dMatrix4Scale GLKMatrix4Scale
  68. #define Isgl3dMatrix4ScaleWithVector3 GLKMatrix4ScaleWithVector3
  69. #define Isgl3dMatrix4ScaleWithVector4 GLKMatrix4ScaleWithVector4
  70. #define Isgl3dMatrix4Rotate GLKMatrix4Rotate
  71. #define Isgl3dMatrix4RotateWithVector3 GLKMatrix4RotateWithVector3
  72. #define Isgl3dMatrix4RotateWithVector4 GLKMatrix4RotateWithVector4
  73. #define Isgl3dMatrix4RotateX GLKMatrix4RotateX
  74. #define Isgl3dMatrix4RotateY GLKMatrix4RotateY
  75. #define Isgl3dMatrix4RotateZ GLKMatrix4RotateZ
  76. #define Isgl3dMatrix4MultiplyVector3 GLKMatrix4MultiplyVector3
  77. #define Isgl3dMatrix4MultiplyVector3WithTranslation GLKMatrix4MultiplyVector3WithTranslation
  78. #define Isgl3dMatrix4MultiplyAndProjectVector3 GLKMatrix4MultiplyAndProjectVector3
  79. #define Isgl3dMatrix4MultiplyVector3Array GLKMatrix4MultiplyVector3Array
  80. #define Isgl3dMatrix4MultiplyVector3ArrayWithTranslation GLKMatrix4MultiplyVector3ArrayWithTranslation
  81. #define Isgl3dMatrix4MultiplyAndProjectVector3Array GLKMatrix4MultiplyAndProjectVector3Array
  82. #define Isgl3dMatrix4MultiplyVector4 GLKMatrix4MultiplyVector4
  83. #define Isgl3dMatrix4MultiplyVector4Array GLKMatrix4MultiplyVector4Array
  84. #else
  85. #include <stddef.h>
  86. #include <stdbool.h>
  87. #include <math.h>
  88. #if defined(__ARM_NEON__)
  89. #include <arm_neon.h>
  90. #endif
  91. #ifdef __cplusplus
  92. extern "C" {
  93. #endif
  94. #pragma mark -
  95. #pragma mark GLKit compatible Prototypes
  96. #pragma mark -
  97. extern const Isgl3dMatrix4 Isgl3dMatrix4Identity;
  98. static inline Isgl3dMatrix4 Isgl3dMatrix4Matrix(float m00, float m01, float m02, float m03,
  99. float m10, float m11, float m12, float m13,
  100. float m20, float m21, float m22, float m23,
  101. float m30, float m31, float m32, float m33);
  102. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeAndTranspose(float m00, float m01, float m02, float m03,
  103. float m10, float m11, float m12, float m13,
  104. float m20, float m21, float m22, float m23,
  105. float m30, float m31, float m32, float m33);
  106. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeWithArray(float values[16]);
  107. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeWithArrayAndTranspose(float values[16]);
  108. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeWithRows(Isgl3dVector4 row0,
  109. Isgl3dVector4 row1,
  110. Isgl3dVector4 row2,
  111. Isgl3dVector4 row3);
  112. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeTranslation(float tx, float ty, float tz);
  113. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeScale(float sx, float sy, float sz);
  114. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeRotation(float radians, float x, float y, float z);
  115. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeXRotation(float radians);
  116. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeYRotation(float radians);
  117. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeZRotation(float radians);
  118. static inline Isgl3dMatrix4 Isgl3dMatrix4MakePerspective(float fovyRadians, float aspect, float nearZ, float farZ);
  119. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeFrustum(float left, float right,
  120. float bottom, float top,
  121. float nearZ, float farZ);
  122. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeOrtho(float left, float right,
  123. float bottom, float top,
  124. float nearZ, float farZ);
  125. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ,
  126. float centerX, float centerY, float centerZ,
  127. float upX, float upY, float upZ);
  128. static inline Isgl3dMatrix3 Isgl3dMatrix4GetMatrix3(Isgl3dMatrix4 matrix);
  129. static inline Isgl3dMatrix2 Isgl3dMatrix4GetMatrix2(Isgl3dMatrix4 matrix);
  130. static inline Isgl3dVector4 Isgl3dMatrix4GetRow(Isgl3dMatrix4 matrix, int row);
  131. static inline Isgl3dVector4 Isgl3dMatrix4GetColumn(Isgl3dMatrix4 matrix, int column);
  132. static inline Isgl3dMatrix4 Isgl3dMatrix4SetRow(Isgl3dMatrix4 matrix, int row, Isgl3dVector4 vector);
  133. static inline Isgl3dMatrix4 Isgl3dMatrix4SetColumn(Isgl3dMatrix4 matrix, int column, Isgl3dVector4 vector);
  134. static inline Isgl3dMatrix4 Isgl3dMatrix4Transpose(Isgl3dMatrix4 matrix);
  135. Isgl3dMatrix4 Isgl3dMatrix4Invert(Isgl3dMatrix4 matrix, bool *isInvertible);
  136. Isgl3dMatrix4 Isgl3dMatrix4InvertAndTranspose(Isgl3dMatrix4 matrix, bool *isInvertible);
  137. #ifndef __clang__
  138. static inline Isgl3dMatrix4 Isgl3dMatrix4Multiply(Isgl3dMatrix4 matrixLeft, Isgl3dMatrix4 matrixRight);
  139. #else
  140. static Isgl3dMatrix4 Isgl3dMatrix4Multiply(Isgl3dMatrix4 matrixLeft, Isgl3dMatrix4 matrixRight);
  141. #endif
  142. static inline Isgl3dMatrix4 Isgl3dMatrix4Add(Isgl3dMatrix4 matrixLeft, Isgl3dMatrix4 matrixRight);
  143. static inline Isgl3dMatrix4 Isgl3dMatrix4Subtract(Isgl3dMatrix4 matrixLeft, Isgl3dMatrix4 matrixRight);
  144. static inline Isgl3dMatrix4 Isgl3dMatrix4Translate(Isgl3dMatrix4 matrix, float tx, float ty, float tz);
  145. static inline Isgl3dMatrix4 Isgl3dMatrix4TranslateWithVector3(Isgl3dMatrix4 matrix, Isgl3dVector3 translationVector);
  146. static inline Isgl3dMatrix4 Isgl3dMatrix4TranslateWithVector4(Isgl3dMatrix4 matrix, Isgl3dVector4 translationVector);
  147. static inline Isgl3dMatrix4 Isgl3dMatrix4Scale(Isgl3dMatrix4 matrix, float sx, float sy, float sz);
  148. static inline Isgl3dMatrix4 Isgl3dMatrix4ScaleWithVector3(Isgl3dMatrix4 matrix, Isgl3dVector3 scaleVector);
  149. static inline Isgl3dMatrix4 Isgl3dMatrix4ScaleWithVector4(Isgl3dMatrix4 matrix, Isgl3dVector4 scaleVector);
  150. static inline Isgl3dMatrix4 Isgl3dMatrix4Rotate(Isgl3dMatrix4 matrix, float radians, float x, float y, float z);
  151. static inline Isgl3dMatrix4 Isgl3dMatrix4RotateWithVector3(Isgl3dMatrix4 matrix, float radians, Isgl3dVector3 axisVector);
  152. static inline Isgl3dMatrix4 Isgl3dMatrix4RotateWithVector4(Isgl3dMatrix4 matrix, float radians, Isgl3dVector4 axisVector);
  153. static inline Isgl3dMatrix4 Isgl3dMatrix4RotateX(Isgl3dMatrix4 matrix, float radians);
  154. static inline Isgl3dMatrix4 Isgl3dMatrix4RotateY(Isgl3dMatrix4 matrix, float radians);
  155. static inline Isgl3dMatrix4 Isgl3dMatrix4RotateZ(Isgl3dMatrix4 matrix, float radians);
  156. static inline Isgl3dVector3 Isgl3dMatrix4MultiplyVector3(Isgl3dMatrix4 matrixLeft, Isgl3dVector3 vectorRight);
  157. static inline Isgl3dVector3 Isgl3dMatrix4MultiplyVector3WithTranslation(Isgl3dMatrix4 matrixLeft, Isgl3dVector3 vectorRight);
  158. static inline Isgl3dVector3 Isgl3dMatrix4MultiplyAndProjectVector3(Isgl3dMatrix4 matrixLeft, Isgl3dVector3 vectorRight);
  159. static inline void Isgl3dMatrix4MultiplyVector3Array(Isgl3dMatrix4 matrix, Isgl3dVector3 *vectors, size_t vectorCount);
  160. static inline void Isgl3dMatrix4MultiplyAndProjectVector3Array(Isgl3dMatrix4 matrix, Isgl3dVector3 *vectors, size_t vectorCount);
  161. static inline Isgl3dVector4 Isgl3dMatrix4MultiplyVector4(Isgl3dMatrix4 matrixLeft, Isgl3dVector4 vectorRight);
  162. static inline void Isgl3dMatrix4MultiplyVector4Array(Isgl3dMatrix4 matrix, Isgl3dVector4 *vectors, size_t vectorCount);
  163. #pragma mark -
  164. #pragma mark GLKit compatible Implementations
  165. #pragma mark -
  166. static inline Isgl3dMatrix4 Isgl3dMatrix4Matrix(float m00, float m01, float m02, float m03,
  167. float m10, float m11, float m12, float m13,
  168. float m20, float m21, float m22, float m23,
  169. float m30, float m31, float m32, float m33)
  170. {
  171. Isgl3dMatrix4 m = { m00, m01, m02, m03,
  172. m10, m11, m12, m13,
  173. m20, m21, m22, m23,
  174. m30, m31, m32, m33 };
  175. return m;
  176. }
  177. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeAndTranspose(float m00, float m01, float m02, float m03,
  178. float m10, float m11, float m12, float m13,
  179. float m20, float m21, float m22, float m23,
  180. float m30, float m31, float m32, float m33)
  181. {
  182. Isgl3dMatrix4 m = { m00, m10, m20, m30,
  183. m01, m11, m21, m31,
  184. m02, m12, m22, m32,
  185. m03, m13, m23, m33 };
  186. return m;
  187. }
  188. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeWithArray(float values[16])
  189. {
  190. Isgl3dMatrix4 m = { values[0], values[1], values[2], values[3],
  191. values[4], values[5], values[6], values[7],
  192. values[8], values[9], values[10], values[11],
  193. values[12], values[13], values[14], values[15] };
  194. return m;
  195. }
  196. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeWithArrayAndTranspose(float values[16])
  197. {
  198. #if defined(__ARM_NEON__)
  199. float32x4x4_t m = vld4q_f32(values);
  200. return *(Isgl3dMatrix4 *)&m;
  201. #else
  202. Isgl3dMatrix4 m = { values[0], values[4], values[8], values[12],
  203. values[1], values[5], values[9], values[13],
  204. values[2], values[6], values[10], values[14],
  205. values[3], values[7], values[11], values[15] };
  206. return m;
  207. #endif
  208. }
  209. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeWithRows(Isgl3dVector4 row0,
  210. Isgl3dVector4 row1,
  211. Isgl3dVector4 row2,
  212. Isgl3dVector4 row3)
  213. {
  214. Isgl3dMatrix4 m = { row0.v[0], row1.v[0], row2.v[0], row3.v[0],
  215. row0.v[1], row1.v[1], row2.v[1], row3.v[1],
  216. row0.v[2], row1.v[2], row2.v[2], row3.v[2],
  217. row0.v[3], row1.v[3], row2.v[3], row3.v[3] };
  218. return m;
  219. }
  220. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeWithColumns(Isgl3dVector4 column0,
  221. Isgl3dVector4 column1,
  222. Isgl3dVector4 column2,
  223. Isgl3dVector4 column3)
  224. {
  225. #if defined(__ARM_NEON__)
  226. float32x4x4_t m;
  227. m.val[0] = vld1q_f32(column0.v);
  228. m.val[1] = vld1q_f32(column1.v);
  229. m.val[2] = vld1q_f32(column2.v);
  230. m.val[3] = vld1q_f32(column3.v);
  231. return *(Isgl3dMatrix4 *)&m;
  232. #else
  233. Isgl3dMatrix4 m = { column0.v[0], column0.v[1], column0.v[2], column0.v[3],
  234. column1.v[0], column1.v[1], column1.v[2], column1.v[3],
  235. column2.v[0], column2.v[1], column2.v[2], column2.v[3],
  236. column3.v[0], column3.v[1], column3.v[2], column3.v[3] };
  237. return m;
  238. #endif
  239. }
  240. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeTranslation(float tx, float ty, float tz)
  241. {
  242. Isgl3dMatrix4 m = Isgl3dMatrix4Identity;
  243. m.m[12] = tx;
  244. m.m[13] = ty;
  245. m.m[14] = tz;
  246. return m;
  247. }
  248. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeScale(float sx, float sy, float sz)
  249. {
  250. Isgl3dMatrix4 m = Isgl3dMatrix4Identity;
  251. m.m[0] = sx;
  252. m.m[5] = sy;
  253. m.m[10] = sz;
  254. return m;
  255. }
  256. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeRotation(float radians, float x, float y, float z)
  257. {
  258. Isgl3dVector3 v = Isgl3dVector3Normalize(Isgl3dVector3Make(x, y, z));
  259. float cos = cosf(radians);
  260. float cosp = 1.0f - cos;
  261. float sin = sinf(radians);
  262. Isgl3dMatrix4 m = { cos + cosp * v.v[0] * v.v[0],
  263. cosp * v.v[0] * v.v[1] + v.v[2] * sin,
  264. cosp * v.v[0] * v.v[2] - v.v[1] * sin,
  265. 0.0f,
  266. cosp * v.v[0] * v.v[1] - v.v[2] * sin,
  267. cos + cosp * v.v[1] * v.v[1],
  268. cosp * v.v[1] * v.v[2] + v.v[0] * sin,
  269. 0.0f,
  270. cosp * v.v[0] * v.v[2] + v.v[1] * sin,
  271. cosp * v.v[1] * v.v[2] - v.v[0] * sin,
  272. cos + cosp * v.v[2] * v.v[2],
  273. 0.0f,
  274. 0.0f,
  275. 0.0f,
  276. 0.0f,
  277. 1.0f };
  278. return m;
  279. }
  280. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeXRotation(float radians)
  281. {
  282. float cos = cosf(radians);
  283. float sin = sinf(radians);
  284. Isgl3dMatrix4 m = { 1.0f, 0.0f, 0.0f, 0.0f,
  285. 0.0f, cos, sin, 0.0f,
  286. 0.0f, -sin, cos, 0.0f,
  287. 0.0f, 0.0f, 0.0f, 1.0f };
  288. return m;
  289. }
  290. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeYRotation(float radians)
  291. {
  292. float cos = cosf(radians);
  293. float sin = sinf(radians);
  294. Isgl3dMatrix4 m = { cos, 0.0f, -sin, 0.0f,
  295. 0.0f, 1.0f, 0.0f, 0.0f,
  296. sin, 0.0f, cos, 0.0f,
  297. 0.0f, 0.0f, 0.0f, 1.0f };
  298. return m;
  299. }
  300. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeZRotation(float radians)
  301. {
  302. float cos = cosf(radians);
  303. float sin = sinf(radians);
  304. Isgl3dMatrix4 m = { cos, sin, 0.0f, 0.0f,
  305. -sin, cos, 0.0f, 0.0f,
  306. 0.0f, 0.0f, 1.0f, 0.0f,
  307. 0.0f, 0.0f, 0.0f, 1.0f };
  308. return m;
  309. }
  310. static inline Isgl3dMatrix4 Isgl3dMatrix4MakePerspective(float fovyRadians, float aspect, float nearZ, float farZ)
  311. {
  312. float cotan = 1.0f / tanf(fovyRadians / 2.0f);
  313. Isgl3dMatrix4 m = { cotan / aspect, 0.0f, 0.0f, 0.0f,
  314. 0.0f, cotan, 0.0f, 0.0f,
  315. 0.0f, 0.0f, (farZ + nearZ) / (nearZ - farZ), -1.0f,
  316. 0.0f, 0.0f, (2.0f * farZ * nearZ) / (nearZ - farZ), 0.0f };
  317. return m;
  318. }
  319. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeFrustum(float left, float right,
  320. float bottom, float top,
  321. float nearZ, float farZ)
  322. {
  323. float ral = right + left;
  324. float rsl = right - left;
  325. float tsb = top - bottom;
  326. float tab = top + bottom;
  327. float fan = farZ + nearZ;
  328. float fsn = farZ - nearZ;
  329. Isgl3dMatrix4 m = { 2.0f * nearZ / rsl, 0.0f, 0.0f, 0.0f,
  330. 0.0f, 2.0f * nearZ / tsb, 0.0f, 0.0f,
  331. ral / rsl, tab / tsb, -fan / fsn, -1.0f,
  332. 0.0f, 0.0f, (-2.0f * farZ * nearZ) / fsn, 0.0f };
  333. return m;
  334. }
  335. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeOrtho(float left, float right,
  336. float bottom, float top,
  337. float nearZ, float farZ)
  338. {
  339. float ral = right + left;
  340. float rsl = right - left;
  341. float tab = top + bottom;
  342. float tsb = top - bottom;
  343. float fan = farZ + nearZ;
  344. float fsn = farZ - nearZ;
  345. Isgl3dMatrix4 m = { 2.0f / rsl, 0.0f, 0.0f, 0.0f,
  346. 0.0f, 2.0f / tsb, 0.0f, 0.0f,
  347. 0.0f, 0.0f, -2.0f / fsn, 0.0f,
  348. -ral / rsl, -tab / tsb, -fan / fsn, 1.0f };
  349. return m;
  350. }
  351. static inline Isgl3dMatrix4 Isgl3dMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ,
  352. float centerX, float centerY, float centerZ,
  353. float upX, float upY, float upZ)
  354. {
  355. Isgl3dVector3 ev = { eyeX, eyeY, eyeZ };
  356. Isgl3dVector3 cv = { centerX, centerY, centerZ };
  357. Isgl3dVector3 uv = { upX, upY, upZ };
  358. Isgl3dVector3 n = Isgl3dVector3Normalize(Isgl3dVector3Add(ev, Isgl3dVector3Negate(cv)));
  359. Isgl3dVector3 u = Isgl3dVector3Normalize(Isgl3dVector3CrossProduct(uv, n));
  360. Isgl3dVector3 v = Isgl3dVector3CrossProduct(n, u);
  361. Isgl3dMatrix4 m = { u.v[0], v.v[0], n.v[0], 0.0f,
  362. u.v[1], v.v[1], n.v[1], 0.0f,
  363. u.v[2], v.v[2], n.v[2], 0.0f,
  364. Isgl3dVector3DotProduct(Isgl3dVector3Negate(u), ev),
  365. Isgl3dVector3DotProduct(Isgl3dVector3Negate(v), ev),
  366. Isgl3dVector3DotProduct(Isgl3dVector3Negate(n), ev),
  367. 1.0f };
  368. return m;
  369. }
  370. static inline Isgl3dMatrix3 Isgl3dMatrix4GetMatrix3(Isgl3dMatrix4 matrix)
  371. {
  372. Isgl3dMatrix3 m = { matrix.m[0], matrix.m[1], matrix.m[2],
  373. matrix.m[4], matrix.m[5], matrix.m[6],
  374. matrix.m[8], matrix.m[9], matrix.m[10] };
  375. return m;
  376. }
  377. static inline Isgl3dMatrix2 Isgl3dMatrix4GetMatrix2(Isgl3dMatrix4 matrix)
  378. {
  379. Isgl3dMatrix2 m = { matrix.m[0], matrix.m[1],
  380. matrix.m[4], matrix.m[5] };
  381. return m;
  382. }
  383. static inline Isgl3dVector4 Isgl3dMatrix4GetRow(Isgl3dMatrix4 matrix, int row)
  384. {
  385. Isgl3dVector4 v = { matrix.m[row], matrix.m[4 + row], matrix.m[8 + row], matrix.m[12 + row] };
  386. return v;
  387. }
  388. static inline Isgl3dVector4 Isgl3dMatrix4GetColumn(Isgl3dMatrix4 matrix, int column)
  389. {
  390. #if defined(__ARM_NEON__)
  391. float32x4_t v = vld1q_f32(&(matrix.m[column * 4]));
  392. return *(Isgl3dVector4 *)&v;
  393. #else
  394. Isgl3dVector4 v = { matrix.m[column * 4 + 0], matrix.m[column * 4 + 1], matrix.m[column * 4 + 2], matrix.m[column * 4 + 3] };
  395. return v;
  396. #endif
  397. }
  398. static inline Isgl3dMatrix4 Isgl3dMatrix4SetRow(Isgl3dMatrix4 matrix, int row, Isgl3dVector4 vector)
  399. {
  400. matrix.m[row] = vector.v[0];
  401. matrix.m[row + 4] = vector.v[1];
  402. matrix.m[row + 8] = vector.v[2];
  403. matrix.m[row + 12] = vector.v[3];
  404. return matrix;
  405. }
  406. static inline Isgl3dMatrix4 Isgl3dMatrix4SetColumn(Isgl3dMatrix4 matrix, int column, Isgl3dVector4 vector)
  407. {
  408. #if defined(__ARM_NEON__)
  409. float *dst = &(matrix.m[column * 4]);
  410. vst1q_f32(dst, vld1q_f32(vector.v));
  411. return matrix;
  412. #else
  413. matrix.m[column * 4 + 0] = vector.v[0];
  414. matrix.m[column * 4 + 1] = vector.v[1];
  415. matrix.m[column * 4 + 2] = vector.v[2];
  416. matrix.m[column * 4 + 3] = vector.v[3];
  417. return matrix;
  418. #endif
  419. }
  420. static inline Isgl3dMatrix4 Isgl3dMatrix4Transpose(Isgl3dMatrix4 matrix)
  421. {
  422. #if defined(__ARM_NEON__)
  423. float32x4x4_t m = vld4q_f32(matrix.m);
  424. return *(Isgl3dMatrix4 *)&m;
  425. #else
  426. Isgl3dMatrix4 m = { matrix.m[0], matrix.m[4], matrix.m[8], matrix.m[12],
  427. matrix.m[1], matrix.m[5], matrix.m[9], matrix.m[13],
  428. matrix.m[2], matrix.m[6], matrix.m[10], matrix.m[14],
  429. matrix.m[3], matrix.m[7], matrix.m[11], matrix.m[15] };
  430. return m;
  431. #endif
  432. }
  433. #ifndef __clang__
  434. static inline Isgl3dMatrix4 Isgl3dMatrix4Multiply(Isgl3dMatrix4 matrixLeft, Isgl3dMatrix4 matrixRight)
  435. #else
  436. static Isgl3dMatrix4 Isgl3dMatrix4Multiply(Isgl3dMatrix4 matrixLeft, Isgl3dMatrix4 matrixRight)
  437. #endif
  438. {
  439. #if defined(__ARM_NEON__)
  440. float32x4x4_t iMatrixLeft = *(float32x4x4_t *)&matrixLeft;
  441. float32x4x4_t iMatrixRight = *(float32x4x4_t *)&matrixRight;
  442. float32x4x4_t m;
  443. m.val[0] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[0], 0));
  444. m.val[1] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[1], 0));
  445. m.val[2] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[2], 0));
  446. m.val[3] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[3], 0));
  447. m.val[0] = vmlaq_n_f32(m.val[0], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[0], 1));
  448. m.val[1] = vmlaq_n_f32(m.val[1], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[1], 1));
  449. m.val[2] = vmlaq_n_f32(m.val[2], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[2], 1));
  450. m.val[3] = vmlaq_n_f32(m.val[3], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[3], 1));
  451. m.val[0] = vmlaq_n_f32(m.val[0], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[0], 2));
  452. m.val[1] = vmlaq_n_f32(m.val[1], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[1], 2));
  453. m.val[2] = vmlaq_n_f32(m.val[2], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[2], 2));
  454. m.val[3] = vmlaq_n_f32(m.val[3], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[3], 2));
  455. m.val[0] = vmlaq_n_f32(m.val[0], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[0], 3));
  456. m.val[1] = vmlaq_n_f32(m.val[1], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[1], 3));
  457. m.val[2] = vmlaq_n_f32(m.val[2], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[2], 3));
  458. m.val[3] = vmlaq_n_f32(m.val[3], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[3], 3));
  459. return *(Isgl3dMatrix4 *)&m;
  460. #else
  461. Isgl3dMatrix4 m;
  462. m.m[0] = matrixLeft.m[0] * matrixRight.m[0] + matrixLeft.m[4] * matrixRight.m[1] + matrixLeft.m[8] * matrixRight.m[2] + matrixLeft.m[12] * matrixRight.m[3];
  463. m.m[4] = matrixLeft.m[0] * matrixRight.m[4] + matrixLeft.m[4] * matrixRight.m[5] + matrixLeft.m[8] * matrixRight.m[6] + matrixLeft.m[12] * matrixRight.m[7];
  464. m.m[8] = matrixLeft.m[0] * matrixRight.m[8] + matrixLeft.m[4] * matrixRight.m[9] + matrixLeft.m[8] * matrixRight.m[10] + matrixLeft.m[12] * matrixRight.m[11];
  465. m.m[12] = matrixLeft.m[0] * matrixRight.m[12] + matrixLeft.m[4] * matrixRight.m[13] + matrixLeft.m[8] * matrixRight.m[14] + matrixLeft.m[12] * matrixRight.m[15];
  466. m.m[1] = matrixLeft.m[1] * matrixRight.m[0] + matrixLeft.m[5] * matrixRight.m[1] + matrixLeft.m[9] * matrixRight.m[2] + matrixLeft.m[13] * matrixRight.m[3];
  467. m.m[5] = matrixLeft.m[1] * matrixRight.m[4] + matrixLeft.m[5] * matrixRight.m[5] + matrixLeft.m[9] * matrixRight.m[6] + matrixLeft.m[13] * matrixRight.m[7];
  468. m.m[9] = matrixLeft.m[1] * matrixRight.m[8] + matrixLeft.m[5] * matrixRight.m[9] + matrixLeft.m[9] * matrixRight.m[10] + matrixLeft.m[13] * matrixRight.m[11];
  469. m.m[13] = matrixLeft.m[1] * matrixRight.m[12] + matrixLeft.m[5] * matrixRight.m[13] + matrixLeft.m[9] * matrixRight.m[14] + matrixLeft.m[13] * matrixRight.m[15];
  470. m.m[2] = matrixLeft.m[2] * matrixRight.m[0] + matrixLeft.m[6] * matrixRight.m[1] + matrixLeft.m[10] * matrixRight.m[2] + matrixLeft.m[14] * matrixRight.m[3];
  471. m.m[6] = matrixLeft.m[2] * matrixRight.m[4] + matrixLeft.m[6] * matrixRight.m[5] + matrixLeft.m[10] * matrixRight.m[6] + matrixLeft.m[14] * matrixRight.m[7];
  472. m.m[10] = matrixLeft.m[2] * matrixRight.m[8] + matrixLeft.m[6] * matrixRight.m[9] + matrixLeft.m[10] * matrixRight.m[10] + matrixLeft.m[14] * matrixRight.m[11];
  473. m.m[14] = matrixLeft.m[2] * matrixRight.m[12] + matrixLeft.m[6] * matrixRight.m[13] + matrixLeft.m[10] * matrixRight.m[14] + matrixLeft.m[14] * matrixRight.m[15];
  474. m.m[3] = matrixLeft.m[3] * matrixRight.m[0] + matrixLeft.m[7] * matrixRight.m[1] + matrixLeft.m[11] * matrixRight.m[2] + matrixLeft.m[15] * matrixRight.m[3];
  475. m.m[7] = matrixLeft.m[3] * matrixRight.m[4] + matrixLeft.m[7] * matrixRight.m[5] + matrixLeft.m[11] * matrixRight.m[6] + matrixLeft.m[15] * matrixRight.m[7];
  476. m.m[11] = matrixLeft.m[3] * matrixRight.m[8] + matrixLeft.m[7] * matrixRight.m[9] + matrixLeft.m[11] * matrixRight.m[10] + matrixLeft.m[15] * matrixRight.m[11];
  477. m.m[15] = matrixLeft.m[3] * matrixRight.m[12] + matrixLeft.m[7] * matrixRight.m[13] + matrixLeft.m[11] * matrixRight.m[14] + matrixLeft.m[15] * matrixRight.m[15];
  478. return m;
  479. #endif
  480. }
  481. static inline Isgl3dMatrix4 Isgl3dMatrix4Add(Isgl3dMatrix4 matrixLeft, Isgl3dMatrix4 matrixRight)
  482. {
  483. #if defined(__ARM_NEON__)
  484. float32x4x4_t iMatrixLeft = *(float32x4x4_t *)&matrixLeft;
  485. float32x4x4_t iMatrixRight = *(float32x4x4_t *)&matrixRight;
  486. float32x4x4_t m;
  487. m.val[0] = vaddq_f32(iMatrixLeft.val[0], iMatrixRight.val[0]);
  488. m.val[1] = vaddq_f32(iMatrixLeft.val[1], iMatrixRight.val[1]);
  489. m.val[2] = vaddq_f32(iMatrixLeft.val[2], iMatrixRight.val[2]);
  490. m.val[3] = vaddq_f32(iMatrixLeft.val[3], iMatrixRight.val[3]);
  491. return *(Isgl3dMatrix4 *)&m;
  492. #else
  493. Isgl3dMatrix4 m;
  494. m.m[0] = matrixLeft.m[0] + matrixRight.m[0];
  495. m.m[1] = matrixLeft.m[1] + matrixRight.m[1];
  496. m.m[2] = matrixLeft.m[2] + matrixRight.m[2];
  497. m.m[3] = matrixLeft.m[3] + matrixRight.m[3];
  498. m.m[4] = matrixLeft.m[4] + matrixRight.m[4];
  499. m.m[5] = matrixLeft.m[5] + matrixRight.m[5];
  500. m.m[6] = matrixLeft.m[6] + matrixRight.m[6];
  501. m.m[7] = matrixLeft.m[7] + matrixRight.m[7];
  502. m.m[8] = matrixLeft.m[8] + matrixRight.m[8];
  503. m.m[9] = matrixLeft.m[9] + matrixRight.m[9];
  504. m.m[10] = matrixLeft.m[10] + matrixRight.m[10];
  505. m.m[11] = matrixLeft.m[11] + matrixRight.m[11];
  506. m.m[12] = matrixLeft.m[12] + matrixRight.m[12];
  507. m.m[13] = matrixLeft.m[13] + matrixRight.m[13];
  508. m.m[14] = matrixLeft.m[14] + matrixRight.m[14];
  509. m.m[15] = matrixLeft.m[15] + matrixRight.m[15];
  510. return m;
  511. #endif
  512. }
  513. static inline Isgl3dMatrix4 Isgl3dMatrix4Subtract(Isgl3dMatrix4 matrixLeft, Isgl3dMatrix4 matrixRight)
  514. {
  515. #if defined(__ARM_NEON__)
  516. float32x4x4_t iMatrixLeft = *(float32x4x4_t *)&matrixLeft;
  517. float32x4x4_t iMatrixRight = *(float32x4x4_t *)&matrixRight;
  518. float32x4x4_t m;
  519. m.val[0] = vsubq_f32(iMatrixLeft.val[0], iMatrixRight.val[0]);
  520. m.val[1] = vsubq_f32(iMatrixLeft.val[1], iMatrixRight.val[1]);
  521. m.val[2] = vsubq_f32(iMatrixLeft.val[2], iMatrixRight.val[2]);
  522. m.val[3] = vsubq_f32(iMatrixLeft.val[3], iMatrixRight.val[3]);
  523. return *(Isgl3dMatrix4 *)&m;
  524. #else
  525. Isgl3dMatrix4 m;
  526. m.m[0] = matrixLeft.m[0] - matrixRight.m[0];
  527. m.m[1] = matrixLeft.m[1] - matrixRight.m[1];
  528. m.m[2] = matrixLeft.m[2] - matrixRight.m[2];
  529. m.m[3] = matrixLeft.m[3] - matrixRight.m[3];
  530. m.m[4] = matrixLeft.m[4] - matrixRight.m[4];
  531. m.m[5] = matrixLeft.m[5] - matrixRight.m[5];
  532. m.m[6] = matrixLeft.m[6] - matrixRight.m[6];
  533. m.m[7] = matrixLeft.m[7] - matrixRight.m[7];
  534. m.m[8] = matrixLeft.m[8] - matrixRight.m[8];
  535. m.m[9] = matrixLeft.m[9] - matrixRight.m[9];
  536. m.m[10] = matrixLeft.m[10] - matrixRight.m[10];
  537. m.m[11] = matrixLeft.m[11] - matrixRight.m[11];
  538. m.m[12] = matrixLeft.m[12] - matrixRight.m[12];
  539. m.m[13] = matrixLeft.m[13] - matrixRight.m[13];
  540. m.m[14] = matrixLeft.m[14] - matrixRight.m[14];
  541. m.m[15] = matrixLeft.m[15] - matrixRight.m[15];
  542. return m;
  543. #endif
  544. }
  545. static inline Isgl3dMatrix4 Isgl3dMatrix4Translate(Isgl3dMatrix4 matrix, float tx, float ty, float tz)
  546. {
  547. Isgl3dMatrix4 m = { matrix.m[0], matrix.m[1], matrix.m[2], matrix.m[3],
  548. matrix.m[4], matrix.m[5], matrix.m[6], matrix.m[7],
  549. matrix.m[8], matrix.m[9], matrix.m[10], matrix.m[11],
  550. matrix.m[0] * tx + matrix.m[4] * ty + matrix.m[8] * tz + matrix.m[12],
  551. matrix.m[1] * tx + matrix.m[5] * ty + matrix.m[9] * tz + matrix.m[13],
  552. matrix.m[2] * tx + matrix.m[6] * ty + matrix.m[10] * tz + matrix.m[14],
  553. matrix.m[15] };
  554. return m;
  555. }
  556. static inline Isgl3dMatrix4 Isgl3dMatrix4TranslateWithVector3(Isgl3dMatrix4 matrix, Isgl3dVector3 translationVector)
  557. {
  558. Isgl3dMatrix4 m = { matrix.m[0], matrix.m[1], matrix.m[2], matrix.m[3],
  559. matrix.m[4], matrix.m[5], matrix.m[6], matrix.m[7],
  560. matrix.m[8], matrix.m[9], matrix.m[10], matrix.m[11],
  561. matrix.m[0] * translationVector.v[0] + matrix.m[4] * translationVector.v[1] + matrix.m[8] * translationVector.v[2] + matrix.m[12],
  562. matrix.m[1] * translationVector.v[0] + matrix.m[5] * translationVector.v[1] + matrix.m[9] * translationVector.v[2] + matrix.m[13],
  563. matrix.m[2] * translationVector.v[0] + matrix.m[6] * translationVector.v[1] + matrix.m[10] * translationVector.v[2] + matrix.m[14],
  564. matrix.m[15] };
  565. return m;
  566. }
  567. static inline Isgl3dMatrix4 Isgl3dMatrix4TranslateWithVector4(Isgl3dMatrix4 matrix, Isgl3dVector4 translationVector)
  568. {
  569. Isgl3dMatrix4 m = { matrix.m[0], matrix.m[1], matrix.m[2], matrix.m[3],
  570. matrix.m[4], matrix.m[5], matrix.m[6], matrix.m[7],
  571. matrix.m[8], matrix.m[9], matrix.m[10], matrix.m[11],
  572. matrix.m[0] * translationVector.v[0] + matrix.m[4] * translationVector.v[1] + matrix.m[8] * translationVector.v[2] + matrix.m[12],
  573. matrix.m[1] * translationVector.v[0] + matrix.m[5] * translationVector.v[1] + matrix.m[9] * translationVector.v[2] + matrix.m[13],
  574. matrix.m[2] * translationVector.v[0] + matrix.m[6] * translationVector.v[1] + matrix.m[10] * translationVector.v[2] + matrix.m[14],
  575. matrix.m[15] };
  576. return m;
  577. }
  578. static inline Isgl3dMatrix4 Isgl3dMatrix4Scale(Isgl3dMatrix4 matrix, float sx, float sy, float sz)
  579. {
  580. #if defined(__ARM_NEON__)
  581. float32x4x4_t iMatrix = *(float32x4x4_t *)&matrix;
  582. float32x4x4_t m;
  583. m.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)sx);
  584. m.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)sy);
  585. m.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)sz);
  586. m.val[3] = iMatrix.val[3];
  587. return *(Isgl3dMatrix4 *)&m;
  588. #else
  589. Isgl3dMatrix4 m = { matrix.m[0] * sx, matrix.m[1] * sx, matrix.m[2] * sx, matrix.m[3] * sx,
  590. matrix.m[4] * sy, matrix.m[5] * sy, matrix.m[6] * sy, matrix.m[7] * sy,
  591. matrix.m[8] * sz, matrix.m[9] * sz, matrix.m[10] * sz, matrix.m[11] * sz,
  592. matrix.m[12], matrix.m[13], matrix.m[14], matrix.m[15] };
  593. return m;
  594. #endif
  595. }
  596. static inline Isgl3dMatrix4 Isgl3dMatrix4ScaleWithVector3(Isgl3dMatrix4 matrix, Isgl3dVector3 scaleVector)
  597. {
  598. #if defined(__ARM_NEON__)
  599. float32x4x4_t iMatrix = *(float32x4x4_t *)&matrix;
  600. float32x4x4_t m;
  601. m.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)scaleVector.v[0]);
  602. m.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)scaleVector.v[1]);
  603. m.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)scaleVector.v[2]);
  604. m.val[3] = iMatrix.val[3];
  605. return *(Isgl3dMatrix4 *)&m;
  606. #else
  607. Isgl3dMatrix4 m = { matrix.m[0] * scaleVector.v[0], matrix.m[1] * scaleVector.v[0], matrix.m[2] * scaleVector.v[0], matrix.m[3] * scaleVector.v[0],
  608. matrix.m[4] * scaleVector.v[1], matrix.m[5] * scaleVector.v[1], matrix.m[6] * scaleVector.v[1], matrix.m[7] * scaleVector.v[1],
  609. matrix.m[8] * scaleVector.v[2], matrix.m[9] * scaleVector.v[2], matrix.m[10] * scaleVector.v[2], matrix.m[11] * scaleVector.v[2],
  610. matrix.m[12], matrix.m[13], matrix.m[14], matrix.m[15] };
  611. return m;
  612. #endif
  613. }
  614. static inline Isgl3dMatrix4 Isgl3dMatrix4ScaleWithVector4(Isgl3dMatrix4 matrix, Isgl3dVector4 scaleVector)
  615. {
  616. #if defined(__ARM_NEON__)
  617. float32x4x4_t iMatrix = *(float32x4x4_t *)&matrix;
  618. float32x4x4_t m;
  619. m.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)scaleVector.v[0]);
  620. m.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)scaleVector.v[1]);
  621. m.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)scaleVector.v[2]);
  622. m.val[3] = iMatrix.val[3];
  623. return *(Isgl3dMatrix4 *)&m;
  624. #else
  625. Isgl3dMatrix4 m = { matrix.m[0] * scaleVector.v[0], matrix.m[1] * scaleVector.v[0], matrix.m[2] * scaleVector.v[0], matrix.m[3] * scaleVector.v[0],
  626. matrix.m[4] * scaleVector.v[1], matrix.m[5] * scaleVector.v[1], matrix.m[6] * scaleVector.v[1], matrix.m[7] * scaleVector.v[1],
  627. matrix.m[8] * scaleVector.v[2], matrix.m[9] * scaleVector.v[2], matrix.m[10] * scaleVector.v[2], matrix.m[11] * scaleVector.v[2],
  628. matrix.m[12], matrix.m[13], matrix.m[14], matrix.m[15] };
  629. return m;
  630. #endif
  631. }
  632. static inline Isgl3dMatrix4 Isgl3dMatrix4Rotate(Isgl3dMatrix4 matrix, float radians, float x, float y, float z)
  633. {
  634. Isgl3dMatrix4 rm = Isgl3dMatrix4MakeRotation(radians, x, y, z);
  635. return Isgl3dMatrix4Multiply(matrix, rm);
  636. }
  637. static inline Isgl3dMatrix4 Isgl3dMatrix4RotateWithVector3(Isgl3dMatrix4 matrix, float radians, Isgl3dVector3 axisVector)
  638. {
  639. Isgl3dMatrix4 rm = Isgl3dMatrix4MakeRotation(radians, axisVector.v[0], axisVector.v[1], axisVector.v[2]);
  640. return Isgl3dMatrix4Multiply(matrix, rm);
  641. }
  642. static inline Isgl3dMatrix4 Isgl3dMatrix4RotateWithVector4(Isgl3dMatrix4 matrix, float radians, Isgl3dVector4 axisVector)
  643. {
  644. Isgl3dMatrix4 rm = Isgl3dMatrix4MakeRotation(radians, axisVector.v[0], axisVector.v[1], axisVector.v[2]);
  645. return Isgl3dMatrix4Multiply(matrix, rm);
  646. }
  647. static inline Isgl3dMatrix4 Isgl3dMatrix4RotateX(Isgl3dMatrix4 matrix, float radians)
  648. {
  649. Isgl3dMatrix4 rm = Isgl3dMatrix4MakeXRotation(radians);
  650. return Isgl3dMatrix4Multiply(matrix, rm);
  651. }
  652. static inline Isgl3dMatrix4 Isgl3dMatrix4RotateY(Isgl3dMatrix4 matrix, float radians)
  653. {
  654. Isgl3dMatrix4 rm = Isgl3dMatrix4MakeYRotation(radians);
  655. return Isgl3dMatrix4Multiply(matrix, rm);
  656. }
  657. static inline Isgl3dMatrix4 Isgl3dMatrix4RotateZ(Isgl3dMatrix4 matrix, float radians)
  658. {
  659. Isgl3dMatrix4 rm = Isgl3dMatrix4MakeZRotation(radians);
  660. return Isgl3dMatrix4Multiply(matrix, rm);
  661. }
  662. static inline Isgl3dVector3 Isgl3dMatrix4MultiplyVector3(Isgl3dMatrix4 matrixLeft, Isgl3dVector3 vectorRight)
  663. {
  664. Isgl3dVector4 v4 = Isgl3dMatrix4MultiplyVector4(matrixLeft, Isgl3dVector4Make(vectorRight.v[0], vectorRight.v[1], vectorRight.v[2], 0.0f));
  665. return Isgl3dVector3Make(v4.v[0], v4.v[1], v4.v[2]);
  666. }
  667. static inline Isgl3dVector3 Isgl3dMatrix4MultiplyVector3WithTranslation(Isgl3dMatrix4 matrixLeft, Isgl3dVector3 vectorRight)
  668. {
  669. Isgl3dVector4 v4 = Isgl3dMatrix4MultiplyVector4(matrixLeft, Isgl3dVector4Make(vectorRight.v[0], vectorRight.v[1], vectorRight.v[2], 1.0f));
  670. return Isgl3dVector3Make(v4.v[0], v4.v[1], v4.v[2]);
  671. }
  672. static inline Isgl3dVector3 Isgl3dMatrix4MultiplyAndProjectVector3(Isgl3dMatrix4 matrixLeft, Isgl3dVector3 vectorRight)
  673. {
  674. Isgl3dVector4 v4 = Isgl3dMatrix4MultiplyVector4(matrixLeft, Isgl3dVector4Make(vectorRight.v[0], vectorRight.v[1], vectorRight.v[2], 1.0f));
  675. return Isgl3dVector3MultiplyScalar(Isgl3dVector3Make(v4.v[0], v4.v[1], v4.v[2]), 1.0f / v4.v[3]);
  676. }
  677. static inline void Isgl3dMatrix4MultiplyVector3Array(Isgl3dMatrix4 matrix, Isgl3dVector3 *vectors, size_t vectorCount)
  678. {
  679. int i;
  680. for (i=0; i < vectorCount; i++)
  681. vectors[i] = Isgl3dMatrix4MultiplyVector3(matrix, vectors[i]);
  682. }
  683. static inline void Isgl3dMatrix4MultiplyVector3ArrayWithTranslation(Isgl3dMatrix4 matrix, Isgl3dVector3 *vectors, size_t vectorCount)
  684. {
  685. int i;
  686. for (i=0; i < vectorCount; i++)
  687. vectors[i] = Isgl3dMatrix4MultiplyVector3WithTranslation(matrix, vectors[i]);
  688. }
  689. static inline void Isgl3dMatrix4MultiplyAndProjectVector3Array(Isgl3dMatrix4 matrix, Isgl3dVector3 *vectors, size_t vectorCount)
  690. {
  691. int i;
  692. for (i=0; i < vectorCount; i++)
  693. vectors[i] = Isgl3dMatrix4MultiplyAndProjectVector3(matrix, vectors[i]);
  694. }
  695. static inline Isgl3dVector4 Isgl3dMatrix4MultiplyVector4(Isgl3dMatrix4 matrixLeft, Isgl3dVector4 vectorRight)
  696. {
  697. #if defined(__ARM_NEON__)
  698. float32x4x4_t iMatrix = *(float32x4x4_t *)&matrixLeft;
  699. float32x4_t v;
  700. iMatrix.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)vectorRight.v[0]);
  701. iMatrix.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)vectorRight.v[1]);
  702. iMatrix.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)vectorRight.v[2]);
  703. iMatrix.val[3] = vmulq_n_f32(iMatrix.val[3], (float32_t)vectorRight.v[3]);
  704. iMatrix.val[0] = vaddq_f32(iMatrix.val[0], iMatrix.val[1]);
  705. iMatrix.val[2] = vaddq_f32(iMatrix.val[2], iMatrix.val[3]);
  706. v = vaddq_f32(iMatrix.val[0], iMatrix.val[2]);
  707. return *(Isgl3dVector4 *)&v;
  708. #else
  709. Isgl3dVector4 v = { matrixLeft.m[0] * vectorRight.v[0] + matrixLeft.m[4] * vectorRight.v[1] + matrixLeft.m[8] * vectorRight.v[2] + matrixLeft.m[12] * vectorRight.v[3],
  710. matrixLeft.m[1] * vectorRight.v[0] + matrixLeft.m[5] * vectorRight.v[1] + matrixLeft.m[9] * vectorRight.v[2] + matrixLeft.m[13] * vectorRight.v[3],
  711. matrixLeft.m[2] * vectorRight.v[0] + matrixLeft.m[6] * vectorRight.v[1] + matrixLeft.m[10] * vectorRight.v[2] + matrixLeft.m[14] * vectorRight.v[3],
  712. matrixLeft.m[3] * vectorRight.v[0] + matrixLeft.m[7] * vectorRight.v[1] + matrixLeft.m[11] * vectorRight.v[2] + matrixLeft.m[15] * vectorRight.v[3] };
  713. return v;
  714. #endif
  715. }
  716. static inline void Isgl3dMatrix4MultiplyVector4Array(Isgl3dMatrix4 matrix, Isgl3dVector4 *vectors, size_t vectorCount)
  717. {
  718. int i;
  719. for (i=0; i < vectorCount; i++)
  720. vectors[i] = Isgl3dMatrix4MultiplyVector4(matrix, vectors[i]);
  721. }
  722. #ifdef __cplusplus
  723. }
  724. #endif
  725. #endif