cglm 0.1.0 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -1
  3. data/Gemfile.lock +18 -16
  4. data/README.md +2 -0
  5. data/cglm.gemspec +3 -3
  6. data/ext/cglm/cglm-0.6.2/include/cglm/affine-mat.h +168 -0
  7. data/ext/cglm/cglm-0.6.2/include/cglm/affine.h +490 -0
  8. data/ext/cglm/cglm-0.6.2/include/cglm/applesimd.h +95 -0
  9. data/ext/cglm/cglm-0.6.2/include/cglm/bezier.h +154 -0
  10. data/ext/cglm/cglm-0.6.2/include/cglm/box.h +279 -0
  11. data/ext/cglm/cglm-0.6.2/include/cglm/call/affine.h +117 -0
  12. data/ext/cglm/cglm-0.6.2/include/cglm/call/bezier.h +31 -0
  13. data/ext/cglm/cglm-0.6.2/include/cglm/call/box.h +79 -0
  14. data/ext/cglm/cglm-0.6.2/include/cglm/call/cam.h +143 -0
  15. data/ext/cglm/cglm-0.6.2/include/cglm/call/curve.h +23 -0
  16. data/ext/cglm/cglm-0.6.2/include/cglm/call/ease.h +143 -0
  17. data/ext/cglm/cglm-0.6.2/include/cglm/call/euler.h +55 -0
  18. data/ext/cglm/cglm-0.6.2/include/cglm/call/frustum.h +41 -0
  19. data/ext/cglm/cglm-0.6.2/include/cglm/call/io.h +44 -0
  20. data/ext/cglm/cglm-0.6.2/include/cglm/call/mat3.h +86 -0
  21. data/ext/cglm/cglm-0.6.2/include/cglm/call/mat4.h +127 -0
  22. data/ext/cglm/cglm-0.6.2/include/cglm/call/plane.h +23 -0
  23. data/ext/cglm/cglm-0.6.2/include/cglm/call/project.h +33 -0
  24. data/ext/cglm/cglm-0.6.2/include/cglm/call/quat.h +159 -0
  25. data/ext/cglm/cglm-0.6.2/include/cglm/call/sphere.h +39 -0
  26. data/ext/cglm/cglm-0.6.2/include/cglm/call/vec3.h +312 -0
  27. data/ext/cglm/cglm-0.6.2/include/cglm/call/vec4.h +290 -0
  28. data/ext/cglm/cglm-0.6.2/include/cglm/call.h +36 -0
  29. data/ext/cglm/cglm-0.6.2/include/cglm/cam.h +585 -0
  30. data/ext/cglm/cglm-0.6.2/include/cglm/cglm.h +32 -0
  31. data/ext/cglm/cglm-0.6.2/include/cglm/color.h +26 -0
  32. data/ext/cglm/cglm-0.6.2/include/cglm/common.h +37 -0
  33. data/ext/cglm/cglm-0.6.2/include/cglm/curve.h +40 -0
  34. data/ext/cglm/cglm-0.6.2/include/cglm/ease.h +317 -0
  35. data/ext/cglm/cglm-0.6.2/include/cglm/euler.h +453 -0
  36. data/ext/cglm/cglm-0.6.2/include/cglm/frustum.h +255 -0
  37. data/ext/cglm/cglm-0.6.2/include/cglm/io.h +203 -0
  38. data/ext/cglm/cglm-0.6.2/include/cglm/mat3.h +422 -0
  39. data/ext/cglm/cglm-0.6.2/include/cglm/mat4.h +726 -0
  40. data/ext/cglm/cglm-0.6.2/include/cglm/plane.h +36 -0
  41. data/ext/cglm/cglm-0.6.2/include/cglm/project.h +118 -0
  42. data/ext/cglm/cglm-0.6.2/include/cglm/quat.h +828 -0
  43. data/ext/cglm/cglm-0.6.2/include/cglm/simd/arm.h +83 -0
  44. data/ext/cglm/cglm-0.6.2/include/cglm/simd/avx/affine.h +66 -0
  45. data/ext/cglm/cglm-0.6.2/include/cglm/simd/avx/mat4.h +66 -0
  46. data/ext/cglm/cglm-0.6.2/include/cglm/simd/intrin.h +90 -0
  47. data/ext/cglm/cglm-0.6.2/include/cglm/simd/neon/mat4.h +57 -0
  48. data/ext/cglm/cglm-0.6.2/include/cglm/simd/sse2/affine.h +111 -0
  49. data/ext/cglm/cglm-0.6.2/include/cglm/simd/sse2/mat3.h +59 -0
  50. data/ext/cglm/cglm-0.6.2/include/cglm/simd/sse2/mat4.h +405 -0
  51. data/ext/cglm/cglm-0.6.2/include/cglm/simd/sse2/quat.h +46 -0
  52. data/ext/cglm/cglm-0.6.2/include/cglm/simd/x86.h +192 -0
  53. data/ext/cglm/cglm-0.6.2/include/cglm/sphere.h +99 -0
  54. data/ext/cglm/cglm-0.6.2/include/cglm/struct/affine.h +337 -0
  55. data/ext/cglm/cglm-0.6.2/include/cglm/struct/box.h +256 -0
  56. data/ext/cglm/cglm-0.6.2/include/cglm/struct/cam.h +451 -0
  57. data/ext/cglm/cglm-0.6.2/include/cglm/struct/color.h +27 -0
  58. data/ext/cglm/cglm-0.6.2/include/cglm/struct/curve.h +40 -0
  59. data/ext/cglm/cglm-0.6.2/include/cglm/struct/euler.h +152 -0
  60. data/ext/cglm/cglm-0.6.2/include/cglm/struct/frustum.h +155 -0
  61. data/ext/cglm/cglm-0.6.2/include/cglm/struct/io.h +82 -0
  62. data/ext/cglm/cglm-0.6.2/include/cglm/struct/mat3.h +285 -0
  63. data/ext/cglm/cglm-0.6.2/include/cglm/struct/mat4.h +459 -0
  64. data/ext/cglm/cglm-0.6.2/include/cglm/struct/plane.h +40 -0
  65. data/ext/cglm/cglm-0.6.2/include/cglm/struct/project.h +104 -0
  66. data/ext/cglm/cglm-0.6.2/include/cglm/struct/quat.h +532 -0
  67. data/ext/cglm/cglm-0.6.2/include/cglm/struct/sphere.h +93 -0
  68. data/ext/cglm/cglm-0.6.2/include/cglm/struct/vec3-ext.h +257 -0
  69. data/ext/cglm/cglm-0.6.2/include/cglm/struct/vec3.h +970 -0
  70. data/ext/cglm/cglm-0.6.2/include/cglm/struct/vec4-ext.h +257 -0
  71. data/ext/cglm/cglm-0.6.2/include/cglm/struct/vec4.h +814 -0
  72. data/ext/cglm/cglm-0.6.2/include/cglm/struct.h +36 -0
  73. data/ext/cglm/cglm-0.6.2/include/cglm/types-struct.h +129 -0
  74. data/ext/cglm/cglm-0.6.2/include/cglm/types.h +76 -0
  75. data/ext/cglm/cglm-0.6.2/include/cglm/util.h +328 -0
  76. data/ext/cglm/cglm-0.6.2/include/cglm/vec3-ext.h +272 -0
  77. data/ext/cglm/cglm-0.6.2/include/cglm/vec3.h +1078 -0
  78. data/ext/cglm/cglm-0.6.2/include/cglm/vec4-ext.h +315 -0
  79. data/ext/cglm/cglm-0.6.2/include/cglm/vec4.h +1078 -0
  80. data/ext/cglm/cglm-0.6.2/include/cglm/version.h +15 -0
  81. data/ext/cglm/extconf.rb +2 -3
  82. data/ext/cglm/rb_cglm.h +5 -3
  83. data/ext/cglm/rb_cglm_mat3.c +3 -3
  84. data/ext/cglm/rb_cglm_mat4.c +3 -3
  85. data/ext/cglm/rb_cglm_quat.c +2 -2
  86. data/ext/cglm/rb_cglm_vec3.c +63 -61
  87. data/ext/cglm/rb_cglm_vec4.c +2 -0
  88. data/ext/cglm/ruby_pre27.h +35 -0
  89. data/lib/cglm/vec3.rb +2 -2
  90. data/lib/cglm/vec4.rb +2 -2
  91. data/lib/cglm/vector_type.rb +15 -0
  92. data/lib/cglm/version.rb +1 -1
  93. metadata +89 -13
@@ -0,0 +1,726 @@
1
+ /*
2
+ * Copyright (c), Recep Aslantas.
3
+ *
4
+ * MIT License (MIT), http://opensource.org/licenses/MIT
5
+ * Full license can be found in the LICENSE file
6
+ */
7
+
8
+ /*!
9
+ * Most of functions in this header are optimized manually with SIMD
10
+ * if available. You dont need to call/incude SIMD headers manually
11
+ */
12
+
13
+ /*
14
+ Macros:
15
+ GLM_MAT4_IDENTITY_INIT
16
+ GLM_MAT4_ZERO_INIT
17
+ GLM_MAT4_IDENTITY
18
+ GLM_MAT4_ZERO
19
+
20
+ Functions:
21
+ CGLM_INLINE void glm_mat4_ucopy(mat4 mat, mat4 dest);
22
+ CGLM_INLINE void glm_mat4_copy(mat4 mat, mat4 dest);
23
+ CGLM_INLINE void glm_mat4_identity(mat4 mat);
24
+ CGLM_INLINE void glm_mat4_identity_array(mat4 * restrict mat, size_t count);
25
+ CGLM_INLINE void glm_mat4_zero(mat4 mat);
26
+ CGLM_INLINE void glm_mat4_pick3(mat4 mat, mat3 dest);
27
+ CGLM_INLINE void glm_mat4_pick3t(mat4 mat, mat3 dest);
28
+ CGLM_INLINE void glm_mat4_ins3(mat3 mat, mat4 dest);
29
+ CGLM_INLINE void glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest);
30
+ CGLM_INLINE void glm_mat4_mulN(mat4 *matrices[], int len, mat4 dest);
31
+ CGLM_INLINE void glm_mat4_mulv(mat4 m, vec4 v, vec4 dest);
32
+ CGLM_INLINE void glm_mat4_mulv3(mat4 m, vec3 v, vec3 dest);
33
+ CGLM_INLINE float glm_mat4_trace(mat4 m);
34
+ CGLM_INLINE float glm_mat4_trace3(mat4 m);
35
+ CGLM_INLINE void glm_mat4_quat(mat4 m, versor dest) ;
36
+ CGLM_INLINE void glm_mat4_transpose_to(mat4 m, mat4 dest);
37
+ CGLM_INLINE void glm_mat4_transpose(mat4 m);
38
+ CGLM_INLINE void glm_mat4_scale_p(mat4 m, float s);
39
+ CGLM_INLINE void glm_mat4_scale(mat4 m, float s);
40
+ CGLM_INLINE float glm_mat4_det(mat4 mat);
41
+ CGLM_INLINE void glm_mat4_inv(mat4 mat, mat4 dest);
42
+ CGLM_INLINE void glm_mat4_inv_fast(mat4 mat, mat4 dest);
43
+ CGLM_INLINE void glm_mat4_swap_col(mat4 mat, int col1, int col2);
44
+ CGLM_INLINE void glm_mat4_swap_row(mat4 mat, int row1, int row2);
45
+ CGLM_INLINE float glm_mat4_rmc(vec4 r, mat4 m, vec4 c);
46
+ */
47
+
48
+ #ifndef cglm_mat_h
49
+ #define cglm_mat_h
50
+
51
+ #include "common.h"
52
+ #include "vec4.h"
53
+ #include "vec3.h"
54
+
55
+ #ifdef CGLM_SSE_FP
56
+ # include "simd/sse2/mat4.h"
57
+ #endif
58
+
59
+ #ifdef CGLM_AVX_FP
60
+ # include "simd/avx/mat4.h"
61
+ #endif
62
+
63
+ #ifdef CGLM_NEON_FP
64
+ # include "simd/neon/mat4.h"
65
+ #endif
66
+
67
+ #ifdef DEBUG
68
+ # include <assert.h>
69
+ #endif
70
+
71
+ #define GLM_MAT4_IDENTITY_INIT {{1.0f, 0.0f, 0.0f, 0.0f}, \
72
+ {0.0f, 1.0f, 0.0f, 0.0f}, \
73
+ {0.0f, 0.0f, 1.0f, 0.0f}, \
74
+ {0.0f, 0.0f, 0.0f, 1.0f}}
75
+
76
+ #define GLM_MAT4_ZERO_INIT {{0.0f, 0.0f, 0.0f, 0.0f}, \
77
+ {0.0f, 0.0f, 0.0f, 0.0f}, \
78
+ {0.0f, 0.0f, 0.0f, 0.0f}, \
79
+ {0.0f, 0.0f, 0.0f, 0.0f}}
80
+
81
+ /* for C only */
82
+ #define GLM_MAT4_IDENTITY ((mat4)GLM_MAT4_IDENTITY_INIT)
83
+ #define GLM_MAT4_ZERO ((mat4)GLM_MAT4_ZERO_INIT)
84
+
85
+ /* DEPRECATED! use _copy, _ucopy versions */
86
+ #define glm_mat4_udup(mat, dest) glm_mat4_ucopy(mat, dest)
87
+ #define glm_mat4_dup(mat, dest) glm_mat4_copy(mat, dest)
88
+
89
+ /* DEPRECATED! default is precise now. */
90
+ #define glm_mat4_inv_precise(mat, dest) glm_mat4_inv(mat, dest)
91
+
92
+ /*!
93
+ * @brief copy all members of [mat] to [dest]
94
+ *
95
+ * matrix may not be aligned, u stands for unaligned, this may be useful when
96
+ * copying a matrix from external source e.g. asset importer...
97
+ *
98
+ * @param[in] mat source
99
+ * @param[out] dest destination
100
+ */
101
+ CGLM_INLINE
102
+ void
103
+ glm_mat4_ucopy(mat4 mat, mat4 dest) {
104
+ dest[0][0] = mat[0][0]; dest[1][0] = mat[1][0];
105
+ dest[0][1] = mat[0][1]; dest[1][1] = mat[1][1];
106
+ dest[0][2] = mat[0][2]; dest[1][2] = mat[1][2];
107
+ dest[0][3] = mat[0][3]; dest[1][3] = mat[1][3];
108
+
109
+ dest[2][0] = mat[2][0]; dest[3][0] = mat[3][0];
110
+ dest[2][1] = mat[2][1]; dest[3][1] = mat[3][1];
111
+ dest[2][2] = mat[2][2]; dest[3][2] = mat[3][2];
112
+ dest[2][3] = mat[2][3]; dest[3][3] = mat[3][3];
113
+ }
114
+
115
+ /*!
116
+ * @brief copy all members of [mat] to [dest]
117
+ *
118
+ * @param[in] mat source
119
+ * @param[out] dest destination
120
+ */
121
+ CGLM_INLINE
122
+ void
123
+ glm_mat4_copy(mat4 mat, mat4 dest) {
124
+ #ifdef __AVX__
125
+ glmm_store256(dest[0], glmm_load256(mat[0]));
126
+ glmm_store256(dest[2], glmm_load256(mat[2]));
127
+ #elif defined( __SSE__ ) || defined( __SSE2__ )
128
+ glmm_store(dest[0], glmm_load(mat[0]));
129
+ glmm_store(dest[1], glmm_load(mat[1]));
130
+ glmm_store(dest[2], glmm_load(mat[2]));
131
+ glmm_store(dest[3], glmm_load(mat[3]));
132
+ #elif defined(CGLM_NEON_FP)
133
+ vst1q_f32(dest[0], vld1q_f32(mat[0]));
134
+ vst1q_f32(dest[1], vld1q_f32(mat[1]));
135
+ vst1q_f32(dest[2], vld1q_f32(mat[2]));
136
+ vst1q_f32(dest[3], vld1q_f32(mat[3]));
137
+ #else
138
+ glm_mat4_ucopy(mat, dest);
139
+ #endif
140
+ }
141
+
142
+ /*!
143
+ * @brief make given matrix identity. It is identical with below,
144
+ * but it is more easy to do that with this func especially for members
145
+ * e.g. glm_mat4_identity(aStruct->aMatrix);
146
+ *
147
+ * @code
148
+ * glm_mat4_copy(GLM_MAT4_IDENTITY, mat); // C only
149
+ *
150
+ * // or
151
+ * mat4 mat = GLM_MAT4_IDENTITY_INIT;
152
+ * @endcode
153
+ *
154
+ * @param[in, out] mat destination
155
+ */
156
+ CGLM_INLINE
157
+ void
158
+ glm_mat4_identity(mat4 mat) {
159
+ CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
160
+ glm_mat4_copy(t, mat);
161
+ }
162
+
163
+ /*!
164
+ * @brief make given matrix array's each element identity matrix
165
+ *
166
+ * @param[in, out] mat matrix array (must be aligned (16/32)
167
+ * if alignment is not disabled)
168
+ *
169
+ * @param[in] count count of matrices
170
+ */
171
+ CGLM_INLINE
172
+ void
173
+ glm_mat4_identity_array(mat4 * __restrict mat, size_t count) {
174
+ CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
175
+ size_t i;
176
+
177
+ for (i = 0; i < count; i++) {
178
+ glm_mat4_copy(t, mat[i]);
179
+ }
180
+ }
181
+
182
+ /*!
183
+ * @brief make given matrix zero.
184
+ *
185
+ * @param[in, out] mat matrix
186
+ */
187
+ CGLM_INLINE
188
+ void
189
+ glm_mat4_zero(mat4 mat) {
190
+ CGLM_ALIGN_MAT mat4 t = GLM_MAT4_ZERO_INIT;
191
+ glm_mat4_copy(t, mat);
192
+ }
193
+
194
+ /*!
195
+ * @brief copy upper-left of mat4 to mat3
196
+ *
197
+ * @param[in] mat source
198
+ * @param[out] dest destination
199
+ */
200
+ CGLM_INLINE
201
+ void
202
+ glm_mat4_pick3(mat4 mat, mat3 dest) {
203
+ dest[0][0] = mat[0][0];
204
+ dest[0][1] = mat[0][1];
205
+ dest[0][2] = mat[0][2];
206
+
207
+ dest[1][0] = mat[1][0];
208
+ dest[1][1] = mat[1][1];
209
+ dest[1][2] = mat[1][2];
210
+
211
+ dest[2][0] = mat[2][0];
212
+ dest[2][1] = mat[2][1];
213
+ dest[2][2] = mat[2][2];
214
+ }
215
+
216
+ /*!
217
+ * @brief copy upper-left of mat4 to mat3 (transposed)
218
+ *
219
+ * the postfix t stands for transpose
220
+ *
221
+ * @param[in] mat source
222
+ * @param[out] dest destination
223
+ */
224
+ CGLM_INLINE
225
+ void
226
+ glm_mat4_pick3t(mat4 mat, mat3 dest) {
227
+ dest[0][0] = mat[0][0];
228
+ dest[0][1] = mat[1][0];
229
+ dest[0][2] = mat[2][0];
230
+
231
+ dest[1][0] = mat[0][1];
232
+ dest[1][1] = mat[1][1];
233
+ dest[1][2] = mat[2][1];
234
+
235
+ dest[2][0] = mat[0][2];
236
+ dest[2][1] = mat[1][2];
237
+ dest[2][2] = mat[2][2];
238
+ }
239
+
240
+ /*!
241
+ * @brief copy mat3 to mat4's upper-left
242
+ *
243
+ * @param[in] mat source
244
+ * @param[out] dest destination
245
+ */
246
+ CGLM_INLINE
247
+ void
248
+ glm_mat4_ins3(mat3 mat, mat4 dest) {
249
+ dest[0][0] = mat[0][0];
250
+ dest[0][1] = mat[0][1];
251
+ dest[0][2] = mat[0][2];
252
+
253
+ dest[1][0] = mat[1][0];
254
+ dest[1][1] = mat[1][1];
255
+ dest[1][2] = mat[1][2];
256
+
257
+ dest[2][0] = mat[2][0];
258
+ dest[2][1] = mat[2][1];
259
+ dest[2][2] = mat[2][2];
260
+ }
261
+
262
+ /*!
263
+ * @brief multiply m1 and m2 to dest
264
+ *
265
+ * m1, m2 and dest matrices can be same matrix, it is possible to write this:
266
+ *
267
+ * @code
268
+ * mat4 m = GLM_MAT4_IDENTITY_INIT;
269
+ * glm_mat4_mul(m, m, m);
270
+ * @endcode
271
+ *
272
+ * @param[in] m1 left matrix
273
+ * @param[in] m2 right matrix
274
+ * @param[out] dest destination matrix
275
+ */
276
+ CGLM_INLINE
277
+ void
278
+ glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest) {
279
+ #ifdef __AVX__
280
+ glm_mat4_mul_avx(m1, m2, dest);
281
+ #elif defined( __SSE__ ) || defined( __SSE2__ )
282
+ glm_mat4_mul_sse2(m1, m2, dest);
283
+ #elif defined(CGLM_NEON_FP)
284
+ glm_mat4_mul_neon(m1, m2, dest);
285
+ #else
286
+ float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3],
287
+ a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3],
288
+ a20 = m1[2][0], a21 = m1[2][1], a22 = m1[2][2], a23 = m1[2][3],
289
+ a30 = m1[3][0], a31 = m1[3][1], a32 = m1[3][2], a33 = m1[3][3],
290
+
291
+ b00 = m2[0][0], b01 = m2[0][1], b02 = m2[0][2], b03 = m2[0][3],
292
+ b10 = m2[1][0], b11 = m2[1][1], b12 = m2[1][2], b13 = m2[1][3],
293
+ b20 = m2[2][0], b21 = m2[2][1], b22 = m2[2][2], b23 = m2[2][3],
294
+ b30 = m2[3][0], b31 = m2[3][1], b32 = m2[3][2], b33 = m2[3][3];
295
+
296
+ dest[0][0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03;
297
+ dest[0][1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03;
298
+ dest[0][2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03;
299
+ dest[0][3] = a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03;
300
+ dest[1][0] = a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13;
301
+ dest[1][1] = a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13;
302
+ dest[1][2] = a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13;
303
+ dest[1][3] = a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13;
304
+ dest[2][0] = a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23;
305
+ dest[2][1] = a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23;
306
+ dest[2][2] = a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23;
307
+ dest[2][3] = a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23;
308
+ dest[3][0] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33;
309
+ dest[3][1] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33;
310
+ dest[3][2] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33;
311
+ dest[3][3] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33;
312
+ #endif
313
+ }
314
+
315
+ /*!
316
+ * @brief mupliply N mat4 matrices and store result in dest
317
+ *
318
+ * this function lets you multiply multiple (more than two or more...) matrices
319
+ * <br><br>multiplication will be done in loop, this may reduce instructions
320
+ * size but if <b>len</b> is too small then compiler may unroll whole loop,
321
+ * usage:
322
+ * @code
323
+ * mat m1, m2, m3, m4, res;
324
+ *
325
+ * glm_mat4_mulN((mat4 *[]){&m1, &m2, &m3, &m4}, 4, res);
326
+ * @endcode
327
+ *
328
+ * @warning matrices parameter is pointer array not mat4 array!
329
+ *
330
+ * @param[in] matrices mat4 * array
331
+ * @param[in] len matrices count
332
+ * @param[out] dest result
333
+ */
334
+ CGLM_INLINE
335
+ void
336
+ glm_mat4_mulN(mat4 * __restrict matrices[], uint32_t len, mat4 dest) {
337
+ uint32_t i;
338
+
339
+ #ifdef DEBUG
340
+ assert(len > 1 && "there must be least 2 matrices to go!");
341
+ #endif
342
+
343
+ glm_mat4_mul(*matrices[0], *matrices[1], dest);
344
+
345
+ for (i = 2; i < len; i++)
346
+ glm_mat4_mul(dest, *matrices[i], dest);
347
+ }
348
+
349
+ /*!
350
+ * @brief multiply mat4 with vec4 (column vector) and store in dest vector
351
+ *
352
+ * @param[in] m mat4 (left)
353
+ * @param[in] v vec4 (right, column vector)
354
+ * @param[out] dest vec4 (result, column vector)
355
+ */
356
+ CGLM_INLINE
357
+ void
358
+ glm_mat4_mulv(mat4 m, vec4 v, vec4 dest) {
359
+ #if defined( __SSE__ ) || defined( __SSE2__ )
360
+ glm_mat4_mulv_sse2(m, v, dest);
361
+ #else
362
+ vec4 res;
363
+ res[0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0] * v[3];
364
+ res[1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1] * v[3];
365
+ res[2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2] * v[3];
366
+ res[3] = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3] * v[3];
367
+ glm_vec4_copy(res, dest);
368
+ #endif
369
+ }
370
+
371
+ /*!
372
+ * @brief trace of matrix
373
+ *
374
+ * sum of the elements on the main diagonal from upper left to the lower right
375
+ *
376
+ * @param[in] m matrix
377
+ */
378
+ CGLM_INLINE
379
+ float
380
+ glm_mat4_trace(mat4 m) {
381
+ return m[0][0] + m[1][1] + m[2][2] + m[3][3];
382
+ }
383
+
384
+ /*!
385
+ * @brief trace of matrix (rotation part)
386
+ *
387
+ * sum of the elements on the main diagonal from upper left to the lower right
388
+ *
389
+ * @param[in] m matrix
390
+ */
391
+ CGLM_INLINE
392
+ float
393
+ glm_mat4_trace3(mat4 m) {
394
+ return m[0][0] + m[1][1] + m[2][2];
395
+ }
396
+
397
+ /*!
398
+ * @brief convert mat4's rotation part to quaternion
399
+ *
400
+ * @param[in] m affine matrix
401
+ * @param[out] dest destination quaternion
402
+ */
403
+ CGLM_INLINE
404
+ void
405
+ glm_mat4_quat(mat4 m, versor dest) {
406
+ float trace, r, rinv;
407
+
408
+ /* it seems using like m12 instead of m[1][2] causes extra instructions */
409
+
410
+ trace = m[0][0] + m[1][1] + m[2][2];
411
+ if (trace >= 0.0f) {
412
+ r = sqrtf(1.0f + trace);
413
+ rinv = 0.5f / r;
414
+
415
+ dest[0] = rinv * (m[1][2] - m[2][1]);
416
+ dest[1] = rinv * (m[2][0] - m[0][2]);
417
+ dest[2] = rinv * (m[0][1] - m[1][0]);
418
+ dest[3] = r * 0.5f;
419
+ } else if (m[0][0] >= m[1][1] && m[0][0] >= m[2][2]) {
420
+ r = sqrtf(1.0f - m[1][1] - m[2][2] + m[0][0]);
421
+ rinv = 0.5f / r;
422
+
423
+ dest[0] = r * 0.5f;
424
+ dest[1] = rinv * (m[0][1] + m[1][0]);
425
+ dest[2] = rinv * (m[0][2] + m[2][0]);
426
+ dest[3] = rinv * (m[1][2] - m[2][1]);
427
+ } else if (m[1][1] >= m[2][2]) {
428
+ r = sqrtf(1.0f - m[0][0] - m[2][2] + m[1][1]);
429
+ rinv = 0.5f / r;
430
+
431
+ dest[0] = rinv * (m[0][1] + m[1][0]);
432
+ dest[1] = r * 0.5f;
433
+ dest[2] = rinv * (m[1][2] + m[2][1]);
434
+ dest[3] = rinv * (m[2][0] - m[0][2]);
435
+ } else {
436
+ r = sqrtf(1.0f - m[0][0] - m[1][1] + m[2][2]);
437
+ rinv = 0.5f / r;
438
+
439
+ dest[0] = rinv * (m[0][2] + m[2][0]);
440
+ dest[1] = rinv * (m[1][2] + m[2][1]);
441
+ dest[2] = r * 0.5f;
442
+ dest[3] = rinv * (m[0][1] - m[1][0]);
443
+ }
444
+ }
445
+
446
+ /*!
447
+ * @brief multiply vector with mat4
448
+ *
449
+ * actually the result is vec4, after multiplication the last component
450
+ * is trimmed. if you need it don't use this func.
451
+ *
452
+ * @param[in] m mat4(affine transform)
453
+ * @param[in] v vec3
454
+ * @param[in] last 4th item to make it vec4
455
+ * @param[out] dest result vector (vec3)
456
+ */
457
+ CGLM_INLINE
458
+ void
459
+ glm_mat4_mulv3(mat4 m, vec3 v, float last, vec3 dest) {
460
+ vec4 res;
461
+ glm_vec4(v, last, res);
462
+ glm_mat4_mulv(m, res, res);
463
+ glm_vec3(res, dest);
464
+ }
465
+
466
+ /*!
467
+ * @brief transpose mat4 and store in dest
468
+ *
469
+ * source matrix will not be transposed unless dest is m
470
+ *
471
+ * @param[in] m matrix
472
+ * @param[out] dest result
473
+ */
474
+ CGLM_INLINE
475
+ void
476
+ glm_mat4_transpose_to(mat4 m, mat4 dest) {
477
+ #if defined( __SSE__ ) || defined( __SSE2__ )
478
+ glm_mat4_transp_sse2(m, dest);
479
+ #else
480
+ dest[0][0] = m[0][0]; dest[1][0] = m[0][1];
481
+ dest[0][1] = m[1][0]; dest[1][1] = m[1][1];
482
+ dest[0][2] = m[2][0]; dest[1][2] = m[2][1];
483
+ dest[0][3] = m[3][0]; dest[1][3] = m[3][1];
484
+ dest[2][0] = m[0][2]; dest[3][0] = m[0][3];
485
+ dest[2][1] = m[1][2]; dest[3][1] = m[1][3];
486
+ dest[2][2] = m[2][2]; dest[3][2] = m[2][3];
487
+ dest[2][3] = m[3][2]; dest[3][3] = m[3][3];
488
+ #endif
489
+ }
490
+
491
+ /*!
492
+ * @brief tranpose mat4 and store result in same matrix
493
+ *
494
+ * @param[in, out] m source and dest
495
+ */
496
+ CGLM_INLINE
497
+ void
498
+ glm_mat4_transpose(mat4 m) {
499
+ #if defined( __SSE__ ) || defined( __SSE2__ )
500
+ glm_mat4_transp_sse2(m, m);
501
+ #else
502
+ mat4 d;
503
+ glm_mat4_transpose_to(m, d);
504
+ glm_mat4_ucopy(d, m);
505
+ #endif
506
+ }
507
+
508
+ /*!
509
+ * @brief scale (multiply with scalar) matrix without simd optimization
510
+ *
511
+ * multiply matrix with scalar
512
+ *
513
+ * @param[in, out] m matrix
514
+ * @param[in] s scalar
515
+ */
516
+ CGLM_INLINE
517
+ void
518
+ glm_mat4_scale_p(mat4 m, float s) {
519
+ m[0][0] *= s; m[0][1] *= s; m[0][2] *= s; m[0][3] *= s;
520
+ m[1][0] *= s; m[1][1] *= s; m[1][2] *= s; m[1][3] *= s;
521
+ m[2][0] *= s; m[2][1] *= s; m[2][2] *= s; m[2][3] *= s;
522
+ m[3][0] *= s; m[3][1] *= s; m[3][2] *= s; m[3][3] *= s;
523
+ }
524
+
525
+ /*!
526
+ * @brief scale (multiply with scalar) matrix
527
+ *
528
+ * multiply matrix with scalar
529
+ *
530
+ * @param[in, out] m matrix
531
+ * @param[in] s scalar
532
+ */
533
+ CGLM_INLINE
534
+ void
535
+ glm_mat4_scale(mat4 m, float s) {
536
+ #if defined( __SSE__ ) || defined( __SSE2__ )
537
+ glm_mat4_scale_sse2(m, s);
538
+ #elif defined(CGLM_NEON_FP)
539
+ float32x4_t v0;
540
+ v0 = vdupq_n_f32(s);
541
+ vst1q_f32(m[0], vmulq_f32(vld1q_f32(m[0]), v0));
542
+ vst1q_f32(m[1], vmulq_f32(vld1q_f32(m[1]), v0));
543
+ vst1q_f32(m[2], vmulq_f32(vld1q_f32(m[2]), v0));
544
+ vst1q_f32(m[3], vmulq_f32(vld1q_f32(m[3]), v0));
545
+ #else
546
+ glm_mat4_scale_p(m, s);
547
+ #endif
548
+ }
549
+
550
+ /*!
551
+ * @brief mat4 determinant
552
+ *
553
+ * @param[in] mat matrix
554
+ *
555
+ * @return determinant
556
+ */
557
+ CGLM_INLINE
558
+ float
559
+ glm_mat4_det(mat4 mat) {
560
+ #if defined( __SSE__ ) || defined( __SSE2__ )
561
+ return glm_mat4_det_sse2(mat);
562
+ #else
563
+ /* [square] det(A) = det(At) */
564
+ float t[6];
565
+ float a = mat[0][0], b = mat[0][1], c = mat[0][2], d = mat[0][3],
566
+ e = mat[1][0], f = mat[1][1], g = mat[1][2], h = mat[1][3],
567
+ i = mat[2][0], j = mat[2][1], k = mat[2][2], l = mat[2][3],
568
+ m = mat[3][0], n = mat[3][1], o = mat[3][2], p = mat[3][3];
569
+
570
+ t[0] = k * p - o * l;
571
+ t[1] = j * p - n * l;
572
+ t[2] = j * o - n * k;
573
+ t[3] = i * p - m * l;
574
+ t[4] = i * o - m * k;
575
+ t[5] = i * n - m * j;
576
+
577
+ return a * (f * t[0] - g * t[1] + h * t[2])
578
+ - b * (e * t[0] - g * t[3] + h * t[4])
579
+ + c * (e * t[1] - f * t[3] + h * t[5])
580
+ - d * (e * t[2] - f * t[4] + g * t[5]);
581
+ #endif
582
+ }
583
+
584
+ /*!
585
+ * @brief inverse mat4 and store in dest
586
+ *
587
+ * @param[in] mat matrix
588
+ * @param[out] dest inverse matrix
589
+ */
590
+ CGLM_INLINE
591
+ void
592
+ glm_mat4_inv(mat4 mat, mat4 dest) {
593
+ #if defined( __SSE__ ) || defined( __SSE2__ )
594
+ glm_mat4_inv_sse2(mat, dest);
595
+ #else
596
+ float t[6];
597
+ float det;
598
+ float a = mat[0][0], b = mat[0][1], c = mat[0][2], d = mat[0][3],
599
+ e = mat[1][0], f = mat[1][1], g = mat[1][2], h = mat[1][3],
600
+ i = mat[2][0], j = mat[2][1], k = mat[2][2], l = mat[2][3],
601
+ m = mat[3][0], n = mat[3][1], o = mat[3][2], p = mat[3][3];
602
+
603
+ t[0] = k * p - o * l; t[1] = j * p - n * l; t[2] = j * o - n * k;
604
+ t[3] = i * p - m * l; t[4] = i * o - m * k; t[5] = i * n - m * j;
605
+
606
+ dest[0][0] = f * t[0] - g * t[1] + h * t[2];
607
+ dest[1][0] =-(e * t[0] - g * t[3] + h * t[4]);
608
+ dest[2][0] = e * t[1] - f * t[3] + h * t[5];
609
+ dest[3][0] =-(e * t[2] - f * t[4] + g * t[5]);
610
+
611
+ dest[0][1] =-(b * t[0] - c * t[1] + d * t[2]);
612
+ dest[1][1] = a * t[0] - c * t[3] + d * t[4];
613
+ dest[2][1] =-(a * t[1] - b * t[3] + d * t[5]);
614
+ dest[3][1] = a * t[2] - b * t[4] + c * t[5];
615
+
616
+ t[0] = g * p - o * h; t[1] = f * p - n * h; t[2] = f * o - n * g;
617
+ t[3] = e * p - m * h; t[4] = e * o - m * g; t[5] = e * n - m * f;
618
+
619
+ dest[0][2] = b * t[0] - c * t[1] + d * t[2];
620
+ dest[1][2] =-(a * t[0] - c * t[3] + d * t[4]);
621
+ dest[2][2] = a * t[1] - b * t[3] + d * t[5];
622
+ dest[3][2] =-(a * t[2] - b * t[4] + c * t[5]);
623
+
624
+ t[0] = g * l - k * h; t[1] = f * l - j * h; t[2] = f * k - j * g;
625
+ t[3] = e * l - i * h; t[4] = e * k - i * g; t[5] = e * j - i * f;
626
+
627
+ dest[0][3] =-(b * t[0] - c * t[1] + d * t[2]);
628
+ dest[1][3] = a * t[0] - c * t[3] + d * t[4];
629
+ dest[2][3] =-(a * t[1] - b * t[3] + d * t[5]);
630
+ dest[3][3] = a * t[2] - b * t[4] + c * t[5];
631
+
632
+ det = 1.0f / (a * dest[0][0] + b * dest[1][0]
633
+ + c * dest[2][0] + d * dest[3][0]);
634
+
635
+ glm_mat4_scale_p(dest, det);
636
+ #endif
637
+ }
638
+
639
+ /*!
640
+ * @brief inverse mat4 and store in dest
641
+ *
642
+ * this func uses reciprocal approximation without extra corrections
643
+ * e.g Newton-Raphson. this should work faster than normal,
644
+ * to get more precise use glm_mat4_inv version.
645
+ *
646
+ * NOTE: You will lose precision, glm_mat4_inv is more accurate
647
+ *
648
+ * @param[in] mat matrix
649
+ * @param[out] dest inverse matrix
650
+ */
651
+ CGLM_INLINE
652
+ void
653
+ glm_mat4_inv_fast(mat4 mat, mat4 dest) {
654
+ #if defined( __SSE__ ) || defined( __SSE2__ )
655
+ glm_mat4_inv_fast_sse2(mat, dest);
656
+ #else
657
+ glm_mat4_inv(mat, dest);
658
+ #endif
659
+ }
660
+
661
+ /*!
662
+ * @brief swap two matrix columns
663
+ *
664
+ * @param[in,out] mat matrix
665
+ * @param[in] col1 col1
666
+ * @param[in] col2 col2
667
+ */
668
+ CGLM_INLINE
669
+ void
670
+ glm_mat4_swap_col(mat4 mat, int col1, int col2) {
671
+ CGLM_ALIGN(16) vec4 tmp;
672
+ glm_vec4_copy(mat[col1], tmp);
673
+ glm_vec4_copy(mat[col2], mat[col1]);
674
+ glm_vec4_copy(tmp, mat[col2]);
675
+ }
676
+
677
+ /*!
678
+ * @brief swap two matrix rows
679
+ *
680
+ * @param[in,out] mat matrix
681
+ * @param[in] row1 row1
682
+ * @param[in] row2 row2
683
+ */
684
+ CGLM_INLINE
685
+ void
686
+ glm_mat4_swap_row(mat4 mat, int row1, int row2) {
687
+ CGLM_ALIGN(16) vec4 tmp;
688
+ tmp[0] = mat[0][row1];
689
+ tmp[1] = mat[1][row1];
690
+ tmp[2] = mat[2][row1];
691
+ tmp[3] = mat[3][row1];
692
+
693
+ mat[0][row1] = mat[0][row2];
694
+ mat[1][row1] = mat[1][row2];
695
+ mat[2][row1] = mat[2][row2];
696
+ mat[3][row1] = mat[3][row2];
697
+
698
+ mat[0][row2] = tmp[0];
699
+ mat[1][row2] = tmp[1];
700
+ mat[2][row2] = tmp[2];
701
+ mat[3][row2] = tmp[3];
702
+ }
703
+
704
+ /*!
705
+ * @brief helper for R (row vector) * M (matrix) * C (column vector)
706
+ *
707
+ * rmc stands for Row * Matrix * Column
708
+ *
709
+ * the result is scalar because R * M = Matrix1x4 (row vector),
710
+ * then Matrix1x4 * Vec4 (column vector) = Matrix1x1 (Scalar)
711
+ *
712
+ * @param[in] r row vector or matrix1x4
713
+ * @param[in] m matrix4x4
714
+ * @param[in] c column vector or matrix4x1
715
+ *
716
+ * @return scalar value e.g. B(s)
717
+ */
718
+ CGLM_INLINE
719
+ float
720
+ glm_mat4_rmc(vec4 r, mat4 m, vec4 c) {
721
+ vec4 tmp;
722
+ glm_mat4_mulv(m, c, tmp);
723
+ return glm_vec4_dot(r, tmp);
724
+ }
725
+
726
+ #endif /* cglm_mat_h */