liblibgb.c 1.2021.3

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.
package/gb/gb_math.h ADDED
@@ -0,0 +1,2234 @@
1
+ /* gb_math.h - v0.07c - public domain C math library - no warranty implied; use at your own risk
2
+ A C math library geared towards game development
3
+ use '#define GB_MATH_IMPLEMENTATION' before including to create the implementation in _ONE_ file
4
+
5
+ Version History:
6
+ 0.07f - Fix constants
7
+ 0.07e - Fixed a warning
8
+ 0.07d - Fix mat4_inverse
9
+ 0.07c - Add gb_random01
10
+ 0.07b - Fix mat4_inverse
11
+ 0.07a - Fix Mat2
12
+ 0.07 - Better Mat4 procedures
13
+ 0.06h - Ignore silly warnings
14
+ 0.06g - Remove memzero
15
+ 0.06f - Remove warning on MSVC
16
+ 0.06e - Change brace style and fix some warnings
17
+ 0.06d - Bug fix
18
+ 0.06c - Remove extra needed define for C++ and inline all operators
19
+ 0.06b - Just formatting
20
+ 0.06a - Implement rough versions of mod, remainder, copy_sign
21
+ 0.06 - Windows GCC Support and C90-ish Support
22
+ 0.05 - Less/no dependencies or CRT
23
+ 0.04d - License Update
24
+ 0.04c - Use 64-bit murmur64 version on WIN64
25
+ 0.04b - Fix strict aliasing in gb_quake_rsqrt
26
+ 0.04a - Minor bug fixes
27
+ 0.04 - Namespace everything with gb
28
+ 0.03 - Complete Replacement
29
+ 0.01 - Initial Version
30
+
31
+ LICENSE
32
+ This software is dual-licensed to the public domain and under the following
33
+ license: you are granted a perpetual, irrevocable license to copy, modify,
34
+ publish, and distribute this file as you see fit.
35
+ WARNING
36
+ - This library is _slightly_ experimental and features may not work as expected.
37
+ - This also means that many functions are not documented.
38
+
39
+ CONTENTS
40
+ - Common Macros
41
+ - Types
42
+ - gbVec(2,3,4)
43
+ - gbMat(2,3,4)
44
+ - gbFloat(2,3,4)
45
+ - gbQuat
46
+ - gbRect(2,3)
47
+ - gbAabb(2,3)
48
+ - gbHalf (16-bit floating point) (storage only)
49
+ - Operations
50
+ - Functions
51
+ - Type Functions
52
+ - Random
53
+ - Hash
54
+ */
55
+
56
+ #ifndef GB_MATH_INCLUDE_GB_MATH_H
57
+ #define GB_MATH_INCLUDE_GB_MATH_H
58
+
59
+ #include <stddef.h>
60
+
61
+ #if !defined(GB_MATH_NO_MATH_H)
62
+ #include <math.h>
63
+ #else
64
+ #include <intrin.h>
65
+ #endif
66
+
67
+ #ifndef GB_MATH_DEF
68
+ #ifdef GB_MATH_STATIC
69
+ #define GB_MATH_DEF static
70
+ #else
71
+ #define GB_MATH_DEF extern
72
+ #endif
73
+ #endif
74
+
75
+ #if defined(_MSC_VER)
76
+ #pragma warning(push)
77
+ #pragma warning(disable:4201)
78
+ #endif
79
+
80
+ typedef union gbVec2 {
81
+ struct { float x, y; };
82
+ float e[2];
83
+ } gbVec2;
84
+
85
+ typedef union gbVec3 {
86
+ struct { float x, y, z; };
87
+ struct { float r, g, b; };
88
+
89
+ gbVec2 xy;
90
+ float e[3];
91
+ } gbVec3;
92
+
93
+ typedef union gbVec4 {
94
+ struct { float x, y, z, w; };
95
+ struct { float r, g, b, a; };
96
+ struct { gbVec2 xy, zw; };
97
+ gbVec3 xyz;
98
+ gbVec3 rgb;
99
+ float e[4];
100
+ } gbVec4;
101
+
102
+
103
+
104
+ typedef union gbMat2 {
105
+ struct { gbVec2 x, y; };
106
+ gbVec2 col[2];
107
+ float e[4];
108
+ } gbMat2;
109
+
110
+ typedef union gbMat3 {
111
+ struct { gbVec3 x, y, z; };
112
+ gbVec3 col[3];
113
+ float e[9];
114
+ } gbMat3;
115
+
116
+ typedef union gbMat4 {
117
+ struct { gbVec4 x, y, z, w; };
118
+ gbVec4 col[4];
119
+ float e[16];
120
+ } gbMat4;
121
+
122
+
123
+ typedef union gbQuat {
124
+ struct { float x, y, z, w; };
125
+ gbVec4 xyzw;
126
+ gbVec3 xyz;
127
+ float e[4];
128
+ } gbQuat;
129
+
130
+
131
+ #if defined(_MSC_VER)
132
+ #pragma warning(pop)
133
+ #endif
134
+
135
+ typedef float gbFloat2[2];
136
+ typedef float gbFloat3[3];
137
+ typedef float gbFloat4[4];
138
+
139
+
140
+ typedef struct gbRect2 { gbVec2 pos, dim; } gbRect2;
141
+ typedef struct gbRect3 { gbVec3 pos, dim; } gbRect3;
142
+
143
+ typedef struct gbAabb2 { gbVec2 centre, half_size; } gbAabb2;
144
+ typedef struct gbAabb3 { gbVec3 centre, half_size; } gbAabb3;
145
+
146
+ #if defined(_MSC_VER)
147
+ typedef unsigned __int32 gb_math_u32;
148
+ typedef unsigned __int64 gb_math_u64;
149
+ #else
150
+ #if defined(GB_USE_STDINT)
151
+ #include <stdint.h>
152
+ typedef uint32_t gb_math_u32;
153
+ typedef uint64_t gb_math_u64;
154
+ #else
155
+ typedef unsigned int gb_math_u32;
156
+ typedef unsigned long long gb_math_u64;
157
+ #endif
158
+ #endif
159
+
160
+ typedef short gbHalf;
161
+
162
+
163
+ #ifndef GB_MATH_CONSTANTS
164
+ #define GB_MATH_CONSTANTS
165
+ #define GB_MATH_EPSILON 1.19209290e-7f
166
+ #define GB_MATH_ZERO 0.0f
167
+ #define GB_MATH_ONE 1.0f
168
+ #define GB_MATH_TWO_THIRDS 0.666666666666666666666666666666666666667f
169
+
170
+ #define GB_MATH_TAU 6.28318530717958647692528676655900576f
171
+ #define GB_MATH_PI 3.14159265358979323846264338327950288f
172
+ #define GB_MATH_ONE_OVER_TAU 0.159154943091895335768883763372514362f
173
+ #define GB_MATH_ONE_OVER_PI 0.318309886183790671537767526745028724f
174
+
175
+ #define GB_MATH_TAU_OVER_2 3.14159265358979323846264338327950288f
176
+ #define GB_MATH_TAU_OVER_4 1.570796326794896619231321691639751442f
177
+ #define GB_MATH_TAU_OVER_8 0.785398163397448309615660845819875721f
178
+
179
+ #define GB_MATH_E 2.7182818284590452353602874713526625f
180
+ #define GB_MATH_SQRT_TWO 1.41421356237309504880168872420969808f
181
+ #define GB_MATH_SQRT_THREE 1.73205080756887729352744634150587236f
182
+ #define GB_MATH_SQRT_FIVE 2.23606797749978969640917366873127623f
183
+
184
+ #define GB_MATH_LOG_TWO 0.693147180559945309417232121458176568f
185
+ #define GB_MATH_LOG_TEN 2.30258509299404568401799145468436421f
186
+ #endif
187
+
188
+
189
+ #if defined(__cplusplus)
190
+ extern "C" {
191
+ #endif
192
+
193
+ #ifndef gb_clamp
194
+ #define gb_clamp(x, lower, upper) (gb_min(gb_max(x, (lower)), (upper)))
195
+ #endif
196
+ #ifndef gb_clamp01
197
+ #define gb_clamp01(x) gb_clamp(x, 0, 1)
198
+ #endif
199
+
200
+ #ifndef gb_square
201
+ #define gb_square(x) ((x)*(x))
202
+ #endif
203
+
204
+ #ifndef gb_cube
205
+ #define gb_cube(x) ((x)*(x)*(x))
206
+ #endif
207
+
208
+ #ifndef gb_abs
209
+ #define gb_abs(x) ((x) > 0 ? (x) : -(x))
210
+ #endif
211
+
212
+ #ifndef gb_sign
213
+ #define gb_sign(x) ((x) >= 0 ? 1 : -1)
214
+ #endif
215
+
216
+
217
+ GB_MATH_DEF float gb_to_radians(float degrees);
218
+ GB_MATH_DEF float gb_to_degrees(float radians);
219
+
220
+ /* NOTE(bill): Because to interpolate angles */
221
+ GB_MATH_DEF float gb_angle_diff(float radians_a, float radians_b);
222
+
223
+ #ifndef gb_min
224
+ #define gb_min(a, b) ((a) < (b) ? (a) : (b))
225
+ #endif
226
+ #ifndef gb_max
227
+ #define gb_max(a, b) ((a) > (b) ? (a) : (b))
228
+ #endif
229
+
230
+ #ifndef gb_min3
231
+ #define gb_min3(a, b, c) gb_min(gb_min(a, b), c)
232
+ #endif
233
+
234
+ #ifndef gb_max3
235
+ #define gb_max3(a, b, c) gb_max(gb_max(a, b), c)
236
+ #endif
237
+
238
+
239
+ GB_MATH_DEF float gb_copy_sign (float x, float y);
240
+ GB_MATH_DEF float gb_remainder (float x, float y);
241
+ GB_MATH_DEF float gb_mod (float x, float y);
242
+ GB_MATH_DEF float gb_sqrt (float a);
243
+ GB_MATH_DEF float gb_rsqrt (float a);
244
+ GB_MATH_DEF float gb_quake_rsqrt(float a); /* NOTE(bill): It's probably better to use 1.0f/gb_sqrt(a)
245
+ * And for simd, there is usually isqrt functions too!
246
+ */
247
+ GB_MATH_DEF float gb_sin (float radians);
248
+ GB_MATH_DEF float gb_cos (float radians);
249
+ GB_MATH_DEF float gb_tan (float radians);
250
+ GB_MATH_DEF float gb_arcsin (float a);
251
+ GB_MATH_DEF float gb_arccos (float a);
252
+ GB_MATH_DEF float gb_arctan (float a);
253
+ GB_MATH_DEF float gb_arctan2(float y, float x);
254
+
255
+ GB_MATH_DEF float gb_exp (float x);
256
+ GB_MATH_DEF float gb_exp2 (float x);
257
+ GB_MATH_DEF float gb_log (float x);
258
+ GB_MATH_DEF float gb_log2 (float x);
259
+ GB_MATH_DEF float gb_fast_exp (float x); /* NOTE(bill): Only valid from -1 <= x <= +1 */
260
+ GB_MATH_DEF float gb_fast_exp2(float x); /* NOTE(bill): Only valid from -1 <= x <= +1 */
261
+ GB_MATH_DEF float gb_pow (float x, float y); /* x^y */
262
+
263
+ GB_MATH_DEF float gb_round(float x);
264
+ GB_MATH_DEF float gb_floor(float x);
265
+ GB_MATH_DEF float gb_ceil (float x);
266
+
267
+ GB_MATH_DEF float gb_half_to_float(gbHalf value);
268
+ GB_MATH_DEF gbHalf gb_float_to_half(float value);
269
+
270
+
271
+ GB_MATH_DEF gbVec2 gb_vec2_zero(void);
272
+ GB_MATH_DEF gbVec2 gb_vec2 (float x, float y);
273
+ GB_MATH_DEF gbVec2 gb_vec2v (float x[2]);
274
+
275
+ GB_MATH_DEF gbVec3 gb_vec3_zero(void);
276
+ GB_MATH_DEF gbVec3 gb_vec3 (float x, float y, float z);
277
+ GB_MATH_DEF gbVec3 gb_vec3v (float x[3]);
278
+
279
+ GB_MATH_DEF gbVec4 gb_vec4_zero(void);
280
+ GB_MATH_DEF gbVec4 gb_vec4 (float x, float y, float z, float w);
281
+ GB_MATH_DEF gbVec4 gb_vec4v (float x[4]);
282
+
283
+
284
+ GB_MATH_DEF void gb_vec2_add(gbVec2 *d, gbVec2 v0, gbVec2 v1);
285
+ GB_MATH_DEF void gb_vec2_sub(gbVec2 *d, gbVec2 v0, gbVec2 v1);
286
+ GB_MATH_DEF void gb_vec2_mul(gbVec2 *d, gbVec2 v, float s);
287
+ GB_MATH_DEF void gb_vec2_div(gbVec2 *d, gbVec2 v, float s);
288
+
289
+ GB_MATH_DEF void gb_vec3_add(gbVec3 *d, gbVec3 v0, gbVec3 v1);
290
+ GB_MATH_DEF void gb_vec3_sub(gbVec3 *d, gbVec3 v0, gbVec3 v1);
291
+ GB_MATH_DEF void gb_vec3_mul(gbVec3 *d, gbVec3 v, float s);
292
+ GB_MATH_DEF void gb_vec3_div(gbVec3 *d, gbVec3 v, float s);
293
+
294
+ GB_MATH_DEF void gb_vec4_add(gbVec4 *d, gbVec4 v0, gbVec4 v1);
295
+ GB_MATH_DEF void gb_vec4_sub(gbVec4 *d, gbVec4 v0, gbVec4 v1);
296
+ GB_MATH_DEF void gb_vec4_mul(gbVec4 *d, gbVec4 v, float s);
297
+ GB_MATH_DEF void gb_vec4_div(gbVec4 *d, gbVec4 v, float s);
298
+
299
+ GB_MATH_DEF void gb_vec2_addeq(gbVec2 *d, gbVec2 v);
300
+ GB_MATH_DEF void gb_vec2_subeq(gbVec2 *d, gbVec2 v);
301
+ GB_MATH_DEF void gb_vec2_muleq(gbVec2 *d, float s);
302
+ GB_MATH_DEF void gb_vec2_diveq(gbVec2 *d, float s);
303
+
304
+ GB_MATH_DEF void gb_vec3_addeq(gbVec3 *d, gbVec3 v);
305
+ GB_MATH_DEF void gb_vec3_subeq(gbVec3 *d, gbVec3 v);
306
+ GB_MATH_DEF void gb_vec3_muleq(gbVec3 *d, float s);
307
+ GB_MATH_DEF void gb_vec3_diveq(gbVec3 *d, float s);
308
+
309
+ GB_MATH_DEF void gb_vec4_addeq(gbVec4 *d, gbVec4 v);
310
+ GB_MATH_DEF void gb_vec4_subeq(gbVec4 *d, gbVec4 v);
311
+ GB_MATH_DEF void gb_vec4_muleq(gbVec4 *d, float s);
312
+ GB_MATH_DEF void gb_vec4_diveq(gbVec4 *d, float s);
313
+
314
+ GB_MATH_DEF float gb_vec2_dot(gbVec2 v0, gbVec2 v1);
315
+ GB_MATH_DEF float gb_vec3_dot(gbVec3 v0, gbVec3 v1);
316
+ GB_MATH_DEF float gb_vec4_dot(gbVec4 v0, gbVec4 v1);
317
+
318
+ GB_MATH_DEF void gb_vec2_cross(float *d, gbVec2 v0, gbVec2 v1);
319
+ GB_MATH_DEF void gb_vec3_cross(gbVec3 *d, gbVec3 v0, gbVec3 v1);
320
+
321
+ GB_MATH_DEF float gb_vec2_mag2(gbVec2 v);
322
+ GB_MATH_DEF float gb_vec3_mag2(gbVec3 v);
323
+ GB_MATH_DEF float gb_vec4_mag2(gbVec4 v);
324
+
325
+ GB_MATH_DEF float gb_vec2_mag(gbVec2 v);
326
+ GB_MATH_DEF float gb_vec3_mag(gbVec3 v);
327
+ GB_MATH_DEF float gb_vec4_mag(gbVec4 v);
328
+
329
+ GB_MATH_DEF void gb_vec2_norm(gbVec2 *d, gbVec2 v);
330
+ GB_MATH_DEF void gb_vec3_norm(gbVec3 *d, gbVec3 v);
331
+ GB_MATH_DEF void gb_vec4_norm(gbVec4 *d, gbVec4 v);
332
+
333
+ GB_MATH_DEF void gb_vec2_norm0(gbVec2 *d, gbVec2 v);
334
+ GB_MATH_DEF void gb_vec3_norm0(gbVec3 *d, gbVec3 v);
335
+ GB_MATH_DEF void gb_vec4_norm0(gbVec4 *d, gbVec4 v);
336
+
337
+ GB_MATH_DEF void gb_vec2_reflect(gbVec2 *d, gbVec2 i, gbVec2 n);
338
+ GB_MATH_DEF void gb_vec3_reflect(gbVec3 *d, gbVec3 i, gbVec3 n);
339
+ GB_MATH_DEF void gb_vec2_refract(gbVec2 *d, gbVec2 i, gbVec2 n, float eta);
340
+ GB_MATH_DEF void gb_vec3_refract(gbVec3 *d, gbVec3 i, gbVec3 n, float eta);
341
+
342
+ GB_MATH_DEF float gb_vec2_aspect_ratio(gbVec2 v);
343
+
344
+
345
+ GB_MATH_DEF void gb_mat2_identity (gbMat2 *m);
346
+ GB_MATH_DEF void gb_float22_identity(float m[2][2]);
347
+
348
+ GB_MATH_DEF void gb_mat2_transpose (gbMat2 *m);
349
+ GB_MATH_DEF void gb_mat2_mul (gbMat2 *out, gbMat2 *m1, gbMat2 *m2);
350
+ GB_MATH_DEF void gb_mat2_mul_vec2 (gbVec2 *out, gbMat2 *m, gbVec2 in);
351
+ GB_MATH_DEF void gb_mat2_inverse (gbMat2 *out, gbMat2 *in);
352
+ GB_MATH_DEF float gb_mat2_determinate(gbMat2 *m);
353
+
354
+ GB_MATH_DEF gbMat2 *gb_mat2_v(gbVec2 m[2]);
355
+ GB_MATH_DEF gbMat2 *gb_mat2_f(float m[2][2]);
356
+ GB_MATH_DEF gbFloat2 *gb_float22_m(gbMat2 *m);
357
+ GB_MATH_DEF gbFloat2 *gb_float22_v(gbVec2 m[2]);
358
+ GB_MATH_DEF gbFloat2 *gb_float22_4(float m[4]);
359
+
360
+ GB_MATH_DEF void gb_float22_transpose(float (*vec)[2]);
361
+ GB_MATH_DEF void gb_float22_mul (float (*out)[2], float (*mat1)[2], float (*mat2)[2]);
362
+ GB_MATH_DEF void gb_float22_mul_vec2 (gbVec2 *out, float m[2][2], gbVec2 in);
363
+
364
+
365
+ GB_MATH_DEF void gb_mat3_identity (gbMat3 *m);
366
+ GB_MATH_DEF void gb_float33_identity(float m[3][3]);
367
+
368
+ GB_MATH_DEF void gb_mat3_transpose (gbMat3 *m);
369
+ GB_MATH_DEF void gb_mat3_mul (gbMat3 *out, gbMat3 *m1, gbMat3 *m2);
370
+ GB_MATH_DEF void gb_mat3_mul_vec3 (gbVec3 *out, gbMat3 *m, gbVec3 in);
371
+ GB_MATH_DEF void gb_mat3_inverse (gbMat3 *out, gbMat3 *in);
372
+ GB_MATH_DEF float gb_mat3_determinate(gbMat3 *m);
373
+
374
+
375
+ GB_MATH_DEF gbMat3 *gb_mat3_v(gbVec3 m[3]);
376
+ GB_MATH_DEF gbMat3 *gb_mat3_f(float m[3][3]);
377
+
378
+ GB_MATH_DEF gbFloat3 *gb_float33_m(gbMat3 *m);
379
+ GB_MATH_DEF gbFloat3 *gb_float33_v(gbVec3 m[3]);
380
+ GB_MATH_DEF gbFloat3 *gb_float33_9(float m[9]);
381
+
382
+ GB_MATH_DEF void gb_float33_transpose(float (*vec)[3]);
383
+ GB_MATH_DEF void gb_float33_mul (float (*out)[3], float (*mat1)[3], float (*mat2)[3]);
384
+ GB_MATH_DEF void gb_float33_mul_vec3 (gbVec3 *out, float m[3][3], gbVec3 in);
385
+
386
+ GB_MATH_DEF void gb_mat4_identity (gbMat4 *m);
387
+ GB_MATH_DEF void gb_float44_identity(float m[4][4]);
388
+
389
+ GB_MATH_DEF void gb_mat4_transpose (gbMat4 *m);
390
+ GB_MATH_DEF void gb_mat4_mul (gbMat4 *out, gbMat4 *m1, gbMat4 *m2);
391
+ GB_MATH_DEF void gb_mat4_mul_vec4 (gbVec4 *out, gbMat4 *m, gbVec4 in);
392
+ GB_MATH_DEF void gb_mat4_inverse (gbMat4 *out, gbMat4 *in);
393
+
394
+ GB_MATH_DEF gbMat4 *gb_mat4_v(gbVec4 m[4]);
395
+ GB_MATH_DEF gbMat4 *gb_mat4_f(float m[4][4]);
396
+
397
+ GB_MATH_DEF gbFloat4 *gb_float44_m (gbMat4 *m);
398
+ GB_MATH_DEF gbFloat4 *gb_float44_v (gbVec4 m[4]);
399
+ GB_MATH_DEF gbFloat4 *gb_float44_16(float m[16]);
400
+
401
+ GB_MATH_DEF void gb_float44_transpose(float (*vec)[4]);
402
+ GB_MATH_DEF void gb_float44_mul (float (*out)[4], float (*mat1)[4], float (*mat2)[4]);
403
+ GB_MATH_DEF void gb_float44_mul_vec4 (gbVec4 *out, float m[4][4], gbVec4 in);
404
+
405
+
406
+ GB_MATH_DEF void gb_mat4_translate (gbMat4 *out, gbVec3 v);
407
+ GB_MATH_DEF void gb_mat4_rotate (gbMat4 *out, gbVec3 v, float angle_radians);
408
+ GB_MATH_DEF void gb_mat4_scale (gbMat4 *out, gbVec3 v);
409
+ GB_MATH_DEF void gb_mat4_scalef (gbMat4 *out, float s);
410
+ GB_MATH_DEF void gb_mat4_ortho2d (gbMat4 *out, float left, float right, float bottom, float top);
411
+ GB_MATH_DEF void gb_mat4_ortho3d (gbMat4 *out, float left, float right, float bottom, float top, float z_near, float z_far);
412
+ GB_MATH_DEF void gb_mat4_perspective (gbMat4 *out, float fovy, float aspect, float z_near, float z_far);
413
+ GB_MATH_DEF void gb_mat4_infinite_perspective(gbMat4 *out, float fovy, float aspect, float z_near);
414
+
415
+ GB_MATH_DEF void gb_mat4_look_at(gbMat4 *out, gbVec3 eye, gbVec3 centre, gbVec3 up);
416
+
417
+
418
+
419
+ GB_MATH_DEF gbQuat gb_quat (float x, float y, float z, float w);
420
+ GB_MATH_DEF gbQuat gb_quatv (float e[4]);
421
+ GB_MATH_DEF gbQuat gb_quat_axis_angle (gbVec3 axis, float angle_radians);
422
+ GB_MATH_DEF gbQuat gb_quat_euler_angles(float pitch, float yaw, float roll);
423
+ GB_MATH_DEF gbQuat gb_quat_identity (void);
424
+
425
+ GB_MATH_DEF void gb_quat_add(gbQuat *d, gbQuat q0, gbQuat q1);
426
+ GB_MATH_DEF void gb_quat_sub(gbQuat *d, gbQuat q0, gbQuat q1);
427
+ GB_MATH_DEF void gb_quat_mul(gbQuat *d, gbQuat q0, gbQuat q1);
428
+ GB_MATH_DEF void gb_quat_div(gbQuat *d, gbQuat q0, gbQuat q1);
429
+
430
+ GB_MATH_DEF void gb_quat_mulf(gbQuat *d, gbQuat q, float s);
431
+ GB_MATH_DEF void gb_quat_divf(gbQuat *d, gbQuat q, float s);
432
+
433
+
434
+ GB_MATH_DEF void gb_quat_addeq(gbQuat *d, gbQuat q);
435
+ GB_MATH_DEF void gb_quat_subeq(gbQuat *d, gbQuat q);
436
+ GB_MATH_DEF void gb_quat_muleq(gbQuat *d, gbQuat q);
437
+ GB_MATH_DEF void gb_quat_diveq(gbQuat *d, gbQuat q);
438
+
439
+
440
+ GB_MATH_DEF void gb_quat_muleqf(gbQuat *d, float s);
441
+ GB_MATH_DEF void gb_quat_diveqf(gbQuat *d, float s);
442
+
443
+
444
+
445
+
446
+ GB_MATH_DEF float gb_quat_dot(gbQuat q0, gbQuat q1);
447
+ GB_MATH_DEF float gb_quat_mag(gbQuat q);
448
+
449
+ GB_MATH_DEF void gb_quat_norm (gbQuat *d, gbQuat q);
450
+ GB_MATH_DEF void gb_quat_conj (gbQuat *d, gbQuat q);
451
+ GB_MATH_DEF void gb_quat_inverse(gbQuat *d, gbQuat q);
452
+
453
+ GB_MATH_DEF void gb_quat_axis (gbVec3 *axis, gbQuat q);
454
+ GB_MATH_DEF float gb_quat_angle(gbQuat q);
455
+
456
+ GB_MATH_DEF float gb_quat_pitch(gbQuat q);
457
+ GB_MATH_DEF float gb_quat_yaw (gbQuat q);
458
+ GB_MATH_DEF float gb_quat_roll (gbQuat q);
459
+
460
+ /* NOTE(bill): Rotate v by q */
461
+ GB_MATH_DEF void gb_quat_rotate_vec3(gbVec3 *d, gbQuat q, gbVec3 v);
462
+ GB_MATH_DEF void gb_mat4_from_quat (gbMat4 *out, gbQuat q);
463
+ GB_MATH_DEF void gb_quat_from_mat4 (gbQuat *out, gbMat4 *m);
464
+
465
+
466
+
467
+ /* Interpolations */
468
+ GB_MATH_DEF float gb_lerp (float a, float b, float t);
469
+ GB_MATH_DEF float gb_unlerp (float t, float a, float b);
470
+ GB_MATH_DEF float gb_smooth_step (float a, float b, float t);
471
+ GB_MATH_DEF float gb_smoother_step(float a, float b, float t);
472
+
473
+ GB_MATH_DEF void gb_vec2_lerp(gbVec2 *d, gbVec2 a, gbVec2 b, float t);
474
+ GB_MATH_DEF void gb_vec3_lerp(gbVec3 *d, gbVec3 a, gbVec3 b, float t);
475
+ GB_MATH_DEF void gb_vec4_lerp(gbVec4 *d, gbVec4 a, gbVec4 b, float t);
476
+
477
+ GB_MATH_DEF void gb_quat_lerp (gbQuat *d, gbQuat a, gbQuat b, float t);
478
+ GB_MATH_DEF void gb_quat_nlerp(gbQuat *d, gbQuat a, gbQuat b, float t);
479
+ GB_MATH_DEF void gb_quat_slerp(gbQuat *d, gbQuat a, gbQuat b, float t);
480
+ GB_MATH_DEF void gb_quat_nquad(gbQuat *d, gbQuat p, gbQuat a, gbQuat b, gbQuat q, float t);
481
+ GB_MATH_DEF void gb_quat_squad(gbQuat *d, gbQuat p, gbQuat a, gbQuat b, gbQuat q, float t);
482
+ GB_MATH_DEF void gb_quat_slerp_approx(gbQuat *d, gbQuat a, gbQuat b, float t);
483
+ GB_MATH_DEF void gb_quat_squad_approx(gbQuat *d, gbQuat p, gbQuat a, gbQuat b, gbQuat q, float t);
484
+
485
+
486
+ /* Rects */
487
+ GB_MATH_DEF gbRect2 gb_rect2(gbVec2 pos, gbVec2 dim);
488
+ GB_MATH_DEF gbRect2 gb_rect2v(float v[4]);
489
+
490
+ GB_MATH_DEF gbRect3 gb_rect3(gbVec3 pos, gbVec3 dim);
491
+ GB_MATH_DEF gbRect3 gb_rect3v(float v[6]);
492
+
493
+ GB_MATH_DEF int gb_rect2_contains (gbRect2 a, float x, float y);
494
+ GB_MATH_DEF int gb_rect2_contains_vec2 (gbRect2 a, gbVec2 p);
495
+ GB_MATH_DEF int gb_rect2_intersects (gbRect2 a, gbRect2 b);
496
+ GB_MATH_DEF int gb_rect2_intersection_result(gbRect2 a, gbRect2 b, gbRect2 *intersection);
497
+
498
+
499
+ #ifndef GB_MURMUR64_DEFAULT_SEED
500
+ #define GB_MURMUR64_DEFAULT_SEED 0x9747b28c
501
+ #endif
502
+ /* Hashing */
503
+ GB_MATH_DEF gb_math_u64 gb_hash_murmur64(void const *key, size_t num_bytes, gb_math_u64 seed);
504
+
505
+ /* Random */
506
+ /* TODO(bill): Use a generator for the random numbers */
507
+ GB_MATH_DEF float gb_random_range_float(float min_inc, float max_inc);
508
+ GB_MATH_DEF int gb_random_range_int (int min_inc, int max_inc);
509
+ GB_MATH_DEF float gb_random01 (void);
510
+
511
+
512
+
513
+ #if defined(__cplusplus)
514
+ }
515
+ #endif
516
+
517
+ #if defined(__cplusplus)
518
+
519
+ /* TODO(bill): How should I apply GB_MATH_DEF to these operator overloads? */
520
+
521
+ inline bool operator==(gbVec2 a, gbVec2 b) { return (a.x == b.x) && (a.y == b.y); }
522
+ inline bool operator!=(gbVec2 a, gbVec2 b) { return !operator==(a, b); }
523
+
524
+ inline gbVec2 operator+(gbVec2 a) { return a; }
525
+ inline gbVec2 operator-(gbVec2 a) { gbVec2 r = {-a.x, -a.y}; return r; }
526
+
527
+ inline gbVec2 operator+(gbVec2 a, gbVec2 b) { gbVec2 r; gb_vec2_add(&r, a, b); return r; }
528
+ inline gbVec2 operator-(gbVec2 a, gbVec2 b) { gbVec2 r; gb_vec2_sub(&r, a, b); return r; }
529
+
530
+ inline gbVec2 operator*(gbVec2 a, float scalar) { gbVec2 r; gb_vec2_mul(&r, a, scalar); return r; }
531
+ inline gbVec2 operator*(float scalar, gbVec2 a) { return operator*(a, scalar); }
532
+
533
+ inline gbVec2 operator/(gbVec2 a, float scalar) { return operator*(a, 1.0f/scalar); }
534
+
535
+ /* Hadamard Product */
536
+ inline gbVec2 operator*(gbVec2 a, gbVec2 b) { gbVec2 r = {a.x*b.x, a.y*b.y}; return r; }
537
+ inline gbVec2 operator/(gbVec2 a, gbVec2 b) { gbVec2 r = {a.x/b.x, a.y/b.y}; return r; }
538
+
539
+ inline gbVec2 &operator+=(gbVec2 &a, gbVec2 b) { return (a = a + b); }
540
+ inline gbVec2 &operator-=(gbVec2 &a, gbVec2 b) { return (a = a - b); }
541
+ inline gbVec2 &operator*=(gbVec2 &a, float scalar) { return (a = a * scalar); }
542
+ inline gbVec2 &operator/=(gbVec2 &a, float scalar) { return (a = a / scalar); }
543
+
544
+
545
+ inline bool operator==(gbVec3 a, gbVec3 b) { return (a.x == b.x) && (a.y == b.y) && (a.z == b.z); }
546
+ inline bool operator!=(gbVec3 a, gbVec3 b) { return !operator==(a, b); }
547
+
548
+ inline gbVec3 operator+(gbVec3 a) { return a; }
549
+ inline gbVec3 operator-(gbVec3 a) { gbVec3 r = {-a.x, -a.y, -a.z}; return r; }
550
+
551
+ inline gbVec3 operator+(gbVec3 a, gbVec3 b) { gbVec3 r; gb_vec3_add(&r, a, b); return r; }
552
+ inline gbVec3 operator-(gbVec3 a, gbVec3 b) { gbVec3 r; gb_vec3_sub(&r, a, b); return r; }
553
+
554
+ inline gbVec3 operator*(gbVec3 a, float scalar) { gbVec3 r; gb_vec3_mul(&r, a, scalar); return r; }
555
+ inline gbVec3 operator*(float scalar, gbVec3 a) { return operator*(a, scalar); }
556
+
557
+ inline gbVec3 operator/(gbVec3 a, float scalar) { return operator*(a, 1.0f/scalar); }
558
+
559
+ /* Hadamard Product */
560
+ inline gbVec3 operator*(gbVec3 a, gbVec3 b) { gbVec3 r = {a.x*b.x, a.y*b.y, a.z*b.z}; return r; }
561
+ inline gbVec3 operator/(gbVec3 a, gbVec3 b) { gbVec3 r = {a.x/b.x, a.y/b.y, a.z/b.z}; return r; }
562
+
563
+ inline gbVec3 &operator+=(gbVec3 &a, gbVec3 b) { return (a = a + b); }
564
+ inline gbVec3 &operator-=(gbVec3 &a, gbVec3 b) { return (a = a - b); }
565
+ inline gbVec3 &operator*=(gbVec3 &a, float scalar) { return (a = a * scalar); }
566
+ inline gbVec3 &operator/=(gbVec3 &a, float scalar) { return (a = a / scalar); }
567
+
568
+
569
+ inline bool operator==(gbVec4 a, gbVec4 b) { return (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w); }
570
+ inline bool operator!=(gbVec4 a, gbVec4 b) { return !operator==(a, b); }
571
+
572
+ inline gbVec4 operator+(gbVec4 a) { return a; }
573
+ inline gbVec4 operator-(gbVec4 a) { gbVec4 r = {-a.x, -a.y, -a.z, -a.w}; return r; }
574
+
575
+ inline gbVec4 operator+(gbVec4 a, gbVec4 b) { gbVec4 r; gb_vec4_add(&r, a, b); return r; }
576
+ inline gbVec4 operator-(gbVec4 a, gbVec4 b) { gbVec4 r; gb_vec4_sub(&r, a, b); return r; }
577
+
578
+ inline gbVec4 operator*(gbVec4 a, float scalar) { gbVec4 r; gb_vec4_mul(&r, a, scalar); return r; }
579
+ inline gbVec4 operator*(float scalar, gbVec4 a) { return operator*(a, scalar); }
580
+
581
+ inline gbVec4 operator/(gbVec4 a, float scalar) { return operator*(a, 1.0f/scalar); }
582
+
583
+ /* Hadamard Product */
584
+ inline gbVec4 operator*(gbVec4 a, gbVec4 b) { gbVec4 r = {a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w}; return r; }
585
+ inline gbVec4 operator/(gbVec4 a, gbVec4 b) { gbVec4 r = {a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w}; return r; }
586
+
587
+ inline gbVec4 &operator+=(gbVec4 &a, gbVec4 b) { return (a = a + b); }
588
+ inline gbVec4 &operator-=(gbVec4 &a, gbVec4 b) { return (a = a - b); }
589
+ inline gbVec4 &operator*=(gbVec4 &a, float scalar) { return (a = a * scalar); }
590
+ inline gbVec4 &operator/=(gbVec4 &a, float scalar) { return (a = a / scalar); }
591
+
592
+
593
+ inline gbMat2 operator+(gbMat2 const &a, gbMat2 const &b) {
594
+ int i, j;
595
+ gbMat2 r = {0};
596
+ for (j = 0; j < 2; j++) {
597
+ for (i = 0; i < 2; i++)
598
+ r.e[2*j+i] = a.e[2*j+i] + b.e[2*j+i];
599
+ }
600
+ return r;
601
+ }
602
+
603
+ inline gbMat2 operator-(gbMat2 const &a, gbMat2 const &b) {
604
+ int i, j;
605
+ gbMat2 r = {0};
606
+ for (j = 0; j < 2; j++) {
607
+ for (i = 0; i < 2; i++)
608
+ r.e[2*j+i] = a.e[2*j+i] - b.e[2*j+i];
609
+ }
610
+ return r;
611
+ }
612
+
613
+ inline gbMat2 operator*(gbMat2 const &a, gbMat2 const &b) { gbMat2 r; gb_mat2_mul(&r, (gbMat2 *)&a, (gbMat2 *)&b); return r; }
614
+ inline gbVec2 operator*(gbMat2 const &a, gbVec2 v) { gbVec2 r; gb_mat2_mul_vec2(&r, (gbMat2 *)&a, v); return r; }
615
+ inline gbMat2 operator*(gbMat2 const &a, float scalar) {
616
+ gbMat2 r = {0};
617
+ int i;
618
+ for (i = 0; i < 2*2; i++) r.e[i] = a.e[i] * scalar;
619
+ return r;
620
+ }
621
+ inline gbMat2 operator*(float scalar, gbMat2 const &a) { return operator*(a, scalar); }
622
+ inline gbMat2 operator/(gbMat2 const &a, float scalar) { return operator*(a, 1.0f/scalar); }
623
+
624
+ inline gbMat2& operator+=(gbMat2& a, gbMat2 const &b) { return (a = a + b); }
625
+ inline gbMat2& operator-=(gbMat2& a, gbMat2 const &b) { return (a = a - b); }
626
+ inline gbMat2& operator*=(gbMat2& a, gbMat2 const &b) { return (a = a * b); }
627
+
628
+
629
+
630
+ inline gbMat3 operator+(gbMat3 const &a, gbMat3 const &b) {
631
+ int i, j;
632
+ gbMat3 r = {0};
633
+ for (j = 0; j < 3; j++) {
634
+ for (i = 0; i < 3; i++)
635
+ r.e[3*j+i] = a.e[3*j+i] + b.e[3*j+i];
636
+ }
637
+ return r;
638
+ }
639
+
640
+ inline gbMat3 operator-(gbMat3 const &a, gbMat3 const &b) {
641
+ int i, j;
642
+ gbMat3 r = {0};
643
+ for (j = 0; j < 3; j++) {
644
+ for (i = 0; i < 3; i++)
645
+ r.e[3*j+i] = a.e[3*j+i] - b.e[3*j+i];
646
+ }
647
+ return r;
648
+ }
649
+
650
+ inline gbMat3 operator*(gbMat3 const &a, gbMat3 const &b) { gbMat3 r; gb_mat3_mul(&r, (gbMat3 *)&a, (gbMat3 *)&b); return r; }
651
+ inline gbVec3 operator*(gbMat3 const &a, gbVec3 v) { gbVec3 r; gb_mat3_mul_vec3(&r, (gbMat3 *)&a, v); return r; } inline gbMat3 operator*(gbMat3 const &a, float scalar) {
652
+ gbMat3 r = {0};
653
+ int i;
654
+ for (i = 0; i < 3*3; i++) r.e[i] = a.e[i] * scalar;
655
+ return r;
656
+ }
657
+ inline gbMat3 operator*(float scalar, gbMat3 const &a) { return operator*(a, scalar); }
658
+ inline gbMat3 operator/(gbMat3 const &a, float scalar) { return operator*(a, 1.0f/scalar); }
659
+
660
+ inline gbMat3& operator+=(gbMat3& a, gbMat3 const &b) { return (a = a + b); }
661
+ inline gbMat3& operator-=(gbMat3& a, gbMat3 const &b) { return (a = a - b); }
662
+ inline gbMat3& operator*=(gbMat3& a, gbMat3 const &b) { return (a = a * b); }
663
+
664
+
665
+
666
+ inline gbMat4 operator+(gbMat4 const &a, gbMat4 const &b) {
667
+ int i, j;
668
+ gbMat4 r = {0};
669
+ for (j = 0; j < 4; j++) {
670
+ for (i = 0; i < 4; i++)
671
+ r.e[4*j+i] = a.e[4*j+i] + b.e[4*j+i];
672
+ }
673
+ return r;
674
+ }
675
+
676
+ inline gbMat4 operator-(gbMat4 const &a, gbMat4 const &b) {
677
+ int i, j;
678
+ gbMat4 r = {0};
679
+ for (j = 0; j < 4; j++) {
680
+ for (i = 0; i < 4; i++)
681
+ r.e[4*j+i] = a.e[4*j+i] - b.e[4*j+i];
682
+ }
683
+ return r;
684
+ }
685
+
686
+ inline gbMat4 operator*(gbMat4 const &a, gbMat4 const &b) { gbMat4 r; gb_mat4_mul(&r, (gbMat4 *)&a, (gbMat4 *)&b); return r; }
687
+ inline gbVec4 operator*(gbMat4 const &a, gbVec4 v) { gbVec4 r; gb_mat4_mul_vec4(&r, (gbMat4 *)&a, v); return r; }
688
+ inline gbMat4 operator*(gbMat4 const &a, float scalar) {
689
+ gbMat4 r = {0};
690
+ int i;
691
+ for (i = 0; i < 4*4; i++) r.e[i] = a.e[i] * scalar;
692
+ return r;
693
+ }
694
+ inline gbMat4 operator*(float scalar, gbMat4 const &a) { return operator*(a, scalar); }
695
+ inline gbMat4 operator/(gbMat4 const &a, float scalar) { return operator*(a, 1.0f/scalar); }
696
+
697
+ inline gbMat4& operator+=(gbMat4 &a, gbMat4 const &b) { return (a = a + b); }
698
+ inline gbMat4& operator-=(gbMat4 &a, gbMat4 const &b) { return (a = a - b); }
699
+ inline gbMat4& operator*=(gbMat4 &a, gbMat4 const &b) { return (a = a * b); }
700
+
701
+
702
+
703
+ inline bool operator==(gbQuat a, gbQuat b) { return a.xyzw == b.xyzw; }
704
+ inline bool operator!=(gbQuat a, gbQuat b) { return !operator==(a, b); }
705
+
706
+ inline gbQuat operator+(gbQuat q) { return q; }
707
+ inline gbQuat operator-(gbQuat q) { return gb_quat(-q.x, -q.y, -q.z, -q.w); }
708
+
709
+ inline gbQuat operator+(gbQuat a, gbQuat b) { gbQuat r; gb_quat_add(&r, a, b); return r; }
710
+ inline gbQuat operator-(gbQuat a, gbQuat b) { gbQuat r; gb_quat_sub(&r, a, b); return r; }
711
+
712
+ inline gbQuat operator*(gbQuat a, gbQuat b) { gbQuat r; gb_quat_mul(&r, a, b); return r; }
713
+ inline gbQuat operator*(gbQuat q, float s) { gbQuat r; gb_quat_mulf(&r, q, s); return r; }
714
+ inline gbQuat operator*(float s, gbQuat q) { return operator*(q, s); }
715
+ inline gbQuat operator/(gbQuat q, float s) { gbQuat r; gb_quat_divf(&r, q, s); return r; }
716
+
717
+ inline gbQuat &operator+=(gbQuat &a, gbQuat b) { gb_quat_addeq(&a, b); return a; }
718
+ inline gbQuat &operator-=(gbQuat &a, gbQuat b) { gb_quat_subeq(&a, b); return a; }
719
+ inline gbQuat &operator*=(gbQuat &a, gbQuat b) { gb_quat_muleq(&a, b); return a; }
720
+ inline gbQuat &operator/=(gbQuat &a, gbQuat b) { gb_quat_diveq(&a, b); return a; }
721
+
722
+ inline gbQuat &operator*=(gbQuat &a, float b) { gb_quat_muleqf(&a, b); return a; }
723
+ inline gbQuat &operator/=(gbQuat &a, float b) { gb_quat_diveqf(&a, b); return a; }
724
+
725
+ /* Rotate v by a */
726
+ inline gbVec3 operator*(gbQuat q, gbVec3 v) { gbVec3 r; gb_quat_rotate_vec3(&r, q, v); return r; }
727
+
728
+ #endif
729
+
730
+
731
+
732
+
733
+ #endif /* GB_MATH_INCLUDE_GB_MATH_H */
734
+
735
+ /****************************************************************
736
+ *
737
+ *
738
+ *
739
+ *
740
+ *
741
+ *
742
+ *
743
+ *
744
+ *
745
+ *
746
+ *
747
+ *
748
+ *
749
+ *
750
+ *
751
+ *
752
+ *
753
+ * Implementation
754
+ *
755
+ *
756
+ *
757
+ *
758
+ *
759
+ *
760
+ *
761
+ *
762
+ *
763
+ *
764
+ *
765
+ *
766
+ *
767
+ *
768
+ *
769
+ *
770
+ ****************************************************************/
771
+
772
+ #if defined(GB_MATH_IMPLEMENTATION) && !defined(GB_MATH_IMPLEMENTATION_DONE)
773
+ #define GB_MATH_IMPLEMENTATION_DONE
774
+
775
+ #if (defined(__GCC__) || defined(__GNUC__)) && !defined(__clang__)
776
+ #pragma GCC diagnostic push
777
+ #pragma GCC diagnostic ignored "-Wattributes"
778
+ #pragma GCC diagnostic ignored "-Wmissing-braces"
779
+ #elif __clang__
780
+ #pragma clang diagnostic push
781
+ #pragma clang diagnostic ignored "-Wattributes"
782
+ #pragma clang diagnostic ignored "-Wmissing-braces"
783
+ #endif
784
+
785
+
786
+ /* NOTE(bill): To remove the need for memcpy */
787
+ static void gb__memcpy_4byte(void *dest, void const *src, size_t size) {
788
+ size_t i;
789
+ unsigned int *d, *s;
790
+ d = (unsigned int *)dest;
791
+ s = (unsigned int *)src;
792
+ for (i = 0; i < size/4; i++) {
793
+ *d++ = *s++;
794
+ }
795
+ }
796
+
797
+
798
+ float gb_to_radians(float degrees) { return degrees * GB_MATH_TAU / 360.0f; }
799
+ float gb_to_degrees(float radians) { return radians * 360.0f / GB_MATH_TAU; }
800
+
801
+ float gb_angle_diff(float radians_a, float radians_b) {
802
+ float delta = gb_mod(radians_b-radians_a, GB_MATH_TAU);
803
+ delta = gb_mod(delta + 1.5f*GB_MATH_TAU, GB_MATH_TAU);
804
+ delta -= 0.5f*GB_MATH_TAU;
805
+ return delta;
806
+ }
807
+
808
+ float gb_copy_sign(float x, float y) {
809
+ int ix, iy;
810
+ ix = *(int *)&x;
811
+ iy = *(int *)&y;
812
+
813
+ ix &= 0x7fffffff;
814
+ ix |= iy & 0x80000000;
815
+ return *(float *)&ix;
816
+ }
817
+
818
+ float gb_remainder(float x, float y) {
819
+ return x - (gb_round(x/y)*y);
820
+ }
821
+
822
+ float gb_mod(float x, float y) {
823
+ float result;
824
+ y = gb_abs(y);
825
+ result = gb_remainder(gb_abs(x), y);
826
+ if (gb_sign(result)) result += y;
827
+ return gb_copy_sign(result, x);
828
+ }
829
+
830
+
831
+ float gb_quake_rsqrt(float a) {
832
+ union {
833
+ int i;
834
+ float f;
835
+ } t;
836
+ float x2;
837
+ float const three_halfs = 1.5f;
838
+
839
+ x2 = a * 0.5f;
840
+ t.f = a;
841
+ t.i = 0x5f375a86 - (t.i >> 1); /* What the fuck? */
842
+ t.f = t.f * (three_halfs - (x2 * t.f * t.f)); /* 1st iteration */
843
+ t.f = t.f * (three_halfs - (x2 * t.f * t.f)); /* 2nd iteration, this can be removed */
844
+
845
+ return t.f;
846
+ }
847
+
848
+
849
+ #if defined(GB_MATH_NO_MATH_H)
850
+ #if defined(_MSC_VER)
851
+
852
+ float gb_rsqrt(float a) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(a))); }
853
+ float gb_sqrt(float a) { return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(a))); };
854
+ float
855
+ gb_sin(float a)
856
+ {
857
+ static float const a0 = +1.91059300966915117e-31f;
858
+ static float const a1 = +1.00086760103908896f;
859
+ static float const a2 = -1.21276126894734565e-2f;
860
+ static float const a3 = -1.38078780785773762e-1f;
861
+ static float const a4 = -2.67353392911981221e-2f;
862
+ static float const a5 = +2.08026600266304389e-2f;
863
+ static float const a6 = -3.03996055049204407e-3f;
864
+ static float const a7 = +1.38235642404333740e-4f;
865
+ return a0 + a*(a1 + a*(a2 + a*(a3 + a*(a4 + a*(a5 + a*(a6 + a*a7))))));
866
+ }
867
+ float
868
+ gb_cos(float a)
869
+ {
870
+ static float const a0 = +1.00238601909309722f;
871
+ static float const a1 = -3.81919947353040024e-2f;
872
+ static float const a2 = -3.94382342128062756e-1f;
873
+ static float const a3 = -1.18134036025221444e-1f;
874
+ static float const a4 = +1.07123798512170878e-1f;
875
+ static float const a5 = -1.86637164165180873e-2f;
876
+ static float const a6 = +9.90140908664079833e-4f;
877
+ static float const a7 = -5.23022132118824778e-14f;
878
+ return a0 + a*(a1 + a*(a2 + a*(a3 + a*(a4 + a*(a5 + a*(a6 + a*a7))))));
879
+ }
880
+
881
+ float
882
+ gb_tan(float radians)
883
+ {
884
+ float rr = radians*radians;
885
+ float a = 9.5168091e-03f;
886
+ a *= rr;
887
+ a += 2.900525e-03f;
888
+ a *= rr;
889
+ a += 2.45650893e-02f;
890
+ a *= rr;
891
+ a += 5.33740603e-02f;
892
+ a *= rr;
893
+ a += 1.333923995e-01f;
894
+ a *= rr;
895
+ a += 3.333314036e-01f;
896
+ a *= rr;
897
+ a += 1.0f;
898
+ a *= radians;
899
+ return a;
900
+ }
901
+
902
+ float gb_arcsin(float a) { return gb_arctan2(a, gb_sqrt((1.0f + a) * (1.0f - a))); }
903
+ float gb_arccos(float a) { return gb_arctan2(gb_sqrt((1.0f + a) * (1.0 - a)), a); }
904
+
905
+ float
906
+ gb_arctan(float a)
907
+ {
908
+ float u = a*a;
909
+ float u2 = u*u;
910
+ float u3 = u2*u;
911
+ float u4 = u3*u;
912
+ float f = 1.0f+0.33288950512027f*u-0.08467922817644f*u2+0.03252232640125f*u3-0.00749305860992f*u4;
913
+ return a/f;
914
+ }
915
+
916
+ float
917
+ gb_arctan2(float y, float x)
918
+ {
919
+ if (gb_abs(x) > gb_abs(y)) {
920
+ float a = gb_arctan(y/x);
921
+ if (x > 0.0f)
922
+ return a;
923
+ else
924
+ return y > 0.0f ? a+GB_MATH_TAU_OVER_2:a-GB_MATH_TAU_OVER_2;
925
+ } else {
926
+ float a = gb_arctan(x/y);
927
+ if (x > 0.0f)
928
+ return y > 0.0f ? GB_MATH_TAU_OVER_4-a:-GB_MATH_TAU_OVER_4-a;
929
+ else
930
+ return y > 0.0f ? GB_MATH_TAU_OVER_4+a:-GB_MATH_TAU_OVER_4+a;
931
+ }
932
+ }
933
+
934
+ float
935
+ gb_exp(float a)
936
+ {
937
+ union { float f; int i; } u, v;
938
+ u.i = (int)(6051102 * a + 1056478197);
939
+ v.i = (int)(1056478197 - 6051102 * a);
940
+ return u.f / v.f;
941
+ }
942
+
943
+ float
944
+ gb_log(float a)
945
+ {
946
+ union { float f; int i; } u = {a};
947
+ return (u.i - 1064866805) * 8.262958405176314e-8f; /* 1 / 12102203.0; */
948
+ }
949
+
950
+ float
951
+ gb_pow(float a, float b)
952
+ {
953
+ int flipped = 0, e;
954
+ float f, r = 1.0f;
955
+ if (b < 0) {
956
+ flipped = 1;
957
+ b = -b;
958
+ }
959
+
960
+ e = (int)b;
961
+ f = gb_exp(b - e);
962
+
963
+ while (e) {
964
+ if (e & 1) r *= a;
965
+ a *= a;
966
+ e >>= 1;
967
+ }
968
+
969
+ r *= f;
970
+ return flipped ? 1.0f/r : r;
971
+ }
972
+
973
+ #else
974
+
975
+ float gb_rsqrt(float a) { return 1.0f/__builtin_sqrt(a); }
976
+ float gb_sqrt(float a) { return __builtin_sqrt(a); }
977
+ float gb_sin(float radians) { return __builtin_sinf(radians); }
978
+ float gb_cos(float radians) { return __builtin_cosf(radians); }
979
+ float gb_tan(float radians) { return __builtin_tanf(radians); }
980
+ float gb_arcsin(float a) { return __builtin_asinf(a); }
981
+ float gb_arccos(float a) { return __builtin_acosf(a); }
982
+ float gb_arctan(float a) { return __builtin_atanf(a); }
983
+ float gb_arctan2(float y, float x) { return __builtin_atan2f(y, x); }
984
+
985
+
986
+ float gb_exp(float x) { return __builtin_expf(x); }
987
+ float gb_log(float x) { return __builtin_logf(x); }
988
+
989
+ // TODO(bill): Should this be gb_exp(y * gb_log(x)) ???
990
+ float gb_pow(float x, float y) { return __builtin_powf(x, y); }
991
+
992
+ #endif
993
+
994
+ #else
995
+ float gb_rsqrt(float a) { return 1.0f/sqrtf(a); }
996
+ float gb_sqrt(float a) { return sqrtf(a); };
997
+ float gb_sin(float radians) { return sinf(radians); };
998
+ float gb_cos(float radians) { return cosf(radians); };
999
+ float gb_tan(float radians) { return tanf(radians); };
1000
+ float gb_arcsin(float a) { return asinf(a); };
1001
+ float gb_arccos(float a) { return acosf(a); };
1002
+ float gb_arctan(float a) { return atanf(a); };
1003
+ float gb_arctan2(float y, float x) { return atan2f(y, x); };
1004
+
1005
+ float gb_exp(float x) { return expf(x); }
1006
+ float gb_log(float x) { return logf(x); }
1007
+ float gb_pow(float x, float y) { return powf(x, y); }
1008
+ #endif
1009
+
1010
+ float gb_exp2(float x) { return gb_exp(GB_MATH_LOG_TWO * x); }
1011
+ float gb_log2(float x) { return gb_log(x) / GB_MATH_LOG_TWO; }
1012
+
1013
+
1014
+ float gb_fast_exp(float x) {
1015
+ /* NOTE(bill): Only works in the range -1 <= x <= +1 */
1016
+ float e = 1.0f + x*(1.0f + x*0.5f*(1.0f + x*0.3333333333f*(1.0f + x*0.25f*(1.0f + x*0.2f))));
1017
+ return e;
1018
+ }
1019
+
1020
+ float gb_fast_exp2(float x) { return gb_fast_exp(GB_MATH_LOG_TWO * x); }
1021
+
1022
+
1023
+
1024
+ float gb_round(float x) { return (float)((x >= 0.0f) ? gb_floor(x + 0.5f) : gb_ceil(x - 0.5f)); }
1025
+ float gb_floor(float x) { return (float)((x >= 0.0f) ? (int)x : (int)(x-0.9999999999999999f)); }
1026
+ float gb_ceil(float x) { return (float)((x < 0) ? (int)x : ((int)x)+1); }
1027
+
1028
+
1029
+
1030
+
1031
+
1032
+ float gb_half_to_float(gbHalf value) {
1033
+ union { unsigned int i; float f; } result;
1034
+ int s = (value >> 15) & 0x001;
1035
+ int e = (value >> 10) & 0x01f;
1036
+ int m = value & 0x3ff;
1037
+
1038
+ if (e == 0) {
1039
+ if (m == 0) {
1040
+ /* Plus or minus zero */
1041
+ result.i = (unsigned int)(s << 31);
1042
+ return result.f;
1043
+ } else {
1044
+ /* Denormalized number */
1045
+ while (!(m & 0x00000400)) {
1046
+ m <<= 1;
1047
+ e -= 1;
1048
+ }
1049
+
1050
+ e += 1;
1051
+ m &= ~0x00000400;
1052
+ }
1053
+ } else if (e == 31) {
1054
+ if (m == 0) {
1055
+ /* Positive or negative infinity */
1056
+ result.i = (unsigned int)((s << 31) | 0x7f800000);
1057
+ return result.f;
1058
+ } else {
1059
+ /* Nan */
1060
+ result.i = (unsigned int)((s << 31) | 0x7f800000 | (m << 13));
1061
+ return result.f;
1062
+ }
1063
+ }
1064
+
1065
+ e = e + (127 - 15);
1066
+ m = m << 13;
1067
+
1068
+ result.i = (unsigned int)((s << 31) | (e << 23) | m);
1069
+ return result.f;
1070
+ }
1071
+
1072
+ gbHalf gb_float_to_half(float value) {
1073
+ union { unsigned int i; float f; } v;
1074
+ int i, s, e, m;
1075
+
1076
+ v.f = value;
1077
+ i = (int)v.i;
1078
+
1079
+ s = (i >> 16) & 0x00008000;
1080
+ e = ((i >> 23) & 0x000000ff) - (127 - 15);
1081
+ m = i & 0x007fffff;
1082
+
1083
+
1084
+ if (e <= 0) {
1085
+ if (e < -10) return (gbHalf)s;
1086
+ m = (m | 0x00800000) >> (1 - e);
1087
+
1088
+ if (m & 0x00001000)
1089
+ m += 0x00002000;
1090
+
1091
+ return (gbHalf)(s | (m >> 13));
1092
+ } else if (e == 0xff - (127 - 15)) {
1093
+ if (m == 0) {
1094
+ return (gbHalf)(s | 0x7c00); /* NOTE(bill): infinity */
1095
+ } else {
1096
+ /* NOTE(bill): NAN */
1097
+ m >>= 13;
1098
+ return (gbHalf)(s | 0x7c00 | m | (m == 0));
1099
+ }
1100
+ } else {
1101
+ if (m & 0x00001000) {
1102
+ m += 0x00002000;
1103
+ if (m & 0x00800000) {
1104
+ m = 0;
1105
+ e += 1;
1106
+ }
1107
+ }
1108
+
1109
+ if (e > 30) {
1110
+ float volatile f = 1e12f;
1111
+ int j;
1112
+ for (j = 0; j < 10; j++)
1113
+ f *= f; /* NOTE(bill): Cause overflow */
1114
+
1115
+ return (gbHalf)(s | 0x7c00);
1116
+ }
1117
+
1118
+ return (gbHalf)(s | (e << 10) | (m >> 13));
1119
+ }
1120
+ }
1121
+
1122
+
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+ #define GB_VEC2_2OP(a,c,post) \
1129
+ a->x = c.x post; \
1130
+ a->y = c.y post;
1131
+
1132
+ #define GB_VEC2_3OP(a,b,op,c,post) \
1133
+ a->x = b.x op c.x post; \
1134
+ a->y = b.y op c.y post;
1135
+
1136
+ #define GB_VEC3_2OP(a,c,post) \
1137
+ a->x = c.x post; \
1138
+ a->y = c.y post; \
1139
+ a->z = c.z post;
1140
+
1141
+ #define GB_VEC3_3OP(a,b,op,c,post) \
1142
+ a->x = b.x op c.x post; \
1143
+ a->y = b.y op c.y post; \
1144
+ a->z = b.z op c.z post;
1145
+
1146
+ #define GB_VEC4_2OP(a,c,post) \
1147
+ a->x = c.x post; \
1148
+ a->y = c.y post; \
1149
+ a->z = c.z post; \
1150
+ a->w = c.w post;
1151
+
1152
+ #define GB_VEC4_3OP(a,b,op,c,post) \
1153
+ a->x = b.x op c.x post; \
1154
+ a->y = b.y op c.y post; \
1155
+ a->z = b.z op c.z post; \
1156
+ a->w = b.w op c.w post;
1157
+
1158
+
1159
+ gbVec2 gb_vec2_zero(void) { gbVec2 v = {0, 0}; return v; }
1160
+ gbVec2 gb_vec2(float x, float y) { gbVec2 v; v.x = x; v.y = y; return v; }
1161
+ gbVec2 gb_vec2v(float x[2]) { gbVec2 v; v.x = x[0]; v.y = x[1]; return v; }
1162
+
1163
+ gbVec3 gb_vec3_zero(void) { gbVec3 v = {0, 0, 0}; return v; }
1164
+ gbVec3 gb_vec3(float x, float y, float z) { gbVec3 v; v.x = x; v.y = y; v.z = z; return v; }
1165
+ gbVec3 gb_vec3v(float x[3]) { gbVec3 v; v.x = x[0]; v.y = x[1]; v.z = x[2]; return v; }
1166
+
1167
+ gbVec4 gb_vec4_zero(void) { gbVec4 v = {0, 0, 0, 0}; return v; }
1168
+ gbVec4 gb_vec4(float x, float y, float z, float w) { gbVec4 v; v.x = x; v.y = y; v.z = z; v.w = w; return v; }
1169
+ gbVec4 gb_vec4v(float x[4]) { gbVec4 v; v.x = x[0]; v.y = x[1]; v.z = x[2]; v.w = x[3]; return v; }
1170
+
1171
+
1172
+ void gb_vec2_add(gbVec2 *d, gbVec2 v0, gbVec2 v1) { GB_VEC2_3OP(d,v0,+,v1,+0); }
1173
+ void gb_vec2_sub(gbVec2 *d, gbVec2 v0, gbVec2 v1) { GB_VEC2_3OP(d,v0,-,v1,+0); }
1174
+ void gb_vec2_mul(gbVec2 *d, gbVec2 v, float s) { GB_VEC2_2OP(d,v,* s); }
1175
+ void gb_vec2_div(gbVec2 *d, gbVec2 v, float s) { GB_VEC2_2OP(d,v,/ s); }
1176
+
1177
+ void gb_vec3_add(gbVec3 *d, gbVec3 v0, gbVec3 v1) { GB_VEC3_3OP(d,v0,+,v1,+0); }
1178
+ void gb_vec3_sub(gbVec3 *d, gbVec3 v0, gbVec3 v1) { GB_VEC3_3OP(d,v0,-,v1,+0); }
1179
+ void gb_vec3_mul(gbVec3 *d, gbVec3 v, float s) { GB_VEC3_2OP(d,v,* s); }
1180
+ void gb_vec3_div(gbVec3 *d, gbVec3 v, float s) { GB_VEC3_2OP(d,v,/ s); }
1181
+
1182
+ void gb_vec4_add(gbVec4 *d, gbVec4 v0, gbVec4 v1) { GB_VEC4_3OP(d,v0,+,v1,+0); }
1183
+ void gb_vec4_sub(gbVec4 *d, gbVec4 v0, gbVec4 v1) { GB_VEC4_3OP(d,v0,-,v1,+0); }
1184
+ void gb_vec4_mul(gbVec4 *d, gbVec4 v, float s) { GB_VEC4_2OP(d,v,* s); }
1185
+ void gb_vec4_div(gbVec4 *d, gbVec4 v, float s) { GB_VEC4_2OP(d,v,/ s); }
1186
+
1187
+
1188
+ void gb_vec2_addeq(gbVec2 *d, gbVec2 v) { GB_VEC2_3OP(d,(*d),+,v,+0); }
1189
+ void gb_vec2_subeq(gbVec2 *d, gbVec2 v) { GB_VEC2_3OP(d,(*d),-,v,+0); }
1190
+ void gb_vec2_muleq(gbVec2 *d, float s) { GB_VEC2_2OP(d,(*d),* s); }
1191
+ void gb_vec2_diveq(gbVec2 *d, float s) { GB_VEC2_2OP(d,(*d),/ s); }
1192
+
1193
+ void gb_vec3_addeq(gbVec3 *d, gbVec3 v) { GB_VEC3_3OP(d,(*d),+,v,+0); }
1194
+ void gb_vec3_subeq(gbVec3 *d, gbVec3 v) { GB_VEC3_3OP(d,(*d),-,v,+0); }
1195
+ void gb_vec3_muleq(gbVec3 *d, float s) { GB_VEC3_2OP(d,(*d),* s); }
1196
+ void gb_vec3_diveq(gbVec3 *d, float s) { GB_VEC3_2OP(d,(*d),/ s); }
1197
+
1198
+ void gb_vec4_addeq(gbVec4 *d, gbVec4 v) { GB_VEC4_3OP(d,(*d),+,v,+0); }
1199
+ void gb_vec4_subeq(gbVec4 *d, gbVec4 v) { GB_VEC4_3OP(d,(*d),-,v,+0); }
1200
+ void gb_vec4_muleq(gbVec4 *d, float s) { GB_VEC4_2OP(d,(*d),* s); }
1201
+ void gb_vec4_diveq(gbVec4 *d, float s) { GB_VEC4_2OP(d,(*d),/ s); }
1202
+
1203
+
1204
+ #undef GB_VEC2_2OP
1205
+ #undef GB_VEC2_3OP
1206
+ #undef GB_VEC3_3OP
1207
+ #undef GB_VEC3_2OP
1208
+ #undef GB_VEC4_2OP
1209
+ #undef GB_VEC4_3OP
1210
+
1211
+
1212
+
1213
+
1214
+ float gb_vec2_dot(gbVec2 v0, gbVec2 v1) { return v0.x*v1.x + v0.y*v1.y; }
1215
+ float gb_vec3_dot(gbVec3 v0, gbVec3 v1) { return v0.x*v1.x + v0.y*v1.y + v0.z*v1.z; }
1216
+ float gb_vec4_dot(gbVec4 v0, gbVec4 v1) { return v0.x*v1.x + v0.y*v1.y + v0.z*v1.z + v0.w*v1.w; }
1217
+
1218
+ void gb_vec2_cross(float *d, gbVec2 v0, gbVec2 v1) { *d = v0.x*v1.y - v1.x*v0.y; }
1219
+ void gb_vec3_cross(gbVec3 *d, gbVec3 v0, gbVec3 v1) { d->x = v0.y*v1.z - v0.z*v1.y;
1220
+ d->y = v0.z*v1.x - v0.x*v1.z;
1221
+ d->z = v0.x*v1.y - v0.y*v1.x; }
1222
+
1223
+ float gb_vec2_mag2(gbVec2 v) { return gb_vec2_dot(v, v); }
1224
+ float gb_vec3_mag2(gbVec3 v) { return gb_vec3_dot(v, v); }
1225
+ float gb_vec4_mag2(gbVec4 v) { return gb_vec4_dot(v, v); }
1226
+
1227
+ /* TODO(bill): Create custom sqrt function */
1228
+ float gb_vec2_mag(gbVec2 v) { return gb_sqrt(gb_vec2_dot(v, v)); }
1229
+ float gb_vec3_mag(gbVec3 v) { return gb_sqrt(gb_vec3_dot(v, v)); }
1230
+ float gb_vec4_mag(gbVec4 v) { return gb_sqrt(gb_vec4_dot(v, v)); }
1231
+
1232
+ void gb_vec2_norm(gbVec2 *d, gbVec2 v) {
1233
+ float inv_mag = gb_rsqrt(gb_vec2_dot(v, v));
1234
+ gb_vec2_mul(d, v, inv_mag);
1235
+ }
1236
+ void gb_vec3_norm(gbVec3 *d, gbVec3 v) {
1237
+ float mag = gb_vec3_mag(v);
1238
+ gb_vec3_div(d, v, mag);
1239
+ }
1240
+ void gb_vec4_norm(gbVec4 *d, gbVec4 v) {
1241
+ float mag = gb_vec4_mag(v);
1242
+ gb_vec4_div(d, v, mag);
1243
+ }
1244
+
1245
+ void gb_vec2_norm0(gbVec2 *d, gbVec2 v) {
1246
+ float mag = gb_vec2_mag(v);
1247
+ if (mag > 0)
1248
+ gb_vec2_div(d, v, mag);
1249
+ else
1250
+ *d = gb_vec2_zero();
1251
+ }
1252
+ void gb_vec3_norm0(gbVec3 *d, gbVec3 v) {
1253
+ float mag = gb_vec3_mag(v);
1254
+ if (mag > 0)
1255
+ gb_vec3_div(d, v, mag);
1256
+ else
1257
+ *d = gb_vec3_zero();
1258
+ }
1259
+ void gb_vec4_norm0(gbVec4 *d, gbVec4 v) {
1260
+ float mag = gb_vec4_mag(v);
1261
+ if (mag > 0)
1262
+ gb_vec4_div(d, v, mag);
1263
+ else
1264
+ *d = gb_vec4_zero();
1265
+ }
1266
+
1267
+
1268
+ void gb_vec2_reflect(gbVec2 *d, gbVec2 i, gbVec2 n) {
1269
+ gbVec2 b = n;
1270
+ gb_vec2_muleq(&b, 2.0f*gb_vec2_dot(n, i));
1271
+ gb_vec2_sub(d, i, b);
1272
+ }
1273
+
1274
+ void gb_vec3_reflect(gbVec3 *d, gbVec3 i, gbVec3 n) {
1275
+ gbVec3 b = n;
1276
+ gb_vec3_muleq(&b, 2.0f*gb_vec3_dot(n, i));
1277
+ gb_vec3_sub(d, i, b);
1278
+ }
1279
+
1280
+ void gb_vec2_refract(gbVec2 *d, gbVec2 i, gbVec2 n, float eta) {
1281
+ gbVec2 a, b;
1282
+ float dv, k;
1283
+
1284
+ dv = gb_vec2_dot(n, i);
1285
+ k = 1.0f - eta*eta * (1.0f - dv*dv);
1286
+ gb_vec2_mul(&a, i, eta);
1287
+ gb_vec2_mul(&b, n, eta*dv*gb_sqrt(k));
1288
+ gb_vec2_sub(d, a, b);
1289
+ gb_vec2_muleq(d, (float)(k >= 0.0f));
1290
+ }
1291
+
1292
+ void gb_vec3_refract(gbVec3 *d, gbVec3 i, gbVec3 n, float eta) {
1293
+ gbVec3 a, b;
1294
+ float dv, k;
1295
+
1296
+ dv = gb_vec3_dot(n, i);
1297
+ k = 1.0f - eta*eta * (1.0f - dv*dv);
1298
+ gb_vec3_mul(&a, i, eta);
1299
+ gb_vec3_mul(&b, n, eta*dv*gb_sqrt(k));
1300
+ gb_vec3_sub(d, a, b);
1301
+ gb_vec3_muleq(d, (float)(k >= 0.0f));
1302
+ }
1303
+
1304
+
1305
+
1306
+
1307
+
1308
+ float gb_vec2_aspect_ratio(gbVec2 v) { return (v.y < 0.0001f) ? 0.0f : v.x/v.y; }
1309
+
1310
+
1311
+
1312
+
1313
+
1314
+ void gb_mat2_transpose(gbMat2 *m) { gb_float22_transpose(gb_float22_m(m)); }
1315
+ void gb_mat2_identity(gbMat2 *m) { gb_float22_identity(gb_float22_m(m)); }
1316
+ void gb_mat2_mul(gbMat2 *out, gbMat2 *m1, gbMat2 *m2) { gb_float22_mul(gb_float22_m(out), gb_float22_m(m1), gb_float22_m(m2)); }
1317
+
1318
+ void gb_float22_identity(float m[2][2]) {
1319
+ m[0][0] = 1; m[0][1] = 0;
1320
+ m[1][0] = 0; m[1][1] = 1;
1321
+ }
1322
+
1323
+ void gb_mat2_mul_vec2(gbVec2 *out, gbMat2 *m, gbVec2 in) { gb_float22_mul_vec2(out, gb_float22_m(m), in); }
1324
+
1325
+ gbMat2 *gb_mat2_v(gbVec2 m[2]) { return (gbMat2 *)m; }
1326
+ gbMat2 *gb_mat2_f(float m[2][2]) { return (gbMat2 *)m; }
1327
+
1328
+ gbFloat2 *gb_float22_m(gbMat2 *m) { return (gbFloat2 *)m; }
1329
+ gbFloat2 *gb_float22_v(gbVec2 m[2]) { return (gbFloat2 *)m; }
1330
+ gbFloat2 *gb_float22_4(float m[4]) { return (gbFloat2 *)m; }
1331
+
1332
+ void gb_float22_transpose(float (*vec)[2]) {
1333
+ int i, j;
1334
+ for (j = 0; j < 2; j++) {
1335
+ for (i = j + 1; i < 2; i++) {
1336
+ float t = vec[i][j];
1337
+ vec[i][j] = vec[j][i];
1338
+ vec[j][i] = t;
1339
+ }
1340
+ }
1341
+ }
1342
+
1343
+
1344
+
1345
+ void gb_float22_mul(float (*out)[2], float (*mat1)[2], float (*mat2)[2]) {
1346
+ int i, j;
1347
+ float temp1[2][2], temp2[2][2];
1348
+ if (mat1 == out) { gb__memcpy_4byte(temp1, mat1, sizeof(temp1)); mat1 = temp1; }
1349
+ if (mat2 == out) { gb__memcpy_4byte(temp2, mat2, sizeof(temp2)); mat2 = temp2; }
1350
+ for (j = 0; j < 2; j++) {
1351
+ for (i = 0; i < 2; i++) {
1352
+ out[j][i] = mat1[0][i]*mat2[j][0]
1353
+ + mat1[1][i]*mat2[j][1];
1354
+ }
1355
+ }
1356
+ }
1357
+
1358
+ void gb_float22_mul_vec2(gbVec2 *out, float m[2][2], gbVec2 v) {
1359
+ out->x = m[0][0]*v.x + m[1][0]*v.y;
1360
+ out->y = m[0][1]*v.x + m[1][1]*v.y;
1361
+ }
1362
+
1363
+ float gb_mat2_determinate(gbMat2 *m) {
1364
+ gbFloat2 *e = gb_float22_m(m);
1365
+ return e[0][0]*e[1][1] - e[1][0]*e[0][1];
1366
+ }
1367
+
1368
+ void gb_mat2_inverse(gbMat2 *out, gbMat2 *in) {
1369
+ gbFloat2 *o = gb_float22_m(out);
1370
+ gbFloat2 *i = gb_float22_m(in);
1371
+
1372
+ float ood = 1.0f / gb_mat2_determinate(in);
1373
+
1374
+ o[0][0] = +i[1][1] * ood;
1375
+ o[0][1] = -i[0][1] * ood;
1376
+ o[1][0] = -i[1][0] * ood;
1377
+ o[1][1] = +i[0][0] * ood;
1378
+ }
1379
+
1380
+
1381
+
1382
+
1383
+
1384
+
1385
+ void gb_mat3_transpose(gbMat3 *m) { gb_float33_transpose(gb_float33_m(m)); }
1386
+ void gb_mat3_identity(gbMat3 *m) { gb_float33_identity(gb_float33_m(m)); }
1387
+ void gb_mat3_mul(gbMat3 *out, gbMat3 *m1, gbMat3 *m2) { gb_float33_mul(gb_float33_m(out), gb_float33_m(m1), gb_float33_m(m2)); }
1388
+
1389
+ void gb_float33_identity(float m[3][3]) {
1390
+ m[0][0] = 1; m[0][1] = 0; m[0][2] = 0;
1391
+ m[1][0] = 0; m[1][1] = 1; m[1][2] = 0;
1392
+ m[2][0] = 0; m[2][1] = 0; m[2][2] = 1;
1393
+ }
1394
+
1395
+ void gb_mat3_mul_vec3(gbVec3 *out, gbMat3 *m, gbVec3 in) { gb_float33_mul_vec3(out, gb_float33_m(m), in); }
1396
+
1397
+ gbMat3 *gb_mat3_v(gbVec3 m[3]) { return (gbMat3 *)m; }
1398
+ gbMat3 *gb_mat3_f(float m[3][3]) { return (gbMat3 *)m; }
1399
+
1400
+ gbFloat3 *gb_float33_m(gbMat3 *m) { return (gbFloat3 *)m; }
1401
+ gbFloat3 *gb_float33_v(gbVec3 m[3]) { return (gbFloat3 *)m; }
1402
+ gbFloat3 *gb_float33_9(float m[9]) { return (gbFloat3 *)m; }
1403
+
1404
+ void gb_float33_transpose(float (*vec)[3]) {
1405
+ int i, j;
1406
+ for (j = 0; j < 3; j++) {
1407
+ for (i = j + 1; i < 3; i++) {
1408
+ float t = vec[i][j];
1409
+ vec[i][j] = vec[j][i];
1410
+ vec[j][i] = t;
1411
+ }
1412
+ }
1413
+ }
1414
+
1415
+ void gb_float33_mul(float (*out)[3], float (*mat1)[3], float (*mat2)[3]) {
1416
+ int i, j;
1417
+ float temp1[3][3], temp2[3][3];
1418
+ if (mat1 == out) { gb__memcpy_4byte(temp1, mat1, sizeof(temp1)); mat1 = temp1; }
1419
+ if (mat2 == out) { gb__memcpy_4byte(temp2, mat2, sizeof(temp2)); mat2 = temp2; }
1420
+ for (j = 0; j < 3; j++) {
1421
+ for (i = 0; i < 3; i++) {
1422
+ out[j][i] = mat1[0][i]*mat2[j][0]
1423
+ + mat1[1][i]*mat2[j][1]
1424
+ + mat1[2][i]*mat2[j][2];
1425
+ }
1426
+ }
1427
+ }
1428
+
1429
+ void gb_float33_mul_vec3(gbVec3 *out, float m[3][3], gbVec3 v) {
1430
+ out->x = m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z;
1431
+ out->y = m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z;
1432
+ out->z = m[0][2]*v.x + m[1][2]*v.y + m[2][2]*v.z;
1433
+ }
1434
+
1435
+
1436
+
1437
+ float gb_mat3_determinate(gbMat3 *m) {
1438
+ gbFloat3 *e = gb_float33_m(m);
1439
+ float d = +e[0][0] * (e[1][1] * e[2][2] - e[1][2] * e[2][1])
1440
+ -e[0][1] * (e[1][0] * e[2][2] - e[1][2] * e[2][0])
1441
+ +e[0][2] * (e[1][0] * e[2][1] - e[1][1] * e[2][0]);
1442
+ return d;
1443
+ }
1444
+
1445
+ void gb_mat3_inverse(gbMat3 *out, gbMat3 *in) {
1446
+ gbFloat3 *o = gb_float33_m(out);
1447
+ gbFloat3 *i = gb_float33_m(in);
1448
+
1449
+ float ood = 1.0f / gb_mat3_determinate(in);
1450
+
1451
+ o[0][0] = +(i[1][1] * i[2][2] - i[2][1] * i[1][2]) * ood;
1452
+ o[0][1] = -(i[1][0] * i[2][2] - i[2][0] * i[1][2]) * ood;
1453
+ o[0][2] = +(i[1][0] * i[2][1] - i[2][0] * i[1][1]) * ood;
1454
+ o[1][0] = -(i[0][1] * i[2][2] - i[2][1] * i[0][2]) * ood;
1455
+ o[1][1] = +(i[0][0] * i[2][2] - i[2][0] * i[0][2]) * ood;
1456
+ o[1][2] = -(i[0][0] * i[2][1] - i[2][0] * i[0][1]) * ood;
1457
+ o[2][0] = +(i[0][1] * i[1][2] - i[1][1] * i[0][2]) * ood;
1458
+ o[2][1] = -(i[0][0] * i[1][2] - i[1][0] * i[0][2]) * ood;
1459
+ o[2][2] = +(i[0][0] * i[1][1] - i[1][0] * i[0][1]) * ood;
1460
+ }
1461
+
1462
+
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+ void gb_mat4_transpose(gbMat4 *m) { gb_float44_transpose(gb_float44_m(m)); }
1473
+ void gb_mat4_identity(gbMat4 *m) { gb_float44_identity(gb_float44_m(m)); }
1474
+ void gb_mat4_mul(gbMat4 *out, gbMat4 *m1, gbMat4 *m2) { gb_float44_mul(gb_float44_m(out), gb_float44_m(m1), gb_float44_m(m2)); }
1475
+
1476
+ void gb_float44_identity(float m[4][4]) {
1477
+ m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
1478
+ m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
1479
+ m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
1480
+ m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
1481
+ }
1482
+
1483
+ void gb_mat4_mul_vec4(gbVec4 *out, gbMat4 *m, gbVec4 in) {
1484
+ gb_float44_mul_vec4(out, gb_float44_m(m), in);
1485
+ }
1486
+
1487
+ gbMat4 *gb_mat4_v(gbVec4 m[4]) { return (gbMat4 *)m; }
1488
+ gbMat4 *gb_mat4_f(float m[4][4]) { return (gbMat4 *)m; }
1489
+
1490
+ gbFloat4 *gb_float44_m(gbMat4 *m) { return (gbFloat4 *)m; }
1491
+ gbFloat4 *gb_float44_v(gbVec4 m[4]) { return (gbFloat4 *)m; }
1492
+ gbFloat4 *gb_float44_16(float m[16]) { return (gbFloat4 *)m; }
1493
+
1494
+ void gb_float44_transpose(float (*vec)[4]) {
1495
+ float tmp;
1496
+ tmp = vec[1][0]; vec[1][0] = vec[0][1]; vec[0][1] = tmp;
1497
+ tmp = vec[2][0]; vec[2][0] = vec[0][2]; vec[0][2] = tmp;
1498
+ tmp = vec[3][0]; vec[3][0] = vec[0][3]; vec[0][3] = tmp;
1499
+ tmp = vec[2][1]; vec[2][1] = vec[1][2]; vec[1][2] = tmp;
1500
+ tmp = vec[3][1]; vec[3][1] = vec[1][3]; vec[1][3] = tmp;
1501
+ tmp = vec[3][2]; vec[3][2] = vec[2][3]; vec[2][3] = tmp;
1502
+ }
1503
+
1504
+ void gb_float44_mul(float (*out)[4], float (*mat1)[4], float (*mat2)[4]) {
1505
+ int i, j;
1506
+ float temp1[4][4], temp2[4][4];
1507
+ if (mat1 == out) { gb__memcpy_4byte(temp1, mat1, sizeof(temp1)); mat1 = temp1; }
1508
+ if (mat2 == out) { gb__memcpy_4byte(temp2, mat2, sizeof(temp2)); mat2 = temp2; }
1509
+ for (j = 0; j < 4; j++) {
1510
+ for (i = 0; i < 4; i++) {
1511
+ out[j][i] = mat1[0][i]*mat2[j][0]
1512
+ + mat1[1][i]*mat2[j][1]
1513
+ + mat1[2][i]*mat2[j][2]
1514
+ + mat1[3][i]*mat2[j][3];
1515
+ }
1516
+ }
1517
+ }
1518
+
1519
+ void gb_float44_mul_vec4(gbVec4 *out, float m[4][4], gbVec4 v) {
1520
+ out->x = m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z + m[3][0]*v.w;
1521
+ out->y = m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z + m[3][1]*v.w;
1522
+ out->z = m[0][2]*v.x + m[1][2]*v.y + m[2][2]*v.z + m[3][2]*v.w;
1523
+ out->w = m[0][3]*v.x + m[1][3]*v.y + m[2][3]*v.z + m[3][3]*v.w;
1524
+ }
1525
+
1526
+ void gb_mat4_inverse(gbMat4 *out, gbMat4 *in) {
1527
+ gbFloat4 *o = gb_float44_m(out);
1528
+ gbFloat4 *m = gb_float44_m(in);
1529
+
1530
+ float ood;
1531
+
1532
+ float sf00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
1533
+ float sf01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
1534
+ float sf02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
1535
+ float sf03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
1536
+ float sf04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
1537
+ float sf05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
1538
+ float sf06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
1539
+ float sf07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
1540
+ float sf08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
1541
+ float sf09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
1542
+ float sf10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
1543
+ float sf11 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
1544
+ float sf12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
1545
+ float sf13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
1546
+ float sf14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
1547
+ float sf15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
1548
+ float sf16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
1549
+ float sf17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
1550
+ float sf18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
1551
+
1552
+ o[0][0] = +(m[1][1] * sf00 - m[1][2] * sf01 + m[1][3] * sf02);
1553
+ o[1][0] = -(m[1][0] * sf00 - m[1][2] * sf03 + m[1][3] * sf04);
1554
+ o[2][0] = +(m[1][0] * sf01 - m[1][1] * sf03 + m[1][3] * sf05);
1555
+ o[3][0] = -(m[1][0] * sf02 - m[1][1] * sf04 + m[1][2] * sf05);
1556
+
1557
+ o[0][1] = -(m[0][1] * sf00 - m[0][2] * sf01 + m[0][3] * sf02);
1558
+ o[1][1] = +(m[0][0] * sf00 - m[0][2] * sf03 + m[0][3] * sf04);
1559
+ o[2][1] = -(m[0][0] * sf01 - m[0][1] * sf03 + m[0][3] * sf05);
1560
+ o[3][1] = +(m[0][0] * sf02 - m[0][1] * sf04 + m[0][2] * sf05);
1561
+
1562
+ o[0][2] = +(m[0][1] * sf06 - m[0][2] * sf07 + m[0][3] * sf08);
1563
+ o[1][2] = -(m[0][0] * sf06 - m[0][2] * sf09 + m[0][3] * sf10);
1564
+ o[2][2] = +(m[0][0] * sf11 - m[0][1] * sf09 + m[0][3] * sf12);
1565
+ o[3][2] = -(m[0][0] * sf08 - m[0][1] * sf10 + m[0][2] * sf12);
1566
+
1567
+ o[0][3] = -(m[0][1] * sf13 - m[0][2] * sf14 + m[0][3] * sf15);
1568
+ o[1][3] = +(m[0][0] * sf13 - m[0][2] * sf16 + m[0][3] * sf17);
1569
+ o[2][3] = -(m[0][0] * sf14 - m[0][1] * sf16 + m[0][3] * sf18);
1570
+ o[3][3] = +(m[0][0] * sf15 - m[0][1] * sf17 + m[0][2] * sf18);
1571
+
1572
+ ood = 1.0f / (m[0][0] * o[0][0] +
1573
+ m[0][1] * o[1][0] +
1574
+ m[0][2] * o[2][0] +
1575
+ m[0][3] * o[3][0]);
1576
+
1577
+ o[0][0] *= ood;
1578
+ o[0][1] *= ood;
1579
+ o[0][2] *= ood;
1580
+ o[0][3] *= ood;
1581
+ o[1][0] *= ood;
1582
+ o[1][1] *= ood;
1583
+ o[1][2] *= ood;
1584
+ o[1][3] *= ood;
1585
+ o[2][0] *= ood;
1586
+ o[2][1] *= ood;
1587
+ o[2][2] *= ood;
1588
+ o[2][3] *= ood;
1589
+ o[3][0] *= ood;
1590
+ o[3][1] *= ood;
1591
+ o[3][2] *= ood;
1592
+ o[3][3] *= ood;
1593
+ }
1594
+
1595
+
1596
+
1597
+
1598
+
1599
+
1600
+
1601
+ void gb_mat4_translate(gbMat4 *out, gbVec3 v) {
1602
+ gb_mat4_identity(out);
1603
+ out->col[3].xyz = v;
1604
+ out->col[3].w = 1;
1605
+ }
1606
+
1607
+ void gb_mat4_rotate(gbMat4 *out, gbVec3 v, float angle_radians) {
1608
+ float c, s;
1609
+ gbVec3 axis, t;
1610
+ gbFloat4 *rot;
1611
+
1612
+ c = gb_cos(angle_radians);
1613
+ s = gb_sin(angle_radians);
1614
+
1615
+ gb_vec3_norm(&axis, v);
1616
+ gb_vec3_mul(&t, axis, 1.0f-c);
1617
+
1618
+ gb_mat4_identity(out);
1619
+ rot = gb_float44_m(out);
1620
+
1621
+ rot[0][0] = c + t.x*axis.x;
1622
+ rot[0][1] = 0 + t.x*axis.y + s*axis.z;
1623
+ rot[0][2] = 0 + t.x*axis.z - s*axis.y;
1624
+ rot[0][3] = 0;
1625
+
1626
+ rot[1][0] = 0 + t.y*axis.x - s*axis.z;
1627
+ rot[1][1] = c + t.y*axis.y;
1628
+ rot[1][2] = 0 + t.y*axis.z + s*axis.x;
1629
+ rot[1][3] = 0;
1630
+
1631
+ rot[2][0] = 0 + t.z*axis.x + s*axis.y;
1632
+ rot[2][1] = 0 + t.z*axis.y - s*axis.x;
1633
+ rot[2][2] = c + t.z*axis.z;
1634
+ rot[2][3] = 0;
1635
+ }
1636
+
1637
+ void gb_mat4_scale(gbMat4 *out, gbVec3 v) {
1638
+ gb_mat4_identity(out);
1639
+ out->e[0] = v.x;
1640
+ out->e[5] = v.y;
1641
+ out->e[10] = v.z;
1642
+ }
1643
+
1644
+ void gb_mat4_scalef(gbMat4 *out, float s) {
1645
+ gb_mat4_identity(out);
1646
+ out->e[0] = s;
1647
+ out->e[5] = s;
1648
+ out->e[10] = s;
1649
+ }
1650
+
1651
+
1652
+ void gb_mat4_ortho2d(gbMat4 *out, float left, float right, float bottom, float top) {
1653
+ gbFloat4 *m;
1654
+ gb_mat4_identity(out);
1655
+ m = gb_float44_m(out);
1656
+
1657
+ m[0][0] = 2.0f / (right - left);
1658
+ m[1][1] = 2.0f / (top - bottom);
1659
+ m[2][2] = -1.0f;
1660
+ m[3][0] = -(right + left) / (right - left);
1661
+ m[3][1] = -(top + bottom) / (top - bottom);
1662
+ }
1663
+
1664
+ void gb_mat4_ortho3d(gbMat4 *out, float left, float right, float bottom, float top, float z_near, float z_far) {
1665
+ gbFloat4 *m;
1666
+ gb_mat4_identity(out);
1667
+ m = gb_float44_m(out);
1668
+
1669
+ m[0][0] = +2.0f / (right - left);
1670
+ m[1][1] = +2.0f / (top - bottom);
1671
+ m[2][2] = -2.0f / (z_far - z_near);
1672
+ m[3][0] = -(right + left) / (right - left);
1673
+ m[3][1] = -(top + bottom) / (top - bottom);
1674
+ m[3][2] = -(z_far + z_near) / (z_far - z_near);
1675
+ }
1676
+
1677
+
1678
+ void gb_mat4_perspective(gbMat4 *out, float fovy, float aspect, float z_near, float z_far) {
1679
+ float tan_half_fovy = gb_tan(0.5f * fovy);
1680
+ gbMat4 zero_mat = {0};
1681
+ gbFloat4 *m = gb_float44_m(out);
1682
+ *out = zero_mat;
1683
+
1684
+ m[0][0] = 1.0f / (aspect*tan_half_fovy);
1685
+ m[1][1] = 1.0f / (tan_half_fovy);
1686
+ m[2][2] = -(z_far + z_near) / (z_far - z_near);
1687
+ m[2][3] = -1.0f;
1688
+ m[3][2] = -2.0f*z_far*z_near / (z_far - z_near);
1689
+ }
1690
+
1691
+ void gb_mat4_infinite_perspective(gbMat4 *out, float fovy, float aspect, float z_near) {
1692
+ float range = gb_tan(0.5f * fovy) * z_near;
1693
+ float left = -range * aspect;
1694
+ float right = range * aspect;
1695
+ float bottom = -range;
1696
+ float top = range;
1697
+ gbMat4 zero_mat = {0};
1698
+ gbFloat4 *m = gb_float44_m(out);
1699
+ *out = zero_mat;
1700
+
1701
+ m[0][0] = (2.0f*z_near) / (right - left);
1702
+ m[1][1] = (2.0f*z_near) / (top - bottom);
1703
+ m[2][2] = -1.0f;
1704
+ m[2][3] = -1.0f;
1705
+ m[3][2] = -2.0f*z_near;
1706
+ }
1707
+
1708
+ void gb_mat4_look_at(gbMat4 *out, gbVec3 eye, gbVec3 centre, gbVec3 up) {
1709
+ gbVec3 f, s, u;
1710
+ gbFloat4 *m;
1711
+
1712
+ gb_vec3_sub(&f, centre, eye);
1713
+ gb_vec3_norm(&f, f);
1714
+
1715
+ gb_vec3_cross(&s, f, up);
1716
+ gb_vec3_norm(&s, s);
1717
+
1718
+ gb_vec3_cross(&u, s, f);
1719
+
1720
+ gb_mat4_identity(out);
1721
+ m = gb_float44_m(out);
1722
+
1723
+ m[0][0] = +s.x;
1724
+ m[1][0] = +s.y;
1725
+ m[2][0] = +s.z;
1726
+
1727
+ m[0][1] = +u.x;
1728
+ m[1][1] = +u.y;
1729
+ m[2][1] = +u.z;
1730
+
1731
+ m[0][2] = -f.x;
1732
+ m[1][2] = -f.y;
1733
+ m[2][2] = -f.z;
1734
+
1735
+ m[3][0] = -gb_vec3_dot(s, eye);
1736
+ m[3][1] = -gb_vec3_dot(u, eye);
1737
+ m[3][2] = +gb_vec3_dot(f, eye);
1738
+ }
1739
+
1740
+
1741
+
1742
+
1743
+
1744
+
1745
+
1746
+
1747
+
1748
+
1749
+
1750
+
1751
+ gbQuat gb_quat(float x, float y, float z, float w) { gbQuat q; q.x = x; q.y = y; q.z = z; q.w = w; return q; }
1752
+ gbQuat gb_quatv(float e[4]) { gbQuat q; q.x = e[0]; q.y = e[1]; q.z = e[2]; q.w = e[3]; return q; }
1753
+
1754
+ gbQuat gb_quat_axis_angle(gbVec3 axis, float angle_radians) {
1755
+ gbQuat q;
1756
+ gb_vec3_norm(&q.xyz, axis);
1757
+ gb_vec3_muleq(&q.xyz, gb_sin(0.5f*angle_radians));
1758
+ q.w = gb_cos(0.5f*angle_radians);
1759
+ return q;
1760
+ }
1761
+
1762
+ gbQuat gb_quat_euler_angles(float pitch, float yaw, float roll) {
1763
+ /* TODO(bill): Do without multiplication, i.e. make it faster */
1764
+ gbQuat q, p, y, r;
1765
+ p = gb_quat_axis_angle(gb_vec3(1, 0, 0), pitch);
1766
+ y = gb_quat_axis_angle(gb_vec3(0, 1, 0), yaw);
1767
+ r = gb_quat_axis_angle(gb_vec3(0, 0, 1), roll);
1768
+
1769
+ gb_quat_mul(&q, y, p);
1770
+ gb_quat_muleq(&q, r);
1771
+
1772
+ return q;
1773
+ }
1774
+
1775
+ gbQuat gb_quat_identity(void) { gbQuat q = {0, 0, 0, 1}; return q; }
1776
+
1777
+
1778
+ void gb_quat_add(gbQuat *d, gbQuat q0, gbQuat q1) { gb_vec4_add(&d->xyzw, q0.xyzw, q1.xyzw); }
1779
+ void gb_quat_sub(gbQuat *d, gbQuat q0, gbQuat q1) { gb_vec4_sub(&d->xyzw, q0.xyzw, q1.xyzw); }
1780
+
1781
+ void gb_quat_mul(gbQuat *d, gbQuat q0, gbQuat q1) {
1782
+ d->x = q0.w * q1.x + q0.x * q1.w + q0.y * q1.z - q0.z * q1.y;
1783
+ d->y = q0.w * q1.y - q0.x * q1.z + q0.y * q1.w + q0.z * q1.x;
1784
+ d->z = q0.w * q1.z + q0.x * q1.y - q0.y * q1.x + q0.z * q1.w;
1785
+ d->w = q0.w * q1.w - q0.x * q1.x - q0.y * q1.y - q0.z * q1.z;
1786
+ }
1787
+
1788
+ void gb_quat_div(gbQuat *d, gbQuat q0, gbQuat q1){ gbQuat iq1; gb_quat_inverse(&iq1, q1); gb_quat_mul(d, q0, iq1); }
1789
+
1790
+ void gb_quat_mulf(gbQuat *d, gbQuat q0, float s) { gb_vec4_mul(&d->xyzw, q0.xyzw, s); }
1791
+ void gb_quat_divf(gbQuat *d, gbQuat q0, float s) { gb_vec4_div(&d->xyzw, q0.xyzw, s); }
1792
+
1793
+
1794
+ void gb_quat_addeq(gbQuat *d, gbQuat q) { gb_vec4_addeq(&d->xyzw, q.xyzw); }
1795
+ void gb_quat_subeq(gbQuat *d, gbQuat q) { gb_vec4_subeq(&d->xyzw, q.xyzw); }
1796
+ void gb_quat_muleq(gbQuat *d, gbQuat q) { gb_quat_mul(d, *d, q); }
1797
+ void gb_quat_diveq(gbQuat *d, gbQuat q) { gb_quat_div(d, *d, q); }
1798
+
1799
+
1800
+ void gb_quat_muleqf(gbQuat *d, float s) { gb_vec4_muleq(&d->xyzw, s); }
1801
+ void gb_quat_diveqf(gbQuat *d, float s) { gb_vec4_diveq(&d->xyzw, s); }
1802
+
1803
+ float gb_quat_dot(gbQuat q0, gbQuat q1) { float r = gb_vec3_dot(q0.xyz, q1.xyz) + q0.w*q1.w; return r; }
1804
+ float gb_quat_mag(gbQuat q) { float r = gb_sqrt(gb_quat_dot(q, q)); return r; }
1805
+
1806
+ void gb_quat_norm(gbQuat *d, gbQuat q) { gb_quat_divf(d, q, gb_quat_mag(q)); }
1807
+ void gb_quat_conj(gbQuat *d, gbQuat q) { d->xyz = gb_vec3(-q.x, -q.y, -q.z); d->w = q.w; }
1808
+ void gb_quat_inverse(gbQuat *d, gbQuat q) { gb_quat_conj(d, q); gb_quat_diveqf(d, gb_quat_dot(q, q)); }
1809
+
1810
+
1811
+ void gb_quat_axis(gbVec3 *axis, gbQuat q) {
1812
+ gbQuat n; gb_quat_norm(&n, q);
1813
+ gb_vec3_div(axis, n.xyz, gb_sin(gb_arccos(q.w)));
1814
+ }
1815
+
1816
+ float gb_quat_angle(gbQuat q) {
1817
+ float mag = gb_quat_mag(q);
1818
+ float c = q.w * (1.0f/mag);
1819
+ float angle = 2.0f*gb_arccos(c);
1820
+ return angle;
1821
+ }
1822
+
1823
+
1824
+ float gb_quat_roll(gbQuat q) { return gb_arctan2(2.0f*q.x*q.y + q.z*q.w, q.x*q.x + q.w*q.w - q.y*q.y - q.z*q.z); }
1825
+ float gb_quat_pitch(gbQuat q) { return gb_arctan2(2.0f*q.y*q.z + q.w*q.x, q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z); }
1826
+ float gb_quat_yaw(gbQuat q) { return gb_arcsin(-2.0f*(q.x*q.z - q.w*q.y)); }
1827
+
1828
+ void gb_quat_rotate_vec3(gbVec3 *d, gbQuat q, gbVec3 v) {
1829
+ /* gbVec3 t = 2.0f * cross(q.xyz, v);
1830
+ * *d = q.w*t + v + cross(q.xyz, t);
1831
+ */
1832
+ gbVec3 t, p;
1833
+ gb_vec3_cross(&t, q.xyz, v);
1834
+ gb_vec3_muleq(&t, 2.0f);
1835
+
1836
+ gb_vec3_cross(&p, q.xyz, t);
1837
+
1838
+ gb_vec3_mul(d, t, q.w);
1839
+ gb_vec3_addeq(d, v);
1840
+ gb_vec3_addeq(d, p);
1841
+ }
1842
+
1843
+
1844
+ void gb_mat4_from_quat(gbMat4 *out, gbQuat q) {
1845
+ gbFloat4 *m;
1846
+ gbQuat a;
1847
+ float xx, yy, zz,
1848
+ xy, xz, yz,
1849
+ wx, wy, wz;
1850
+
1851
+ gb_quat_norm(&a, q);
1852
+ xx = a.x*a.x; yy = a.y*a.y; zz = a.z*a.z;
1853
+ xy = a.x*a.y; xz = a.x*a.z; yz = a.y*a.z;
1854
+ wx = a.w*a.x; wy = a.w*a.y; wz = a.w*a.z;
1855
+
1856
+ gb_mat4_identity(out);
1857
+ m = gb_float44_m(out);
1858
+
1859
+ m[0][0] = 1.0f - 2.0f*(yy + zz);
1860
+ m[0][1] = 2.0f*(xy + wz);
1861
+ m[0][2] = 2.0f*(xz - wy);
1862
+
1863
+ m[1][0] = 2.0f*(xy - wz);
1864
+ m[1][1] = 1.0f - 2.0f*(xx + zz);
1865
+ m[1][2] = 2.0f*(yz + wx);
1866
+
1867
+ m[2][0] = 2.0f*(xz + wy);
1868
+ m[2][1] = 2.0f*(yz - wx);
1869
+ m[2][2] = 1.0f - 2.0f*(xx + yy);
1870
+ }
1871
+
1872
+ void gb_quat_from_mat4(gbQuat *out, gbMat4 *mat) {
1873
+ gbFloat4 *m;
1874
+ float four_x_squared_minus_1, four_y_squared_minus_1,
1875
+ four_z_squared_minus_1, four_w_squared_minus_1,
1876
+ four_biggest_squared_minus_1;
1877
+ int biggest_index = 0;
1878
+ float biggest_value, mult;
1879
+
1880
+ m = gb_float44_m(mat);
1881
+
1882
+ four_x_squared_minus_1 = m[0][0] - m[1][1] - m[2][2];
1883
+ four_y_squared_minus_1 = m[1][1] - m[0][0] - m[2][2];
1884
+ four_z_squared_minus_1 = m[2][2] - m[0][0] - m[1][1];
1885
+ four_w_squared_minus_1 = m[0][0] + m[1][1] + m[2][2];
1886
+
1887
+ four_biggest_squared_minus_1 = four_w_squared_minus_1;
1888
+ if (four_x_squared_minus_1 > four_biggest_squared_minus_1) {
1889
+ four_biggest_squared_minus_1 = four_x_squared_minus_1;
1890
+ biggest_index = 1;
1891
+ }
1892
+ if (four_y_squared_minus_1 > four_biggest_squared_minus_1) {
1893
+ four_biggest_squared_minus_1 = four_y_squared_minus_1;
1894
+ biggest_index = 2;
1895
+ }
1896
+ if (four_z_squared_minus_1 > four_biggest_squared_minus_1) {
1897
+ four_biggest_squared_minus_1 = four_z_squared_minus_1;
1898
+ biggest_index = 3;
1899
+ }
1900
+
1901
+ biggest_value = gb_sqrt(four_biggest_squared_minus_1 + 1.0f) * 0.5f;
1902
+ mult = 0.25f / biggest_value;
1903
+
1904
+ switch (biggest_index) {
1905
+ case 0:
1906
+ out->w = biggest_value;
1907
+ out->x = (m[1][2] - m[2][1]) * mult;
1908
+ out->y = (m[2][0] - m[0][2]) * mult;
1909
+ out->z = (m[0][1] - m[1][0]) * mult;
1910
+ break;
1911
+ case 1:
1912
+ out->w = (m[1][2] - m[2][1]) * mult;
1913
+ out->x = biggest_value;
1914
+ out->y = (m[0][1] + m[1][0]) * mult;
1915
+ out->z = (m[2][0] + m[0][2]) * mult;
1916
+ break;
1917
+ case 2:
1918
+ out->w = (m[2][0] - m[0][2]) * mult;
1919
+ out->x = (m[0][1] + m[1][0]) * mult;
1920
+ out->y = biggest_value;
1921
+ out->z = (m[1][2] + m[2][1]) * mult;
1922
+ break;
1923
+ case 3:
1924
+ out->w = (m[0][1] - m[1][0]) * mult;
1925
+ out->x = (m[2][0] + m[0][2]) * mult;
1926
+ out->y = (m[1][2] + m[2][1]) * mult;
1927
+ out->z = biggest_value;
1928
+ break;
1929
+ default:
1930
+ /* NOTE(bill): This shouldn't fucking happen!!! */
1931
+ break;
1932
+ }
1933
+
1934
+ }
1935
+
1936
+
1937
+
1938
+
1939
+
1940
+
1941
+ float gb_lerp (float a, float b, float t) { return a*(1.0f-t) + b*t; }
1942
+ float gb_unlerp (float t, float a, float b) { return (t-a)/(b-a); }
1943
+ float gb_smooth_step (float a, float b, float t) { float x = (t - a)/(b - a); return x*x*(3.0f - 2.0f*x); }
1944
+ float gb_smoother_step(float a, float b, float t) { float x = (t - a)/(b - a); return x*x*x*(x*(6.0f*x - 15.0f) + 10.0f); }
1945
+
1946
+
1947
+ #define GB_VEC_LERPN(N, d, a, b, t) \
1948
+ gbVec##N db; \
1949
+ gb_vec##N##_sub(&db, b, a); \
1950
+ gb_vec##N##_muleq(&db, t); \
1951
+ gb_vec##N##_add(d, a, db)
1952
+ void gb_vec2_lerp(gbVec2 *d, gbVec2 a, gbVec2 b, float t) { GB_VEC_LERPN(2, d, a, b, t); }
1953
+ void gb_vec3_lerp(gbVec3 *d, gbVec3 a, gbVec3 b, float t) { GB_VEC_LERPN(3, d, a, b, t); }
1954
+ void gb_vec4_lerp(gbVec4 *d, gbVec4 a, gbVec4 b, float t) { GB_VEC_LERPN(4, d, a, b, t); }
1955
+
1956
+ #undef GB_VEC_LERPN
1957
+
1958
+ void gb_quat_lerp(gbQuat *d, gbQuat a, gbQuat b, float t) { gb_vec4_lerp(&d->xyzw, a.xyzw, b.xyzw, t); }
1959
+ void gb_quat_nlerp(gbQuat *d, gbQuat a, gbQuat b, float t) { gb_quat_lerp(d, a, b, t); gb_quat_norm(d, *d); }
1960
+
1961
+ void gb_quat_slerp(gbQuat *d, gbQuat a, gbQuat b, float t) {
1962
+ gbQuat x, y, z;
1963
+ float cos_theta, angle;
1964
+ float s1, s0, is;
1965
+
1966
+ z = b;
1967
+ cos_theta = gb_quat_dot(a, b);
1968
+
1969
+ if (cos_theta < 0.0f) {
1970
+ z = gb_quat(-b.x, -b.y, -b.z, -b.w);
1971
+ cos_theta = -cos_theta;
1972
+ }
1973
+
1974
+ if (cos_theta > 1.0f) {
1975
+ /* NOTE(bill): Use lerp not nlerp as it's not a real angle or they are not normalized */
1976
+ gb_quat_lerp(d, a, b, t);
1977
+ }
1978
+
1979
+ angle = gb_arccos(cos_theta);
1980
+
1981
+ s1 = gb_sin((1.0f - t)*angle);
1982
+ s0 = gb_sin(t*angle);
1983
+ is = 1.0f/gb_sin(angle);
1984
+ gb_quat_mulf(&x, a, s1);
1985
+ gb_quat_mulf(&y, z, s0);
1986
+ gb_quat_add(d, x, y);
1987
+ gb_quat_muleqf(d, is);
1988
+ }
1989
+
1990
+ void gb_quat_slerp_approx(gbQuat *d, gbQuat a, gbQuat b, float t) {
1991
+ /* NOTE(bill): Derived by taylor expanding the geometric interpolation equation
1992
+ * Even works okay for nearly anti-parallel versors!!!
1993
+ */
1994
+ /* NOTE(bill): Extra interations cannot be used as they require angle^4 which is not worth it to approximate */
1995
+ float tp = t + (1.0f - gb_quat_dot(a, b))/3.0f * t*(-2.0f*t*t + 3.0f*t - 1.0f);
1996
+ gb_quat_nlerp(d, a, b, tp);
1997
+ }
1998
+
1999
+ void gb_quat_nquad(gbQuat *d, gbQuat p, gbQuat a, gbQuat b, gbQuat q, float t) {
2000
+ gbQuat x, y;
2001
+ gb_quat_nlerp(&x, p, q, t);
2002
+ gb_quat_nlerp(&y, a, b, t);
2003
+ gb_quat_nlerp(d, x, y, 2.0f*t*(1.0f-t));
2004
+ }
2005
+
2006
+ void gb_quat_squad(gbQuat *d, gbQuat p, gbQuat a, gbQuat b, gbQuat q, float t) {
2007
+ gbQuat x, y;
2008
+ gb_quat_slerp(&x, p, q, t);
2009
+ gb_quat_slerp(&y, a, b, t);
2010
+ gb_quat_slerp(d, x, y, 2.0f*t*(1.0f-t));
2011
+ }
2012
+
2013
+ void gb_quat_squad_approx(gbQuat *d, gbQuat p, gbQuat a, gbQuat b, gbQuat q, float t) {
2014
+ gbQuat x, y;
2015
+ gb_quat_slerp_approx(&x, p, q, t);
2016
+ gb_quat_slerp_approx(&y, a, b, t);
2017
+ gb_quat_slerp_approx(d, x, y, 2.0f*t*(1.0f-t));
2018
+ }
2019
+
2020
+
2021
+
2022
+
2023
+
2024
+
2025
+ gbRect2 gb_rect2(gbVec2 pos, gbVec2 dim) {
2026
+ gbRect2 r;
2027
+ r.pos = pos;
2028
+ r.dim = dim;
2029
+ return r;
2030
+ }
2031
+
2032
+ gbRect2 gb_rect2v(float v[4]) {
2033
+ gbRect2 r;
2034
+ r.pos = gb_vec2v(&v[0]);
2035
+ r.dim = gb_vec2v(&v[2]);
2036
+ return r;
2037
+ }
2038
+
2039
+ gbRect3 gb_rect3(gbVec3 pos, gbVec3 dim) {
2040
+ gbRect3 r;
2041
+ r.pos = pos;
2042
+ r.dim = dim;
2043
+ return r;
2044
+ }
2045
+
2046
+ gbRect3 gb_rect3v(float v[6]) {
2047
+ gbRect3 r;
2048
+ r.pos = gb_vec3v(&v[0]);
2049
+ r.dim = gb_vec3v(&v[3]);
2050
+ return r;
2051
+ }
2052
+
2053
+
2054
+ int gb_rect2_contains(gbRect2 a, float x, float y) {
2055
+ float min_x = gb_min(a.pos.x, a.pos.x+a.dim.x);
2056
+ float max_x = gb_max(a.pos.x, a.pos.x+a.dim.x);
2057
+ float min_y = gb_min(a.pos.y, a.pos.y+a.dim.y);
2058
+ float max_y = gb_max(a.pos.y, a.pos.y+a.dim.y);
2059
+ int result = (x >= min_x) & (x < max_x) & (y >= min_y) & (y < max_y);
2060
+ return result;
2061
+ }
2062
+
2063
+ int gb_rect2_contains_vec2(gbRect2 a, gbVec2 p) { return gb_rect2_contains(a, p.x, p.y); }
2064
+
2065
+ int gb_rect2_intersects(gbRect2 a, gbRect2 b) {
2066
+ gbRect2 r = {0};
2067
+ return gb_rect2_intersection_result(a, b, &r);
2068
+ }
2069
+
2070
+ int gb_rect2_intersection_result(gbRect2 a, gbRect2 b, gbRect2 *intersection) {
2071
+ float a_min_x = gb_min(a.pos.x, a.pos.x+a.dim.x);
2072
+ float a_max_x = gb_max(a.pos.x, a.pos.x+a.dim.x);
2073
+ float a_min_y = gb_min(a.pos.y, a.pos.y+a.dim.y);
2074
+ float a_max_y = gb_max(a.pos.y, a.pos.y+a.dim.y);
2075
+
2076
+ float b_min_x = gb_min(b.pos.x, b.pos.x+b.dim.x);
2077
+ float b_max_x = gb_max(b.pos.x, b.pos.x+b.dim.x);
2078
+ float b_min_y = gb_min(b.pos.y, b.pos.y+b.dim.y);
2079
+ float b_max_y = gb_max(b.pos.y, b.pos.y+b.dim.y);
2080
+
2081
+ float x0 = gb_max(a_min_x, b_min_x);
2082
+ float y0 = gb_max(a_min_y, b_min_y);
2083
+ float x1 = gb_min(a_max_x, b_max_x);
2084
+ float y1 = gb_min(a_max_y, b_max_y);
2085
+
2086
+ if ((x0 < x1) && (y0 < y1)) {
2087
+ gbRect2 r = gb_rect2(gb_vec2(x0, y0), gb_vec2(x1-x0, y1-y0));
2088
+ *intersection = r;
2089
+ return 1;
2090
+ } else {
2091
+ gbRect2 r = {0};
2092
+ *intersection = r;
2093
+ return 0;
2094
+ }
2095
+ }
2096
+
2097
+
2098
+ #if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
2099
+ gb_math_u64 gb_hash_murmur64(void const *key, size_t num_bytes, gb_math_u64 seed) {
2100
+ gb_math_u64 const m = 0xc6a4a7935bd1e995ULL;
2101
+ gb_math_u64 const r = 47;
2102
+
2103
+ gb_math_u64 h = seed ^ (num_bytes * m);
2104
+
2105
+ gb_math_u64 *data = (gb_math_u64 *)(key);
2106
+ gb_math_u64 *end = data + (num_bytes / 8);
2107
+ unsigned char *data2;
2108
+
2109
+ while (data != end) {
2110
+ gb_math_u64 k = *data++;
2111
+ k *= m;
2112
+ k ^= k >> r;
2113
+ k *= m;
2114
+ h ^= k;
2115
+ h *= m;
2116
+ }
2117
+
2118
+ data2 = (unsigned char *)data;
2119
+
2120
+ switch (num_bytes & 7) {
2121
+ case 7: h ^= (gb_math_u64)data2[6] << 48;
2122
+ case 6: h ^= (gb_math_u64)data2[5] << 40;
2123
+ case 5: h ^= (gb_math_u64)data2[4] << 32;
2124
+ case 4: h ^= (gb_math_u64)data2[3] << 24;
2125
+ case 3: h ^= (gb_math_u64)data2[2] << 16;
2126
+ case 2: h ^= (gb_math_u64)data2[1] << 8;
2127
+ case 1: h ^= (gb_math_u64)data2[0];
2128
+ h *= m;
2129
+ };
2130
+
2131
+ h ^= h >> r;
2132
+ h *= m;
2133
+ h ^= h >> r;
2134
+
2135
+ return h;
2136
+ }
2137
+ #else
2138
+ gb_math_u64 gb_hash_murmur64(void const *key, size_t num_bytes, gb_math_u64 seed) {
2139
+ gb_math_u32 const m = 0x5bd1e995;
2140
+ gb_math_u32 const r = 24;
2141
+
2142
+ gb_math_u64 h = 0;
2143
+ gb_math_u32 h1 = (gb_math_u32)seed ^ (gb_math_u32)num_bytes;
2144
+ gb_math_u32 h2 = (gb_math_u32)((gb_math_u64)seed >> 32);
2145
+
2146
+ gb_math_u32 *data = (gb_math_u32 *)key;
2147
+
2148
+
2149
+ while (num_bytes >= 8) {
2150
+ gb_math_u32 k1, k2;
2151
+ k1 = *data++;
2152
+ k1 *= m;
2153
+ k1 ^= k1 >> r;
2154
+ k1 *= m;
2155
+ h1 *= m;
2156
+ h1 ^= k1;
2157
+ num_bytes -= 4;
2158
+
2159
+ k2 = *data++;
2160
+ k2 *= m;
2161
+ k2 ^= k2 >> r;
2162
+ k2 *= m;
2163
+ h2 *= m;
2164
+ h2 ^= k2;
2165
+ num_bytes -= 4;
2166
+ }
2167
+
2168
+ if (num_bytes >= 4) {
2169
+ gb_math_u32 k1 = *data++;
2170
+ k1 *= m;
2171
+ k1 ^= k1 >> r;
2172
+ k1 *= m;
2173
+ h1 *= m;
2174
+ h1 ^= k1;
2175
+ num_bytes -= 4;
2176
+ }
2177
+
2178
+ switch (num_bytes) {
2179
+ gb_math_u32 a, b, c;
2180
+ case 3: c = data[2]; h2 ^= c << 16;
2181
+ case 2: b = data[1]; h2 ^= b << 8;
2182
+ case 1: a = data[0]; h2 ^= a << 0;
2183
+ h2 *= m;
2184
+ };
2185
+
2186
+ h1 ^= h2 >> 18;
2187
+ h1 *= m;
2188
+ h2 ^= h1 >> 22;
2189
+ h2 *= m;
2190
+ h1 ^= h2 >> 17;
2191
+ h1 *= m;
2192
+ h2 ^= h1 >> 19;
2193
+ h2 *= m;
2194
+
2195
+ h = (gb_math_u64)(h << 32) | (gb_math_u64)h2;
2196
+
2197
+ return h;
2198
+ }
2199
+ #endif
2200
+
2201
+
2202
+ /* TODO(bill): Make better random number generators */
2203
+ float gb_random_range_float(float min_inc, float max_inc) {
2204
+ int int_result = gb_random_range_int(0, 2147483646); /* Prevent integer overflow */
2205
+ float result = int_result/(float)2147483646;
2206
+ result *= max_inc - min_inc;
2207
+ result += min_inc;
2208
+ return result;
2209
+ }
2210
+
2211
+ int gb_random_range_int(int min_inc, int max_inc) {
2212
+ static unsigned int random_value = 0xdeadbeef; /* Random Value */
2213
+ unsigned int diff, result;
2214
+ random_value = random_value * 2147001325 + 715136305; /* BCPL generator */
2215
+ diff = max_inc - min_inc + 1;
2216
+ result = random_value % diff;
2217
+ result += min_inc;
2218
+
2219
+ return result;
2220
+ }
2221
+
2222
+ float gb_random01(void) {
2223
+ return gb_random_range_float(0.0f, 1.0f);
2224
+ }
2225
+
2226
+ #if defined(__GCC__) || defined(__GNUC__)
2227
+ #pragma GCC diagnostic pop
2228
+ #elif defined(__clang__)
2229
+ #pragma clang diagnostic pop
2230
+ #endif
2231
+
2232
+
2233
+
2234
+ #endif /* GB_MATH_IMPLEMENTATION */