cglm 0.1.0 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/Gemfile.lock +18 -16
- data/README.md +2 -0
- data/cglm.gemspec +3 -3
- data/ext/cglm/cglm-0.6.2/include/cglm/affine-mat.h +168 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/affine.h +490 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/applesimd.h +95 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/bezier.h +154 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/box.h +279 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/affine.h +117 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/bezier.h +31 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/box.h +79 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/cam.h +143 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/curve.h +23 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/ease.h +143 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/euler.h +55 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/frustum.h +41 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/io.h +44 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/mat3.h +86 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/mat4.h +127 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/plane.h +23 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/project.h +33 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/quat.h +159 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/sphere.h +39 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/vec3.h +312 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call/vec4.h +290 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/call.h +36 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/cam.h +585 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/cglm.h +32 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/color.h +26 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/common.h +37 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/curve.h +40 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/ease.h +317 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/euler.h +453 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/frustum.h +255 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/io.h +203 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/mat3.h +422 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/mat4.h +726 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/plane.h +36 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/project.h +118 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/quat.h +828 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/simd/arm.h +83 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/simd/avx/affine.h +66 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/simd/avx/mat4.h +66 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/simd/intrin.h +90 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/simd/neon/mat4.h +57 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/simd/sse2/affine.h +111 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/simd/sse2/mat3.h +59 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/simd/sse2/mat4.h +405 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/simd/sse2/quat.h +46 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/simd/x86.h +192 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/sphere.h +99 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/affine.h +337 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/box.h +256 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/cam.h +451 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/color.h +27 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/curve.h +40 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/euler.h +152 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/frustum.h +155 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/io.h +82 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/mat3.h +285 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/mat4.h +459 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/plane.h +40 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/project.h +104 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/quat.h +532 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/sphere.h +93 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/vec3-ext.h +257 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/vec3.h +970 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/vec4-ext.h +257 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct/vec4.h +814 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/struct.h +36 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/types-struct.h +129 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/types.h +76 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/util.h +328 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/vec3-ext.h +272 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/vec3.h +1078 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/vec4-ext.h +315 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/vec4.h +1078 -0
- data/ext/cglm/cglm-0.6.2/include/cglm/version.h +15 -0
- data/ext/cglm/extconf.rb +2 -3
- data/ext/cglm/rb_cglm.h +5 -3
- data/ext/cglm/rb_cglm_mat3.c +3 -3
- data/ext/cglm/rb_cglm_mat4.c +3 -3
- data/ext/cglm/rb_cglm_quat.c +2 -2
- data/ext/cglm/rb_cglm_vec3.c +63 -61
- data/ext/cglm/rb_cglm_vec4.c +2 -0
- data/ext/cglm/ruby_pre27.h +35 -0
- data/lib/cglm/vec3.rb +2 -2
- data/lib/cglm/vec4.rb +2 -2
- data/lib/cglm/vector_type.rb +15 -0
- data/lib/cglm/version.rb +1 -1
- 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 */
|