snow-math 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+