snow-math 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/extconf.rb +17 -0
- data/ext/snow-math/mat4.c +739 -0
- data/ext/snow-math/maths.c +2 -0
- data/ext/snow-math/maths_local.h +257 -0
- data/ext/snow-math/quat.c +187 -0
- data/ext/snow-math/snow-math.c +2117 -0
- data/ext/snow-math/vec3.c +144 -0
- data/ext/snow-math/vec4.c +145 -0
- data/lib/snow-math.rb +14 -0
- data/lib/snow-math/inspect.rb +20 -0
- data/lib/snow-math/line.rb +0 -0
- data/lib/snow-math/mat3.rb +0 -0
- data/lib/snow-math/mat4.rb +80 -0
- data/lib/snow-math/plane.rb +0 -0
- data/lib/snow-math/ptr.rb +25 -0
- data/lib/snow-math/quat.rb +114 -0
- data/lib/snow-math/swizzle.rb +57 -0
- data/lib/snow-math/to_a.rb +51 -0
- data/lib/snow-math/vec2.rb +0 -0
- data/lib/snow-math/vec3.rb +111 -0
- data/lib/snow-math/vec4.rb +113 -0
- metadata +71 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 19a3f42ccb51ce6b8f3ce302da01828ccf1b9456
|
4
|
+
data.tar.gz: cd4fea9cddf77d8e9d3b3656eb428101aff96786
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 937dc344b4c8c9925b014faf86fd6edccd93e010dbbf344c83e2c302f310baa1c97a7aa73f02f34ee97497a75a80d78e4932064083c685d124861169d9ef003a
|
7
|
+
data.tar.gz: d3113bcfacd41fe382c6f89c3fbd4e320344d60b7eb26c64bceab5d551986677217f9a284457098789377afef9817bc62ffa787d793c58179ad4afd89ba74453
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#! /usr/bin/env ruby -w
|
2
|
+
# This file is part of ruby-snowmath.
|
3
|
+
# Copyright (c) 2013 Noel Raymond Cower. All rights reserved.
|
4
|
+
# See COPYING for license details.
|
5
|
+
|
6
|
+
require 'mkmf'
|
7
|
+
|
8
|
+
if ARGV.include?("--use-float") || ARGV.include?("-F")
|
9
|
+
$CFLAGS += " -DUSE_FLOAT"
|
10
|
+
puts "Using float as base type"
|
11
|
+
else
|
12
|
+
puts "Using double as base type"
|
13
|
+
end
|
14
|
+
|
15
|
+
have_library('m', 'cos')
|
16
|
+
|
17
|
+
create_makefile('snow-math/bindings', 'snow-math/')
|
@@ -0,0 +1,739 @@
|
|
1
|
+
/*
|
2
|
+
Transformation matrix
|
3
|
+
Written by Noel Cower
|
4
|
+
|
5
|
+
See COPYING for license information
|
6
|
+
*/
|
7
|
+
|
8
|
+
#define __SNOW__MAT4_C__
|
9
|
+
|
10
|
+
#include "maths_local.h"
|
11
|
+
|
12
|
+
#if defined(__cplusplus)
|
13
|
+
extern "C"
|
14
|
+
{
|
15
|
+
#endif /* __cplusplus */
|
16
|
+
|
17
|
+
/* reference:
|
18
|
+
x y z w
|
19
|
+
0 1 2 3
|
20
|
+
4 5 6 7
|
21
|
+
8 9 10 11
|
22
|
+
12 13 14 15
|
23
|
+
*/
|
24
|
+
|
25
|
+
const mat4_t g_mat4_identity = {
|
26
|
+
1.0, 0.0, 0.0, 0.0,
|
27
|
+
0.0, 1.0, 0.0, 0.0,
|
28
|
+
0.0, 0.0, 1.0, 0.0,
|
29
|
+
0.0, 0.0, 0.0, 1.0
|
30
|
+
};
|
31
|
+
|
32
|
+
static inline s_float_t mat4_cofactor(const mat4_t m, int r0, int r1, int r2, int c0, int c1, int c2);
|
33
|
+
|
34
|
+
void mat4_identity(mat4_t out)
|
35
|
+
{
|
36
|
+
out[0] = out[5] = out[10] = out[15] = 1.0;
|
37
|
+
out[1] = out[2] = out[3] =
|
38
|
+
out[4] = out[6] = out[7] =
|
39
|
+
out[8] = out[9] = out[11] =
|
40
|
+
out[12] = out[13] = out[14] = 0.0;
|
41
|
+
}
|
42
|
+
|
43
|
+
void mat4_copy(const mat4_t in, mat4_t out)
|
44
|
+
{
|
45
|
+
if (in != out) {
|
46
|
+
int index = 0;
|
47
|
+
for (; index < 16; ++index) out[index] = in[index];
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
void mat4_set(
|
52
|
+
s_float_t m00, s_float_t m01, s_float_t m02, s_float_t m03,
|
53
|
+
s_float_t m04, s_float_t m05, s_float_t m06, s_float_t m07,
|
54
|
+
s_float_t m08, s_float_t m09, s_float_t m10, s_float_t m11,
|
55
|
+
s_float_t m12, s_float_t m13, s_float_t m14, s_float_t m15,
|
56
|
+
mat4_t out)
|
57
|
+
{
|
58
|
+
out[0 ] = m00;
|
59
|
+
out[1 ] = m01;
|
60
|
+
out[2 ] = m02;
|
61
|
+
out[3 ] = m03;
|
62
|
+
out[4 ] = m04;
|
63
|
+
out[5 ] = m05;
|
64
|
+
out[6 ] = m06;
|
65
|
+
out[7 ] = m07;
|
66
|
+
out[8 ] = m08;
|
67
|
+
out[9 ] = m09;
|
68
|
+
out[10] = m10;
|
69
|
+
out[11] = m11;
|
70
|
+
out[12] = m12;
|
71
|
+
out[13] = m13;
|
72
|
+
out[14] = m14;
|
73
|
+
out[15] = m15;
|
74
|
+
}
|
75
|
+
|
76
|
+
void mat4_set_axes3(const vec3_t x, const vec3_t y, const vec3_t z, const vec3_t w, mat4_t out)
|
77
|
+
{
|
78
|
+
out[0] = x[0];
|
79
|
+
out[4] = x[1];
|
80
|
+
out[8] = x[2];
|
81
|
+
|
82
|
+
out[1] = y[0];
|
83
|
+
out[5] = y[1];
|
84
|
+
out[9] = y[2];
|
85
|
+
|
86
|
+
out[2] = z[0];
|
87
|
+
out[6] = z[1];
|
88
|
+
out[10] = z[2];
|
89
|
+
|
90
|
+
out[3] = w[0];
|
91
|
+
out[7] = w[1];
|
92
|
+
out[11] = w[2];
|
93
|
+
|
94
|
+
out[12] = out[13] = out[14] = 0.0;
|
95
|
+
out[15] = 1.0;
|
96
|
+
}
|
97
|
+
|
98
|
+
void mat4_get_axes3(const mat4_t m, vec3_t x, vec3_t y, vec3_t z, vec3_t w)
|
99
|
+
{
|
100
|
+
if (x) {
|
101
|
+
x[0] = m[0];
|
102
|
+
x[1] = m[4];
|
103
|
+
x[2] = m[8];
|
104
|
+
}
|
105
|
+
|
106
|
+
if (y) {
|
107
|
+
y[0] = m[1];
|
108
|
+
y[1] = m[5];
|
109
|
+
y[2] = m[9];
|
110
|
+
}
|
111
|
+
|
112
|
+
if (z) {
|
113
|
+
z[0] = m[2];
|
114
|
+
z[1] = m[6];
|
115
|
+
z[2] = m[10];
|
116
|
+
}
|
117
|
+
|
118
|
+
if (w) {
|
119
|
+
w[0] = m[3];
|
120
|
+
w[1] = m[7];
|
121
|
+
w[2] = m[11];
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
void mat4_set_axes4(const vec4_t x, const vec4_t y, const vec4_t z, const vec4_t w, mat4_t out)
|
126
|
+
{
|
127
|
+
out[0] = x[0];
|
128
|
+
out[4] = x[1];
|
129
|
+
out[8] = x[2];
|
130
|
+
out[12] = x[3];
|
131
|
+
|
132
|
+
out[1] = y[0];
|
133
|
+
out[5] = y[1];
|
134
|
+
out[9] = y[2];
|
135
|
+
out[13] = y[3];
|
136
|
+
|
137
|
+
out[2] = z[0];
|
138
|
+
out[6] = z[1];
|
139
|
+
out[10] = z[2];
|
140
|
+
out[14] = z[3];
|
141
|
+
|
142
|
+
out[3] = w[0];
|
143
|
+
out[7] = w[1];
|
144
|
+
out[11] = w[2];
|
145
|
+
out[15] = w[3];
|
146
|
+
}
|
147
|
+
|
148
|
+
void mat4_get_axes4(const mat4_t m, vec4_t x, vec4_t y, vec4_t z, vec4_t w)
|
149
|
+
{
|
150
|
+
if (x) {
|
151
|
+
x[0] = m[0];
|
152
|
+
x[1] = m[4];
|
153
|
+
x[2] = m[8];
|
154
|
+
x[3] = m[12];
|
155
|
+
}
|
156
|
+
|
157
|
+
if (y) {
|
158
|
+
y[0] = m[1];
|
159
|
+
y[1] = m[5];
|
160
|
+
y[2] = m[9];
|
161
|
+
y[3] = m[13];
|
162
|
+
}
|
163
|
+
|
164
|
+
if (z) {
|
165
|
+
z[0] = m[2];
|
166
|
+
z[1] = m[6];
|
167
|
+
z[2] = m[10];
|
168
|
+
z[3] = m[14];
|
169
|
+
}
|
170
|
+
|
171
|
+
if (w) {
|
172
|
+
w[0] = m[3];
|
173
|
+
w[1] = m[7];
|
174
|
+
w[2] = m[11];
|
175
|
+
w[3] = m[15];
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
|
180
|
+
/*! Builds a rotation matrix with the given angle and axis. */
|
181
|
+
void mat4_rotation(s_float_t angle, s_float_t x, s_float_t y, s_float_t z, mat4_t out)
|
182
|
+
{
|
183
|
+
const s_float_t angle_rad = angle * S_DEG2RAD;
|
184
|
+
const s_float_t c = s_cos(angle_rad);
|
185
|
+
const s_float_t s = s_sin(angle_rad);
|
186
|
+
const s_float_t ic = 1.0 - c;
|
187
|
+
const s_float_t xy = x * y * ic;
|
188
|
+
const s_float_t yz = y * z * ic;
|
189
|
+
const s_float_t xz = x * z * ic;
|
190
|
+
const s_float_t xs = s * x;
|
191
|
+
const s_float_t ys = s * y;
|
192
|
+
const s_float_t zs = s * z;
|
193
|
+
|
194
|
+
out[0] = ((x * x) * ic) + c;
|
195
|
+
out[1] = xy + zs;
|
196
|
+
out[2] = xz - ys;
|
197
|
+
out[4] = xy - zs;
|
198
|
+
out[5] = ((y * y) * ic) + c;
|
199
|
+
out[6] = yz + xs;
|
200
|
+
out[8] = xz + ys;
|
201
|
+
out[9] = yz - xs;
|
202
|
+
out[10] = ((z * z) * ic) + c;
|
203
|
+
out[3] = out[7] = out[11] =
|
204
|
+
out[12] = out[13] = out[14] = 0.0;
|
205
|
+
out[15] = 1.0;
|
206
|
+
}
|
207
|
+
|
208
|
+
void mat4_frustum(s_float_t left, s_float_t right, s_float_t bottom, s_float_t top, s_float_t near, s_float_t far, mat4_t out)
|
209
|
+
{
|
210
|
+
const s_float_t xdelta = right - left;
|
211
|
+
const s_float_t ydelta = top - bottom;
|
212
|
+
const s_float_t zdelta = far - near;
|
213
|
+
const s_float_t neardouble = 2.0 * near;
|
214
|
+
|
215
|
+
out[0] = neardouble / xdelta;
|
216
|
+
out[2] = (right + left) / xdelta;
|
217
|
+
out[5] = neardouble / ydelta;
|
218
|
+
out[6] = (top + bottom) / ydelta;
|
219
|
+
out[10] = -((far + near) / zdelta);
|
220
|
+
out[11] = -1.0;
|
221
|
+
out[14] = -((neardouble * far) / zdelta);
|
222
|
+
out[1] = out[3] = out[4] =
|
223
|
+
out[7] = out[8] = out[9] =
|
224
|
+
out[12] = out[13] = out[15] = 0.0;
|
225
|
+
}
|
226
|
+
|
227
|
+
void mat4_orthographic(s_float_t left, s_float_t right, s_float_t bottom, s_float_t top, s_float_t near, s_float_t far, mat4_t out)
|
228
|
+
{
|
229
|
+
const s_float_t xdelta = right - left;
|
230
|
+
const s_float_t ydelta = top - bottom;
|
231
|
+
const s_float_t zdelta = far - near;
|
232
|
+
|
233
|
+
out[0] = 2.0 / xdelta;
|
234
|
+
out[5] = 2.0 / ydelta;
|
235
|
+
out[10] = -2.0 / zdelta;
|
236
|
+
out[12] = -((right + left) / xdelta);
|
237
|
+
out[13] = -((top + bottom) / ydelta);
|
238
|
+
out[14] = -((far + near) / zdelta);
|
239
|
+
out[15] = 1.0;
|
240
|
+
out[1] = out[2] = out[3] =
|
241
|
+
out[4] = out[6] = out[7] =
|
242
|
+
out[8] = out[9] = out[11] = 0.0;
|
243
|
+
}
|
244
|
+
|
245
|
+
void mat4_perspective(s_float_t fov_y, s_float_t aspect, s_float_t near, s_float_t far, mat4_t out)
|
246
|
+
{
|
247
|
+
const s_float_t r = s_tan(fov_y * 0.5 * S_DEG2RAD);
|
248
|
+
const s_float_t left = -r * aspect;
|
249
|
+
const s_float_t right = r * aspect;
|
250
|
+
const s_float_t bottom = -r;
|
251
|
+
const s_float_t top = r;
|
252
|
+
const s_float_t two_near = 2 * near;
|
253
|
+
const s_float_t zdelta = 1.0 / (near - far);
|
254
|
+
|
255
|
+
out[0] = two_near * (right - left);
|
256
|
+
out[5] = two_near / (top - bottom);
|
257
|
+
out[10] = (far + near) * zdelta;
|
258
|
+
out[11] = -1.0;
|
259
|
+
out[14] = (two_near * far) * zdelta;
|
260
|
+
out[1] = out[2] = out[3] =
|
261
|
+
out[4] = out[6] = out[7] =
|
262
|
+
out[8] = out[9] = out[12] =
|
263
|
+
out[13] = out[15] = 0.0;
|
264
|
+
}
|
265
|
+
|
266
|
+
void mat4_look_at(const vec3_t eye, const vec3_t center, const vec3_t up, mat4_t out)
|
267
|
+
{
|
268
|
+
mat4_t r;
|
269
|
+
vec3_t facing_norm, up_norm, s;
|
270
|
+
/* facing_norm */
|
271
|
+
vec3_subtract(center, eye, facing_norm);
|
272
|
+
vec3_normalize(facing_norm, facing_norm);
|
273
|
+
/* up_norm */
|
274
|
+
vec3_normalize(up, up_norm);
|
275
|
+
/* s */
|
276
|
+
vec3_cross_product(facing_norm, up_norm, s);
|
277
|
+
vec3_normalize(s, s);
|
278
|
+
/* up_norm rejigged */
|
279
|
+
vec3_cross_product(s, facing_norm, up_norm);
|
280
|
+
up_norm[1] = -up_norm[1];
|
281
|
+
facing_norm[0] = -facing_norm[0];
|
282
|
+
facing_norm[1] = -facing_norm[1];
|
283
|
+
facing_norm[2] = -facing_norm[2];
|
284
|
+
|
285
|
+
mat4_set_axes3(s, up_norm, facing_norm, g_vec3_zero, r);
|
286
|
+
mat4_translate(-eye[0], -eye[1], -eye[2], r, out);
|
287
|
+
}
|
288
|
+
|
289
|
+
void mat4_from_quat(const quat_t quat, mat4_t out)
|
290
|
+
{
|
291
|
+
s_float_t tx, ty, tz, xx, xy, xz, yy, yz, zz, wx, wy, wz;
|
292
|
+
|
293
|
+
tx = 2.0 * quat[0];
|
294
|
+
ty = 2.0 * quat[1];
|
295
|
+
tz = 2.0 * quat[2];
|
296
|
+
|
297
|
+
xx = tx * quat[0];
|
298
|
+
xy = tx * quat[1];
|
299
|
+
xz = tx * quat[2];
|
300
|
+
|
301
|
+
yy = ty * quat[1];
|
302
|
+
yz = tz * quat[1];
|
303
|
+
|
304
|
+
zz = tz * quat[3];
|
305
|
+
|
306
|
+
wx = tx * quat[3];
|
307
|
+
wy = ty * quat[3];
|
308
|
+
wz = tz * quat[3];
|
309
|
+
|
310
|
+
out[0 ] = 1.0 - (yy + zz);
|
311
|
+
out[1 ] = xy - wz;
|
312
|
+
out[2 ] = xz + wy;
|
313
|
+
out[4 ] = xy + wz;
|
314
|
+
out[5 ] = 1.0 - (xx + zz);
|
315
|
+
out[6 ] = yz - wx;
|
316
|
+
out[8 ] = xz - wy;
|
317
|
+
out[9 ] = yz + wx;
|
318
|
+
out[10] = 1.0 - (xx + yy);
|
319
|
+
|
320
|
+
out[7 ] = 0.0;
|
321
|
+
out[3 ] = 0.0;
|
322
|
+
out[11] = 0.0;
|
323
|
+
out[12] = 0.0;
|
324
|
+
out[13] = 0.0;
|
325
|
+
out[14] = 0.0;
|
326
|
+
|
327
|
+
out[15] = 1.0;
|
328
|
+
}
|
329
|
+
|
330
|
+
void mat4_get_row4(const mat4_t in, int row, vec4_t out)
|
331
|
+
{
|
332
|
+
if (0 <= row && row < 4) {
|
333
|
+
const s_float_t *rowvec = in + (row * 4);
|
334
|
+
out[0] = rowvec[0];
|
335
|
+
out[1] = rowvec[1];
|
336
|
+
out[2] = rowvec[2];
|
337
|
+
out[3] = rowvec[3];
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
341
|
+
void mat4_get_row3(const mat4_t in, int row, vec3_t out)
|
342
|
+
{
|
343
|
+
if (0 <= row && row < 4) {
|
344
|
+
const s_float_t *rowvec = in + (row * 4);
|
345
|
+
out[0] = rowvec[0];
|
346
|
+
out[1] = rowvec[1];
|
347
|
+
out[2] = rowvec[2];
|
348
|
+
}
|
349
|
+
}
|
350
|
+
|
351
|
+
void mat4_get_column4(const mat4_t in, int column, vec4_t out)
|
352
|
+
{
|
353
|
+
if (0 <= column && column < 4) {
|
354
|
+
const s_float_t *colvec = in + column;
|
355
|
+
out[0] = colvec[0];
|
356
|
+
out[1] = colvec[4];
|
357
|
+
out[2] = colvec[8];
|
358
|
+
out[3] = colvec[12];
|
359
|
+
}
|
360
|
+
}
|
361
|
+
|
362
|
+
void mat4_get_column3(const mat4_t in, int column, vec3_t out)
|
363
|
+
{
|
364
|
+
if (0 <= column && column < 4) {
|
365
|
+
const s_float_t *colvec = in + column;
|
366
|
+
out[0] = colvec[0];
|
367
|
+
out[1] = colvec[4];
|
368
|
+
out[2] = colvec[8];
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
void mat4_set_row4(int row, const vec4_t value, mat4_t inout)
|
373
|
+
{
|
374
|
+
if (0 <= row && row < 4) {
|
375
|
+
s_float_t *rowvec = inout + (row * 4);
|
376
|
+
rowvec[0] = value[0];
|
377
|
+
rowvec[1] = value[1];
|
378
|
+
rowvec[2] = value[2];
|
379
|
+
rowvec[3] = value[3];
|
380
|
+
}
|
381
|
+
}
|
382
|
+
|
383
|
+
void mat4_set_row3(int row, const vec3_t value, mat4_t inout)
|
384
|
+
{
|
385
|
+
if (0 <= row && row < 4) {
|
386
|
+
s_float_t *rowvec = inout + (row * 4);
|
387
|
+
rowvec[0] = value[0];
|
388
|
+
rowvec[1] = value[1];
|
389
|
+
rowvec[2] = value[2];
|
390
|
+
}
|
391
|
+
}
|
392
|
+
|
393
|
+
void mat4_set_column4(int column, const vec4_t value, mat4_t inout)
|
394
|
+
{
|
395
|
+
if (0 <= column && column < 4) {
|
396
|
+
s_float_t *colvec = inout + column;
|
397
|
+
colvec[0] = value[0];
|
398
|
+
colvec[4] = value[1];
|
399
|
+
colvec[8] = value[2];
|
400
|
+
colvec[12] = value[3];
|
401
|
+
}
|
402
|
+
}
|
403
|
+
|
404
|
+
void mat4_set_column3(int column, const vec3_t value, mat4_t inout)
|
405
|
+
{
|
406
|
+
if (0 <= column && column < 4) {
|
407
|
+
s_float_t *colvec = inout + column;
|
408
|
+
colvec[0] = value[0];
|
409
|
+
colvec[4] = value[1];
|
410
|
+
colvec[8] = value[2];
|
411
|
+
}
|
412
|
+
}
|
413
|
+
|
414
|
+
int mat4_equals(const mat4_t left, const mat4_t right)
|
415
|
+
{
|
416
|
+
/*
|
417
|
+
compare the XYZ components of all axes first, since they are the most likely
|
418
|
+
to vary between checks
|
419
|
+
*/
|
420
|
+
return (
|
421
|
+
s_fabs(left[0] - right[0]) < S_FLOAT_EPSILON &&
|
422
|
+
s_fabs(left[1] - right[1]) < S_FLOAT_EPSILON &&
|
423
|
+
s_fabs(left[2] - right[2]) < S_FLOAT_EPSILON &&
|
424
|
+
|
425
|
+
s_fabs(left[4] - right[4]) < S_FLOAT_EPSILON &&
|
426
|
+
s_fabs(left[5] - right[5]) < S_FLOAT_EPSILON &&
|
427
|
+
s_fabs(left[6] - right[6]) < S_FLOAT_EPSILON &&
|
428
|
+
|
429
|
+
s_fabs(left[8] - right[8]) < S_FLOAT_EPSILON &&
|
430
|
+
s_fabs(left[9] - right[9]) < S_FLOAT_EPSILON &&
|
431
|
+
s_fabs(left[10] - right[10]) < S_FLOAT_EPSILON &&
|
432
|
+
|
433
|
+
s_fabs(left[12] - right[12]) < S_FLOAT_EPSILON &&
|
434
|
+
s_fabs(left[13] - right[13]) < S_FLOAT_EPSILON &&
|
435
|
+
s_fabs(left[14] - right[14]) < S_FLOAT_EPSILON &&
|
436
|
+
|
437
|
+
s_fabs(left[3] - right[3]) < S_FLOAT_EPSILON &&
|
438
|
+
s_fabs(left[7] - right[7]) < S_FLOAT_EPSILON &&
|
439
|
+
s_fabs(left[11] - right[11]) < S_FLOAT_EPSILON &&
|
440
|
+
s_fabs(left[15] - right[15]) < S_FLOAT_EPSILON
|
441
|
+
);
|
442
|
+
}
|
443
|
+
|
444
|
+
void mat4_transpose(const mat4_t in, mat4_t out)
|
445
|
+
{
|
446
|
+
s_float_t temp;
|
447
|
+
#define swap_elem(X, Y) temp = in[(X)]; out[(X)] = in[(Y)]; out[(Y)] = temp
|
448
|
+
swap_elem(1, 4);
|
449
|
+
swap_elem(8, 2);
|
450
|
+
swap_elem(9, 6);
|
451
|
+
swap_elem(12, 3);
|
452
|
+
swap_elem(13, 7);
|
453
|
+
swap_elem(14, 11);
|
454
|
+
out[0] = in[0];
|
455
|
+
out[5] = in[5];
|
456
|
+
out[10] = in[10];
|
457
|
+
out[15] = in[15];
|
458
|
+
}
|
459
|
+
|
460
|
+
void mat4_inverse_orthogonal(const mat4_t in, mat4_t out)
|
461
|
+
{
|
462
|
+
const s_float_t m12 = in[12];
|
463
|
+
const s_float_t m13 = in[13];
|
464
|
+
const s_float_t m14 = in[14];
|
465
|
+
mat4_t temp = {
|
466
|
+
in[0],
|
467
|
+
in[4],
|
468
|
+
in[8],
|
469
|
+
0.0,
|
470
|
+
in[1],
|
471
|
+
in[5],
|
472
|
+
in[9],
|
473
|
+
0.0,
|
474
|
+
in[2],
|
475
|
+
in[6],
|
476
|
+
in[10],
|
477
|
+
0.0
|
478
|
+
};
|
479
|
+
|
480
|
+
temp[12] = -((m12 * temp[0]) + (m13 * temp[4]) + (m14 * temp[8]));
|
481
|
+
temp[13] = -((m12 * temp[1]) + (m13 * temp[5]) + (m14 * temp[9]));
|
482
|
+
temp[14] = -((m12 * temp[2]) + (m13 * temp[6]) + (m14 * temp[10]));
|
483
|
+
temp[15] = 1.0;
|
484
|
+
|
485
|
+
mat4_copy(temp, out);
|
486
|
+
}
|
487
|
+
|
488
|
+
/*!
|
489
|
+
* Writes the inverse affine of the input matrix to the output matrix.
|
490
|
+
* \returns Non-zero if an inverse affine matrix can be created, otherwise
|
491
|
+
* zero if not. If zero, the output matrix is the identity matrix.
|
492
|
+
*/
|
493
|
+
int mat4_inverse_affine(const mat4_t in, mat4_t out)
|
494
|
+
{
|
495
|
+
mat4_t temp;
|
496
|
+
s_float_t det;
|
497
|
+
s_float_t m12, m13, m14;
|
498
|
+
|
499
|
+
temp[0 ] = (in[5 ] * in[10]) - (in[6 ] * in[9 ]);
|
500
|
+
temp[1 ] = (in[2 ] * in[9 ]) - (in[1 ] * in[10]);
|
501
|
+
temp[2 ] = (in[1 ] * in[6 ]) - (in[2 ] * in[5 ]);
|
502
|
+
|
503
|
+
temp[4 ] = (in[6 ] * in[ 8]) - (in[4 ] * in[10]);
|
504
|
+
temp[5 ] = (in[0 ] * in[10]) - (in[2 ] * in[ 8]);
|
505
|
+
temp[6 ] = (in[2 ] * in[ 4]) - (in[0 ] * in[ 6]);
|
506
|
+
|
507
|
+
temp[8 ] = (in[4 ] * in[ 9]) - (in[5 ] * in[ 8]);
|
508
|
+
temp[9 ] = (in[1 ] * in[ 8]) - (in[0 ] * in[ 9]);
|
509
|
+
temp[10] = (in[0 ] * in[ 5]) - (in[1 ] * in[ 4]);
|
510
|
+
|
511
|
+
det = (in[0] * temp[0]) + (in[1] * temp[4]) + (in[2] * temp[8]);
|
512
|
+
if (s_fabs(det) < S_FLOAT_EPSILON) {
|
513
|
+
mat4_identity(out);
|
514
|
+
return 0;
|
515
|
+
}
|
516
|
+
|
517
|
+
det = 1.0 / det;
|
518
|
+
|
519
|
+
out[0] = temp[0] * det;
|
520
|
+
out[1] = temp[1] * det;
|
521
|
+
out[2] = temp[2] * det;
|
522
|
+
out[4] = temp[4] * det;
|
523
|
+
out[5] = temp[5] * det;
|
524
|
+
out[6] = temp[6] * det;
|
525
|
+
out[8 ] = temp[8 ] * det;
|
526
|
+
out[9 ] = temp[9 ] * det;
|
527
|
+
out[10] = temp[10] * det;
|
528
|
+
|
529
|
+
m12 = in[12];
|
530
|
+
m13 = in[13];
|
531
|
+
m14 = in[14];
|
532
|
+
|
533
|
+
out[12] = -((m12 * temp[0]) + (m13 * temp[4]) + (m14 * temp[8 ]));
|
534
|
+
out[13] = -((m12 * temp[1]) + (m13 * temp[5]) + (m14 * temp[9 ]));
|
535
|
+
out[14] = -((m12 * temp[2]) + (m13 * temp[6]) + (m14 * temp[10]));
|
536
|
+
|
537
|
+
out[3] = out[7] = out[11] = 0.0;
|
538
|
+
out[15] = 1.0;
|
539
|
+
|
540
|
+
return 1;
|
541
|
+
}
|
542
|
+
|
543
|
+
inline s_float_t mat4_cofactor(const mat4_t m, int r0, int r1, int r2, int c0, int c1, int c2)
|
544
|
+
{
|
545
|
+
#define cofactor_addr(l, r) (m[l*4+r])
|
546
|
+
return (
|
547
|
+
(cofactor_addr(r0,c0) * ((cofactor_addr(r1, c1) * cofactor_addr(r2, c2)) - (cofactor_addr(r2, c1) * cofactor_addr(r1, c2)))) -
|
548
|
+
(cofactor_addr(r0,c1) * ((cofactor_addr(r1, c0) * cofactor_addr(r2, c2)) - (cofactor_addr(r2, c0) * cofactor_addr(r1, c2)))) +
|
549
|
+
(cofactor_addr(r0,c2) * ((cofactor_addr(r1, c0) * cofactor_addr(r2, c1)) - (cofactor_addr(r2, c0) * cofactor_addr(r1, c1))))
|
550
|
+
);
|
551
|
+
#undef cofactor_addr
|
552
|
+
}
|
553
|
+
|
554
|
+
void mat4_adjoint(const mat4_t in, mat4_t out)
|
555
|
+
{
|
556
|
+
if (in == out) {
|
557
|
+
mat4_t temp = {
|
558
|
+
mat4_cofactor(in, 1, 2, 3, 1, 2, 3),
|
559
|
+
-mat4_cofactor(in, 0, 2, 3, 1, 2, 3),
|
560
|
+
mat4_cofactor(in, 0, 1, 3, 1, 2, 3),
|
561
|
+
-mat4_cofactor(in, 0, 1, 2, 1, 2, 3),
|
562
|
+
|
563
|
+
-mat4_cofactor(in, 1, 2, 3, 0, 2, 3),
|
564
|
+
mat4_cofactor(in, 0, 2, 3, 0, 2, 3),
|
565
|
+
-mat4_cofactor(in, 0, 1, 3, 0, 2, 3),
|
566
|
+
mat4_cofactor(in, 0, 1, 2, 0, 2, 3),
|
567
|
+
|
568
|
+
mat4_cofactor(in, 1, 2, 3, 0, 1, 3),
|
569
|
+
-mat4_cofactor(in, 0, 2, 3, 0, 1, 3),
|
570
|
+
mat4_cofactor(in, 0, 1, 3, 0, 1, 3),
|
571
|
+
-mat4_cofactor(in, 0, 1, 2, 0, 1, 3),
|
572
|
+
|
573
|
+
-mat4_cofactor(in, 1, 2, 3, 0, 1, 2),
|
574
|
+
mat4_cofactor(in, 0, 2, 3, 0, 1, 2),
|
575
|
+
-mat4_cofactor(in, 0, 1, 3, 0, 1, 2),
|
576
|
+
mat4_cofactor(in, 0, 1, 2, 0, 1, 2)
|
577
|
+
};
|
578
|
+
mat4_copy(temp, out);
|
579
|
+
} else {
|
580
|
+
out[0 ] = mat4_cofactor(in, 1, 2, 3, 1, 2, 3);
|
581
|
+
out[1 ] = -mat4_cofactor(in, 0, 2, 3, 1, 2, 3);
|
582
|
+
out[2 ] = mat4_cofactor(in, 0, 1, 3, 1, 2, 3);
|
583
|
+
out[3 ] = -mat4_cofactor(in, 0, 1, 2, 1, 2, 3);
|
584
|
+
|
585
|
+
out[4 ] = -mat4_cofactor(in, 1, 2, 3, 0, 2, 3);
|
586
|
+
out[5 ] = mat4_cofactor(in, 0, 2, 3, 0, 2, 3);
|
587
|
+
out[6 ] = -mat4_cofactor(in, 0, 1, 3, 0, 2, 3);
|
588
|
+
out[7 ] = mat4_cofactor(in, 0, 1, 2, 0, 2, 3);
|
589
|
+
|
590
|
+
out[8 ] = mat4_cofactor(in, 1, 2, 3, 0, 1, 3);
|
591
|
+
out[9 ] = -mat4_cofactor(in, 0, 2, 3, 0, 1, 3);
|
592
|
+
out[10] = mat4_cofactor(in, 0, 1, 3, 0, 1, 3);
|
593
|
+
out[11] = -mat4_cofactor(in, 0, 1, 2, 0, 1, 3);
|
594
|
+
|
595
|
+
out[12] = -mat4_cofactor(in, 1, 2, 3, 0, 1, 2);
|
596
|
+
out[13] = mat4_cofactor(in, 0, 2, 3, 0, 1, 2);
|
597
|
+
out[14] = -mat4_cofactor(in, 0, 1, 3, 0, 1, 2);
|
598
|
+
out[15] = mat4_cofactor(in, 0, 1, 2, 0, 1, 2);
|
599
|
+
}
|
600
|
+
}
|
601
|
+
|
602
|
+
s_float_t mat4_determinant(const mat4_t m)
|
603
|
+
{
|
604
|
+
return (
|
605
|
+
(m[0] * mat4_cofactor(m, 1, 2, 3, 1, 2, 3)) -
|
606
|
+
(m[1] * mat4_cofactor(m, 1, 2, 3, 0, 2, 3)) +
|
607
|
+
(m[2] * mat4_cofactor(m, 1, 2, 3, 0, 1, 3)) -
|
608
|
+
(m[3] * mat4_cofactor(m, 1, 2, 3, 0, 1, 2))
|
609
|
+
);
|
610
|
+
}
|
611
|
+
|
612
|
+
int mat4_inverse_general(const mat4_t in, mat4_t out)
|
613
|
+
{
|
614
|
+
int index;
|
615
|
+
s_float_t det = mat4_determinant(in);
|
616
|
+
|
617
|
+
if (s_fabs(det) < S_FLOAT_EPSILON) {
|
618
|
+
return 0;
|
619
|
+
}
|
620
|
+
|
621
|
+
mat4_adjoint(in, out);
|
622
|
+
det = 1.0 / det;
|
623
|
+
for (index = 0; index < 16; ++index) {
|
624
|
+
out[index] *= det;
|
625
|
+
}
|
626
|
+
|
627
|
+
return 1;
|
628
|
+
}
|
629
|
+
|
630
|
+
/*! Translates the given matrix by <X, Y, Z>. */
|
631
|
+
void mat4_translate(s_float_t x, s_float_t y, s_float_t z, const mat4_t in, mat4_t out)
|
632
|
+
{
|
633
|
+
s_float_t m12 = in[12] + ((x * in[0]) + (y * in[4]) + (z * in[8]));
|
634
|
+
s_float_t m13 = in[13] + ((x * in[1]) + (y * in[5]) + (z * in[9]));
|
635
|
+
s_float_t m14 = in[14] + ((x * in[2]) + (y * in[6]) + (z * in[10]));
|
636
|
+
s_float_t m15 = in[15] + ((x * in[3]) + (y * in[7]) + (z * in[11]));
|
637
|
+
|
638
|
+
if (in != out)
|
639
|
+
mat4_copy(in, out);
|
640
|
+
|
641
|
+
out[12] = m12;
|
642
|
+
out[13] = m13;
|
643
|
+
out[14] = m14;
|
644
|
+
out[15] = m15;
|
645
|
+
}
|
646
|
+
|
647
|
+
void mat4_translation(s_float_t x, s_float_t y, s_float_t z, mat4_t out) {
|
648
|
+
s_float_t m12 = x;
|
649
|
+
s_float_t m13 = y;
|
650
|
+
s_float_t m14 = z;
|
651
|
+
s_float_t m15 = 1;
|
652
|
+
|
653
|
+
mat4_copy(g_mat4_identity, out);
|
654
|
+
|
655
|
+
out[12] = m12;
|
656
|
+
out[13] = m13;
|
657
|
+
out[14] = m14;
|
658
|
+
out[15] = m15;
|
659
|
+
}
|
660
|
+
|
661
|
+
void mat4_multiply(const mat4_t left, const mat4_t right, mat4_t out)
|
662
|
+
{
|
663
|
+
mat4_t temp;
|
664
|
+
int index;
|
665
|
+
|
666
|
+
// Transpose the left matrix so we can be a little more cache-friendly.
|
667
|
+
mat4_transpose(left, temp);
|
668
|
+
|
669
|
+
for (index = 0; index < 4; ++index) {
|
670
|
+
const int inner_index = index * 4;
|
671
|
+
s_float_t cx, cy, cz, cw;
|
672
|
+
|
673
|
+
cx = temp[inner_index];
|
674
|
+
cy = temp[inner_index + 1];
|
675
|
+
cz = temp[inner_index + 2];
|
676
|
+
cw = temp[inner_index + 3];
|
677
|
+
|
678
|
+
temp[inner_index] = (cx * right[0 ]) + (cy * right[1 ]) + (cz * right[2 ]) + (cw * right[3 ]);
|
679
|
+
temp[inner_index + 1] = (cx * right[4 ]) + (cy * right[5 ]) + (cz * right[6 ]) + (cw * right[7 ]);
|
680
|
+
temp[inner_index + 2] = (cx * right[8 ]) + (cy * right[9 ]) + (cz * right[10]) + (cw * right[11]);
|
681
|
+
temp[inner_index + 3] = (cx * right[12]) + (cy * right[13]) + (cz * right[14]) + (cw * right[15]);
|
682
|
+
}
|
683
|
+
|
684
|
+
mat4_transpose(temp, out);
|
685
|
+
}
|
686
|
+
|
687
|
+
void mat4_multiply_vec4(const mat4_t left, const vec4_t right, vec4_t out)
|
688
|
+
{
|
689
|
+
const s_float_t x = right[0], y = right[1], z = right[2], w = right[3];
|
690
|
+
out[0] = (x * left[0]) + (y * left[4]) + (z * left[8 ]) + (w * left[12]);
|
691
|
+
out[1] = (x * left[1]) + (y * left[5]) + (z * left[9 ]) + (w * left[13]);
|
692
|
+
out[2] = (x * left[2]) + (y * left[6]) + (z * left[10]) + (w * left[14]);
|
693
|
+
out[3] = (x * left[3]) + (y * left[7]) + (z * left[11]) + (w * left[15]);
|
694
|
+
}
|
695
|
+
|
696
|
+
void mat4_transform_vec3(const mat4_t left, const vec3_t right, vec3_t out)
|
697
|
+
{
|
698
|
+
const s_float_t x = right[0], y = right[1], z = right[2];
|
699
|
+
out[0] = (x * left[0]) + (y * left[4]) + (z * left[8 ]) + left[12];
|
700
|
+
out[1] = (x * left[1]) + (y * left[5]) + (z * left[9 ]) + left[13];
|
701
|
+
out[2] = (x * left[2]) + (y * left[6]) + (z * left[10]) + left[14];
|
702
|
+
}
|
703
|
+
|
704
|
+
void mat4_rotate_vec3(const mat4_t left, const vec3_t right, vec3_t out)
|
705
|
+
{
|
706
|
+
const s_float_t x = right[0], y = right[1], z = right[2];
|
707
|
+
out[0] = (x * left[0]) + (y * left[4]) + (z * left[8 ]);
|
708
|
+
out[1] = (x * left[1]) + (y * left[5]) + (z * left[9 ]);
|
709
|
+
out[2] = (x * left[2]) + (y * left[6]) + (z * left[10]);
|
710
|
+
}
|
711
|
+
|
712
|
+
void mat4_inv_rotate_vec3(const mat4_t left, const vec3_t right, vec3_t out)
|
713
|
+
{
|
714
|
+
const s_float_t x = right[0], y = right[1], z = right[2];
|
715
|
+
out[0] = (x * left[0]) + (y * left[1]) + (z * left[2 ]);
|
716
|
+
out[1] = (x * left[4]) + (y * left[5]) + (z * left[6 ]);
|
717
|
+
out[2] = (x * left[8]) + (y * left[9]) + (z * left[10]);
|
718
|
+
}
|
719
|
+
|
720
|
+
void mat4_scale(const mat4_t in, s_float_t x, s_float_t y, s_float_t z, mat4_t out)
|
721
|
+
{
|
722
|
+
mat4_copy(in, out);
|
723
|
+
out[0] *= x;
|
724
|
+
out[4] *= x;
|
725
|
+
out[8] *= x;
|
726
|
+
|
727
|
+
out[1] *= y;
|
728
|
+
out[5] *= y;
|
729
|
+
out[9] *= y;
|
730
|
+
|
731
|
+
out[2 ] *= z;
|
732
|
+
out[6 ] *= z;
|
733
|
+
out[10] *= z;
|
734
|
+
}
|
735
|
+
|
736
|
+
#if defined(__cplusplus)
|
737
|
+
}
|
738
|
+
#endif /* __cplusplus */
|
739
|
+
|