Avara3D 0.2.0
C++ API reference
Math.h
1//
2// Math.h
3// avara3d
4//
5// Created by Morgan Davis on 12/7/25.
6// Copyright © 2026 Morgan K Davis. All rights reserved.
7//
8
9#ifndef AVARA3D_MATH_H
10#define AVARA3D_MATH_H
11
12#include <cstdint>
13#include <limits>
14#include <random>
15#include <string>
16
17namespace a3d::math {
18
19 struct f32vec2;
20 struct f32vec3;
21 struct f32vec4;
22 struct i32vec2;
23 struct i32vec3;
24 struct i32vec4;
25 struct u32vec2;
26 struct u32vec3;
27 struct u32vec4;
28 struct u8vec2;
29 struct u8vec3;
30 struct u8vec4;
31 struct f32mat2;
32 struct f32mat3;
33 struct f32mat4;
34 struct f32quat;
35
36 // [Types]
37
38 using f32 = float;
39 using u8 = std::uint8_t;
40 using i32 = std::int32_t;
41 using u32 = std::uint32_t;
42
43 using vec2 = f32vec2;
44 using vec3 = f32vec3;
45 using vec4 = f32vec4;
46
47 using ivec2 = i32vec2;
48 using ivec3 = i32vec3;
49 using ivec4 = i32vec4;
50
51 using uvec2 = u32vec2;
52 using uvec3 = u32vec3;
53 using uvec4 = u32vec4;
54
55 using mat2 = f32mat2;
56 using mat3 = f32mat3;
57 using mat4 = f32mat4;
58
59 using quat = f32quat;
60
61 // [Constants]
62
63 // floating-point limits
64
65 inline constexpr f32 F32_LOWEST = std::numeric_limits<f32>::lowest();
66 inline constexpr f32 F32_MAX = std::numeric_limits<f32>::max();
67 inline constexpr f32 F32_MIN_NORMAL = std::numeric_limits<f32>::min();
68 inline constexpr f32 F32_DENORM_MIN = std::numeric_limits<f32>::denorm_min();
69 inline constexpr f32 F32_EPSILON = std::numeric_limits<f32>::epsilon();
70 inline constexpr f32 F32_INFINITY = std::numeric_limits<f32>::infinity();
71 inline constexpr f32 F32_QUIET_NAN = std::numeric_limits<f32>::quiet_NaN();
72
73 // comparison
74
75 inline constexpr f32 F32_COMPARE_EPSILON = 1e-6f;
76
77 // mathematical constants
78
79 inline constexpr f32 E = 2.7182818284590452354f;
80 inline constexpr f32 LOG2_E = 1.4426950408889634074f;
81 inline constexpr f32 LOG10_E = 0.43429448190325182765f;
82 inline constexpr f32 LN_2 = 0.69314718055994530942f;
83 inline constexpr f32 LN_10 = 2.30258509299404568402f;
84
85 inline constexpr f32 PI = 3.14159265358979323846f;
86 inline constexpr f32 TWO_PI = 6.2831853071795864769f;
87 inline constexpr f32 PI_OVER_2 = 1.57079632679489661923f;
88 inline constexpr f32 PI_OVER_4 = 0.78539816339744830962f;
89 inline constexpr f32 ONE_OVER_PI = 0.31830988618379067154f;
90 inline constexpr f32 TWO_OVER_PI = 0.63661977236758134308f;
91 inline constexpr f32 TWO_OVER_SQRT_PI = 1.12837916709551257390f;
92
93 inline constexpr f32 SQRT_2 = 1.41421356237309504880f;
94 inline constexpr f32 ONE_OVER_SQRT_2 = 0.70710678118654752440f;
95
96 // [32-bit Float Vector]
97
98 struct f32vec2 {
99 union {
100 struct {
101 f32 x, y;
102 };
103
104 struct {
105 f32 s, t;
106 };
107 };
108
110 f32vec2(f32 x_, f32 y_);
111 explicit f32vec2(f32 n);
112 explicit f32vec2(const f32vec3& v);
113 explicit f32vec2(const f32vec4& v);
114 f32& operator[](std::size_t i);
115 const f32& operator[](std::size_t i) const;
116 };
118 struct f32vec3 {
119 union {
120 struct {
121 f32 x, y, z;
122 };
124 struct {
125 f32 r, g, b;
126 };
127
128 struct {
129 f32 s, t, p;
130 };
131
132 struct {
133 f32 pitch, yaw, roll;
134 };
135 };
136
138 f32vec3(f32 x_, f32 y_, f32 z_);
139 f32vec3(const f32vec2& v, f32 z_);
140 explicit f32vec3(f32 n);
141 explicit f32vec3(const f32vec2& v);
142 explicit f32vec3(const f32vec4& v);
143 f32& operator[](std::size_t i);
144 const f32& operator[](std::size_t i) const;
145 };
147 struct f32vec4 {
148 union {
149 struct {
150 f32 x, y, z, w;
151 };
153 struct {
154 f32 r, g, b, a;
155 };
156 };
157
159 f32vec4(f32 x_, f32 y_, f32 z_, f32 w_);
160 f32vec4(const f32vec3& v, f32 w_);
161 explicit f32vec4(f32 n);
162 explicit f32vec4(const f32vec2& v);
163 explicit f32vec4(const f32vec3& v);
164 f32& operator[](std::size_t i);
165 const f32& operator[](std::size_t i) const;
166 };
168 f32vec2 operator-(const f32vec2& v);
169 f32vec3 operator-(const f32vec3& v);
170 f32vec4 operator-(const f32vec4& v);
172 f32vec2 operator+(const f32vec2& a, const f32vec2& b);
173 f32vec3 operator+(const f32vec3& a, const f32vec3& b);
174 f32vec4 operator+(const f32vec4& a, const f32vec4& b);
175
176 f32vec2 operator-(const f32vec2& a, const f32vec2& b);
177 f32vec3 operator-(const f32vec3& a, const f32vec3& b);
178 f32vec4 operator-(const f32vec4& a, const f32vec4& b);
179
180 f32vec2 operator*(const f32vec2& a, const f32vec2& b);
181 f32vec3 operator*(const f32vec3& a, const f32vec3& b);
182 f32vec4 operator*(const f32vec4& a, const f32vec4& b);
183
184 f32vec2 operator*(const f32vec2& v, f32 s);
185 f32vec3 operator*(const f32vec3& v, f32 s);
186 f32vec4 operator*(const f32vec4& v, f32 s);
187
188 f32vec2 operator*(f32 s, const f32vec2& v);
189 f32vec3 operator*(f32 s, const f32vec3& v);
190 f32vec4 operator*(f32 s, const f32vec4& v);
191
192 f32vec2 operator/(const f32vec2& a, const f32vec2& b);
193 f32vec3 operator/(const f32vec3& a, const f32vec3& b);
194 f32vec4 operator/(const f32vec4& a, const f32vec4& b);
195
196 f32vec2 operator/(const f32vec2& v, f32 s);
197 f32vec3 operator/(const f32vec3& v, f32 s);
198 f32vec4 operator/(const f32vec4& v, f32 s);
199
200 f32vec2& operator+=(f32vec2& a, const f32vec2& b);
201 f32vec3& operator+=(f32vec3& a, const f32vec3& b);
202 f32vec4& operator+=(f32vec4& a, const f32vec4& b);
203
204 f32vec2& operator-=(f32vec2& a, const f32vec2& b);
205 f32vec3& operator-=(f32vec3& a, const f32vec3& b);
206 f32vec4& operator-=(f32vec4& a, const f32vec4& b);
207
208 f32vec2& operator*=(f32vec2& a, const f32vec2& b);
209 f32vec3& operator*=(f32vec3& a, const f32vec3& b);
210 f32vec4& operator*=(f32vec4& a, const f32vec4& b);
211
212 f32vec2& operator*=(f32vec2& v, f32 s);
213 f32vec3& operator*=(f32vec3& v, f32 s);
214 f32vec4& operator*=(f32vec4& v, f32 s);
215
216 f32vec2& operator/=(f32vec2& a, const f32vec2& b);
217 f32vec3& operator/=(f32vec3& a, const f32vec3& b);
218 f32vec4& operator/=(f32vec4& a, const f32vec4& b);
219
220 f32vec2& operator/=(f32vec2& v, f32 s);
221 f32vec3& operator/=(f32vec3& v, f32 s);
222 f32vec4& operator/=(f32vec4& v, f32 s);
223
224 bool operator==(const f32vec2& a, const f32vec2& b);
225 bool operator==(const f32vec3& a, const f32vec3& b);
226 bool operator==(const f32vec4& a, const f32vec4& b);
227
228 bool operator!=(const f32vec2& a, const f32vec2& b);
229 bool operator!=(const f32vec3& a, const f32vec3& b);
230 bool operator!=(const f32vec4& a, const f32vec4& b);
231
232 f32 min(const f32vec2& v);
233 f32 min(const f32vec3& v);
234 f32 min(const f32vec4& v);
235
236 f32 max(const f32vec2& v);
237 f32 max(const f32vec3& v);
238 f32 max(const f32vec4& v);
239
240 f32vec2 min(const f32vec2& a, const f32vec2& b);
241 f32vec3 min(const f32vec3& a, const f32vec3& b);
242 f32vec4 min(const f32vec4& a, const f32vec4& b);
243
244 f32vec2 max(const f32vec2& a, const f32vec2& b);
245 f32vec3 max(const f32vec3& a, const f32vec3& b);
246 f32vec4 max(const f32vec4& a, const f32vec4& b);
247
248 f32vec2 abs(const f32vec2& v);
249 f32vec3 abs(const f32vec3& v);
250 f32vec4 abs(const f32vec4& v);
251
252 f32 dot(const f32vec2& a, const f32vec2& b);
253 f32 dot(const f32vec3& a, const f32vec3& b);
254 f32 dot(const f32vec4& a, const f32vec4& b);
255
256 f32 length(const f32vec2& v);
257 f32 length(const f32vec3& v);
258 f32 length(const f32vec4& v);
259
260 f32vec2 normalize(const f32vec2& v);
261 f32vec3 normalize(const f32vec3& v);
262 f32vec4 normalize(const f32vec4& v);
263
264 f32vec3 cross(const f32vec3& a, const f32vec3& b);
265
266 std::string to_string(const f32vec2& v);
267 std::string to_string(const f32vec3& v);
268 std::string to_string(const f32vec4& v);
269
270 f32* value_ptr(f32vec2& v);
271 const f32* value_ptr(const f32vec2& v);
272 f32* value_ptr(f32vec3& v);
273 const f32* value_ptr(const f32vec3& v);
274 f32* value_ptr(f32vec4& v);
275 const f32* value_ptr(const f32vec4& v);
276
277 f32vec2 make_vec2(const f32* ptr);
278 f32vec3 make_vec3(const f32* ptr);
279 f32vec4 make_vec4(const f32* ptr);
280
281 // [Signed 32-bit Integer Vector]
282
283 struct i32vec2 {
284 i32 x, y;
285 i32vec2();
286 i32vec2(i32 x_, i32 y_);
287 explicit i32vec2(i32 n);
288 explicit i32vec2(const i32vec3& v);
289 explicit i32vec2(const i32vec4& v);
290 i32& operator[](std::size_t i);
291 const i32& operator[](std::size_t i) const;
292 };
293
294 struct i32vec3 {
295 i32 x, y, z;
297 i32vec3(i32 x_, i32 y_, i32 z_);
298 i32vec3(const i32vec2& v, i32 z_);
299 explicit i32vec3(i32 n);
300 explicit i32vec3(const i32vec2& v);
301 explicit i32vec3(const i32vec4& v);
302 i32& operator[](std::size_t i);
303 const i32& operator[](std::size_t i) const;
304 };
306 struct i32vec4 {
307 i32 x, y, z, w;
309 i32vec4(i32 x_, i32 y_, i32 z_, i32 w_);
310 i32vec4(const i32vec3& v, i32 w_);
311 explicit i32vec4(i32 n);
312 explicit i32vec4(const i32vec2& v);
313 explicit i32vec4(const i32vec3& v);
314 i32& operator[](std::size_t i);
315 const i32& operator[](std::size_t i) const;
316 };
318 i32vec2 operator-(const i32vec2& v);
319 i32vec3 operator-(const i32vec3& v);
320 i32vec4 operator-(const i32vec4& v);
322 i32vec2 operator+(const i32vec2& a, const i32vec2& b);
323 i32vec3 operator+(const i32vec3& a, const i32vec3& b);
324 i32vec4 operator+(const i32vec4& a, const i32vec4& b);
326 i32vec2 operator-(const i32vec2& a, const i32vec2& b);
327 i32vec3 operator-(const i32vec3& a, const i32vec3& b);
328 i32vec4 operator-(const i32vec4& a, const i32vec4& b);
329
330 i32vec2 operator*(const i32vec2& v, i32 s);
331 i32vec3 operator*(const i32vec3& v, i32 s);
332 i32vec4 operator*(const i32vec4& v, i32 s);
333 i32vec2 operator*(i32 s, const i32vec2& v);
334 i32vec3 operator*(i32 s, const i32vec3& v);
335 i32vec4 operator*(i32 s, const i32vec4& v);
336
337 i32vec2 operator/(const i32vec2& v, i32 s);
338 i32vec3 operator/(const i32vec3& v, i32 s);
339 i32vec4 operator/(const i32vec4& v, i32 s);
340
341 i32vec2& operator+=(i32vec2& a, const i32vec2& b);
342 i32vec3& operator+=(i32vec3& a, const i32vec3& b);
343 i32vec4& operator+=(i32vec4& a, const i32vec4& b);
344
345 i32vec2& operator-=(i32vec2& a, const i32vec2& b);
346 i32vec3& operator-=(i32vec3& a, const i32vec3& b);
347 i32vec4& operator-=(i32vec4& a, const i32vec4& b);
348
349 i32vec2& operator*=(i32vec2& v, i32 s);
350 i32vec3& operator*=(i32vec3& v, i32 s);
351 i32vec4& operator*=(i32vec4& v, i32 s);
352
353 i32vec2& operator/=(i32vec2& v, i32 s);
354 i32vec3& operator/=(i32vec3& v, i32 s);
355 i32vec4& operator/=(i32vec4& v, i32 s);
356
357 bool operator==(const i32vec2& a, const i32vec2& b);
358 bool operator==(const i32vec3& a, const i32vec3& b);
359 bool operator==(const i32vec4& a, const i32vec4& b);
360
361 bool operator!=(const i32vec2& a, const i32vec2& b);
362 bool operator!=(const i32vec3& a, const i32vec3& b);
363 bool operator!=(const i32vec4& a, const i32vec4& b);
364
365 f32 min(const i32vec2& v);
366 f32 min(const i32vec3& v);
367 f32 min(const i32vec4& v);
368
369 f32 max(const i32vec2& v);
370 f32 max(const i32vec3& v);
371 f32 max(const i32vec4& v);
372
373 i32vec2 min(const i32vec2& a, const i32vec2& b);
374 i32vec3 min(const i32vec3& a, const i32vec3& b);
375 i32vec4 min(const i32vec4& a, const i32vec4& b);
376
377 i32vec2 max(const i32vec2& a, const i32vec2& b);
378 i32vec3 max(const i32vec3& a, const i32vec3& b);
379 i32vec4 max(const i32vec4& a, const i32vec4& b);
380
381 i32 dot(const i32vec2& a, const i32vec2& b);
382 i32 dot(const i32vec3& a, const i32vec3& b);
383 i32 dot(const i32vec4& a, const i32vec4& b);
384
385 std::string to_string(const i32vec2& v);
386 std::string to_string(const i32vec3& v);
387 std::string to_string(const i32vec4& v);
388
389 i32* value_ptr(i32vec2& v);
390 const i32* value_ptr(const i32vec2& v);
391 i32* value_ptr(i32vec3& v);
392 const i32* value_ptr(const i32vec3& v);
393 i32* value_ptr(i32vec4& v);
394 const i32* value_ptr(const i32vec4& v);
395
396 i32vec2 make_vec2(const i32* ptr);
397 i32vec3 make_vec3(const i32* ptr);
398 i32vec4 make_vec4(const i32* ptr);
399
400 // [Unsigned 32-bit Integer Vector]
401
402 struct u32vec2 {
403 u32 x, y;
404 u32vec2();
405 u32vec2(u32 x_, u32 y_);
406 explicit u32vec2(u32 n);
407 explicit u32vec2(const u32vec3& v);
408 explicit u32vec2(const u32vec4& v);
409 u32& operator[](std::size_t i);
410 const u32& operator[](std::size_t i) const;
411 };
412
413 struct u32vec3 {
414 u32 x, y, z;
415 u32vec3();
416 u32vec3(u32 x_, u32 y_, u32 z_);
417 u32vec3(const u32vec2& v, u32 z_);
418 explicit u32vec3(u32 n);
419 explicit u32vec3(const u32vec2& v);
420 explicit u32vec3(const u32vec4& v);
421 u32& operator[](std::size_t i);
422 const u32& operator[](std::size_t i) const;
423 };
425 struct u32vec4 {
426 u32 x, y, z, w;
428 u32vec4(u32 x_, u32 y_, u32 z_, u32 w_);
429 u32vec4(const u32vec3& v, u32 w_);
430 explicit u32vec4(u32 n);
431 explicit u32vec4(const u32vec2& v);
432 explicit u32vec4(const u32vec3& v);
433 u32& operator[](std::size_t i);
434 const u32& operator[](std::size_t i) const;
435 };
437 u32vec2 operator+(const u32vec2& a, const u32vec2& b);
438 u32vec3 operator+(const u32vec3& a, const u32vec3& b);
439 u32vec4 operator+(const u32vec4& a, const u32vec4& b);
441 u32vec2 operator-(const u32vec2& a, const u32vec2& b);
442 u32vec3 operator-(const u32vec3& a, const u32vec3& b);
443 u32vec4 operator-(const u32vec4& a, const u32vec4& b);
445 u32vec2 operator*(const u32vec2& v, u32 s);
446 u32vec3 operator*(const u32vec3& v, u32 s);
447 u32vec4 operator*(const u32vec4& v, u32 s);
448 u32vec2 operator*(u32 s, const u32vec2& v);
449 u32vec3 operator*(u32 s, const u32vec3& v);
450 u32vec4 operator*(u32 s, const u32vec4& v);
451
452 u32vec2 operator/(const u32vec2& v, u32 s);
453 u32vec3 operator/(const u32vec3& v, u32 s);
454 u32vec4 operator/(const u32vec4& v, u32 s);
455
456 u32vec2& operator+=(u32vec2& a, const u32vec2& b);
457 u32vec3& operator+=(u32vec3& a, const u32vec3& b);
458 u32vec4& operator+=(u32vec4& a, const u32vec4& b);
459
460 u32vec2& operator-=(u32vec2& a, const u32vec2& b);
461 u32vec3& operator-=(u32vec3& a, const u32vec3& b);
462 u32vec4& operator-=(u32vec4& a, const u32vec4& b);
463
464 u32vec2& operator*=(u32vec2& v, u32 s);
465 u32vec3& operator*=(u32vec3& v, u32 s);
466 u32vec4& operator*=(u32vec4& v, u32 s);
467
468 u32vec2& operator/=(u32vec2& v, u32 s);
469 u32vec3& operator/=(u32vec3& v, u32 s);
470 u32vec4& operator/=(u32vec4& v, u32 s);
471
472 bool operator==(const u32vec2& a, const u32vec2& b);
473 bool operator==(const u32vec3& a, const u32vec3& b);
474 bool operator==(const u32vec4& a, const u32vec4& b);
475
476 bool operator!=(const u32vec2& a, const u32vec2& b);
477 bool operator!=(const u32vec3& a, const u32vec3& b);
478 bool operator!=(const u32vec4& a, const u32vec4& b);
479
480 f32 min(const u32vec2& v);
481 f32 min(const u32vec3& v);
482 f32 min(const u32vec4& v);
483
484 f32 max(const u32vec2& v);
485 f32 max(const u32vec3& v);
486 f32 max(const u32vec4& v);
487
488 u32vec2 min(const u32vec2& a, const u32vec2& b);
489 u32vec3 min(const u32vec3& a, const u32vec3& b);
490 u32vec4 min(const u32vec4& a, const u32vec4& b);
491
492 u32vec2 max(const u32vec2& a, const u32vec2& b);
493 u32vec3 max(const u32vec3& a, const u32vec3& b);
494 u32vec4 max(const u32vec4& a, const u32vec4& b);
495
496 u32 dot(const u32vec2& a, const u32vec2& b);
497 u32 dot(const u32vec3& a, const u32vec3& b);
498 u32 dot(const u32vec4& a, const u32vec4& b);
499
500 std::string to_string(const u32vec2& v);
501 std::string to_string(const u32vec3& v);
502 std::string to_string(const u32vec4& v);
503
504 u32* value_ptr(u32vec2& v);
505 const u32* value_ptr(const u32vec2& v);
506 u32* value_ptr(u32vec3& v);
507 const u32* value_ptr(const u32vec3& v);
508 u32* value_ptr(u32vec4& v);
509 const u32* value_ptr(const u32vec4& v);
510
511 u32vec2 make_vec2(const u32* ptr);
512 u32vec3 make_vec3(const u32* ptr);
513 u32vec4 make_vec4(const u32* ptr);
514
515 // [Unsigned 8-bit Integer Vector]
516
517 struct u8vec2 {
518 u8 x, y;
519 u8vec2();
520 u8vec2(u8 x_, u8 y_);
521 explicit u8vec2(u8 n);
522 explicit u8vec2(const u8vec3& v);
523 explicit u8vec2(const u8vec4& v);
524 u8& operator[](std::size_t i);
525 const u8& operator[](std::size_t i) const;
526 };
527
528 struct u8vec3 {
529 union {
530 struct {
531 u8 x, y, z;
532 };
533
534 struct {
535 u8 r, g, b;
536 };
537 };
540 u8vec3(u8 x_, u8 y_, u8 z_);
541 u8vec3(const u8vec2& v, u8 z_);
542 explicit u8vec3(u8 n);
543 explicit u8vec3(const u8vec2& v);
544 explicit u8vec3(const u8vec4& v);
545 u8& operator[](std::size_t i);
546 const u8& operator[](std::size_t i) const;
547 };
549 struct u8vec4 {
550 union {
551 struct {
552 u8 x, y, z, w;
553 };
554
555 struct {
556 u8 r, g, b, a;
557 };
558 };
561 u8vec4(u8 x_, u8 y_, u8 z_, u8 w_);
562 u8vec4(const u8vec3& v, u8 w_);
563 explicit u8vec4(u8 n);
564 explicit u8vec4(const u8vec2& v);
565 explicit u8vec4(const u8vec3& v);
566 u8& operator[](std::size_t i);
567 const u8& operator[](std::size_t i) const;
568 };
570 u8vec2 operator+(const u8vec2& a, const u8vec2& b);
571 u8vec3 operator+(const u8vec3& a, const u8vec3& b);
572 u8vec4 operator+(const u8vec4& a, const u8vec4& b);
574 u8vec2 operator-(const u8vec2& a, const u8vec2& b);
575 u8vec3 operator-(const u8vec3& a, const u8vec3& b);
576 u8vec4 operator-(const u8vec4& a, const u8vec4& b);
578 u8vec2 operator*(const u8vec2& v, f32 s); // saturates to [0, 255]
579 u8vec3 operator*(const u8vec3& v, f32 s); // saturates to [0, 255]
580 u8vec4 operator*(const u8vec4& v, f32 s); // saturates to [0, 255]
582 u8vec2 operator*(f32 s, const u8vec2& v); // saturates to [0, 255]
583 u8vec3 operator*(f32 s, const u8vec3& v); // saturates to [0, 255]
584 u8vec4 operator*(f32 s, const u8vec4& v); // saturates to [0, 255]
585
586 u8vec2 operator/(const u8vec2& v, f32 s); // saturates to [0, 255]
587 u8vec3 operator/(const u8vec3& v, f32 s); // saturates to [0, 255]
588 u8vec4 operator/(const u8vec4& v, f32 s); // saturates to [0, 255]
589
590 u8vec2& operator+=(u8vec2& a, const u8vec2& b);
591 u8vec3& operator+=(u8vec3& a, const u8vec3& b);
592 u8vec4& operator+=(u8vec4& a, const u8vec4& b);
593
594 u8vec2& operator-=(u8vec2& a, const u8vec2& b);
595 u8vec3& operator-=(u8vec3& a, const u8vec3& b);
596 u8vec4& operator-=(u8vec4& a, const u8vec4& b);
597
598 u8vec2& operator*=(u8vec2& v, f32 s); // saturates to [0, 255]
599 u8vec3& operator*=(u8vec3& v, f32 s); // saturates to [0, 255]
600 u8vec4& operator*=(u8vec4& v, f32 s); // saturates to [0, 255]
601
602 u8vec2& operator/=(u8vec2& v, f32 s); // saturates to [0, 255]
603 u8vec3& operator/=(u8vec3& v, f32 s); // saturates to [0, 255]
604 u8vec4& operator/=(u8vec4& v, f32 s); // saturates to [0, 255]
605
606 bool operator==(const u8vec2& a, const u8vec2& b);
607 bool operator==(const u8vec3& a, const u8vec3& b);
608 bool operator==(const u8vec4& a, const u8vec4& b);
609
610 bool operator!=(const u8vec2& a, const u8vec2& b);
611 bool operator!=(const u8vec3& a, const u8vec3& b);
612 bool operator!=(const u8vec4& a, const u8vec4& b);
613
614 f32 min(const u8vec2& v);
615 f32 min(const u8vec3& v);
616 f32 min(const u8vec4& v);
617
618 f32 max(const u8vec2& v);
619 f32 max(const u8vec3& v);
620 f32 max(const u8vec4& v);
621
622 u8vec2 min(const u8vec2& a, const u8vec2& b);
623 u8vec3 min(const u8vec3& a, const u8vec3& b);
624 u8vec4 min(const u8vec4& a, const u8vec4& b);
625
626 u8vec2 max(const u8vec2& a, const u8vec2& b);
627 u8vec3 max(const u8vec3& a, const u8vec3& b);
628 u8vec4 max(const u8vec4& a, const u8vec4& b);
629
630 u8* value_ptr(u8vec2& v);
631 const u8* value_ptr(const u8vec2& v);
632
633 u8* value_ptr(u8vec3& v);
634 const u8* value_ptr(const u8vec3& v);
635
636 u8* value_ptr(u8vec4& v);
637 const u8* value_ptr(const u8vec4& v);
638
639 u8vec2 make_vec2(const u8* ptr);
640 u8vec3 make_vec3(const u8* ptr);
641 u8vec4 make_vec4(const u8* ptr);
642
643 std::string to_string(const u8vec2& v);
644 std::string to_string(const u8vec3& v);
645 std::string to_string(const u8vec4& v);
646
647 // [32-bit Float Matrix]
648
649 struct f32mat2 {
650 f32vec2 c0, c1;
651 f32mat2();
652 explicit f32mat2(f32 diag);
653 f32mat2(const f32vec2& c0_, const f32vec2& c1_);
654 f32vec2& operator[](std::size_t i);
655 const f32vec2& operator[](std::size_t i) const;
656 };
657
658 struct f32mat3 {
659 f32vec3 c0, c1, c2;
660 f32mat3();
661 explicit f32mat3(f32 diag);
662 f32mat3(const f32vec3& c0_, const f32vec3& c1_, const f32vec3& c2_);
663 f32mat3(const f32mat4& m);
664 f32vec3& operator[](std::size_t i);
665 const f32vec3& operator[](std::size_t i) const;
666 };
667
668 struct f32mat4 {
669 f32vec4 c0, c1, c2, c3;
671 explicit f32mat4(f32 diag);
672 f32mat4(const f32vec4& c0_, const f32vec4& c1_, const f32vec4& c2_, const f32vec4& c3_);
673 explicit f32mat4(const f32mat3& m);
674 f32vec4& operator[](std::size_t i);
675 const f32vec4& operator[](std::size_t i) const;
676 };
677
678 f32mat2 operator-(const f32mat2& m);
679 f32mat3 operator-(const f32mat3& m);
680 f32mat4 operator-(const f32mat4& m);
682 f32vec2 operator*(const f32mat2& m, const f32vec2& v);
683 f32vec3 operator*(const f32mat3& m, const f32vec3& v);
684 f32vec4 operator*(const f32mat4& m, const f32vec4& v);
686 f32mat2 operator*(const f32mat2& a, const f32mat2& b);
687 f32mat3 operator*(const f32mat3& a, const f32mat3& b);
688 f32mat4 operator*(const f32mat4& a, const f32mat4& b);
690 f32mat2& operator*=(f32mat2& a, const f32mat2& b);
691 f32mat3& operator*=(f32mat3& a, const f32mat3& b);
692 f32mat4& operator*=(f32mat4& a, const f32mat4& b);
694 bool operator==(const f32mat2& a, const f32mat2& b);
695 bool operator!=(const f32mat2& a, const f32mat2& b);
696
697 bool operator==(const f32mat3& a, const f32mat3& b);
698 bool operator!=(const f32mat3& a, const f32mat3& b);
699
700 bool operator==(const f32mat4& a, const f32mat4& b);
701 bool operator!=(const f32mat4& a, const f32mat4& b);
702
703 f32mat2 abs(const f32mat2& m);
704 f32mat3 abs(const f32mat3& m);
705 f32mat4 abs(const f32mat4& m);
706
707 f32mat2 transpose(const f32mat2& m);
708 f32mat3 transpose(const f32mat3& m);
709 f32mat4 transpose(const f32mat4& m);
710
711 f32 determinant(const f32mat2& m);
712 f32 determinant(const f32mat3& m);
713 f32 determinant(const f32mat4& m);
714
715 f32mat2 inverse(const f32mat2& m);
716 f32mat3 inverse(const f32mat3& m);
717 f32mat4 inverse(const f32mat4& m);
718
719 f32vec3 translation(const f32mat4& m);
720
721 f32mat4 translate(const f32mat4& m, const f32vec3& v);
722 f32mat4 rotate(const f32mat4& m, f32 angle, const f32vec3& v);
723 f32mat4 scale(const f32mat4& m, const f32vec3& v);
724 f32mat4 scale(const f32mat4& m, f32 s);
725
726 std::string to_string(const f32mat2& m, unsigned pad = 10);
727 std::string to_string(const f32mat3& m, unsigned pad = 10);
728 std::string to_string(const f32mat4& m, unsigned pad = 10);
729
730 f32* value_ptr(f32mat2& m);
731 const f32* value_ptr(const f32mat2& m);
732 f32* value_ptr(f32mat3& m);
733 const f32* value_ptr(const f32mat3& m);
734 f32* value_ptr(f32mat4& m);
735 const f32* value_ptr(const f32mat4& m);
736
737 f32mat2 make_mat2(const f32* ptr);
738 f32mat3 make_mat3(const f32* ptr);
739 f32mat4 make_mat4(const f32* ptr);
740
741 // [32-bit Float Quaternion]
742
743 struct f32quat {
744 f32 w, x, y, z;
745 f32quat();
746 f32quat(f32 w_, f32 x_, f32 y_, f32 z_);
747 explicit f32quat(f32 s);
748 f32& operator[](std::size_t i);
749 const f32& operator[](std::size_t i) const;
750 };
751
752 f32quat operator*(const f32quat& a, const f32quat& b);
753 f32quat operator*(const f32quat& q, f32 s);
754 f32quat operator*(f32 s, const f32quat& q);
755
756 f32quat& operator*=(f32quat& a, const f32quat& b);
757 f32quat& operator*=(f32quat& q, f32 s);
758
759 bool operator==(const f32quat& a, const f32quat& b);
760 bool operator!=(const f32quat& a, const f32quat& b);
761
762 f32 dot(const f32quat& a, const f32quat& b);
763 f32 length(const f32quat& q);
764 f32quat normalize(const f32quat& q);
765 f32quat conjugate(const f32quat& q);
766 f32quat inverse(const f32quat& q);
768 f32vec3 rotate(const f32quat& q, const f32vec3& v);
769 f32vec3 operator*(const f32quat& q, const f32vec3& v);
771 f32quat quaternion(const f32vec3& axis, f32 angle);
772 f32vec4 axis_angle(const f32quat& q);
773
774 f32quat quaternion(const f32vec3& euler_angles); // pitch/yaw/roll to quaternion, y–x–z order
775 f32vec3 euler_angles(const f32quat& q); // pitch/yaw/roll to quaternion, y–x–z order
776
777 f32quat slerp(const f32quat& a, const f32quat& b, f32 t);
778
779 f32mat3 mat3_cast(f32quat const& q);
780 f32mat4 mat4_cast(f32quat const& q);
781
782 std::string to_string(const f32quat& q);
783
784 f32* value_ptr(f32quat& q);
785 const f32* value_ptr(const f32quat& q);
786
787 f32quat make_quat(const f32* ptr);
788
789 // [Projection & Camera]
790
791 f32mat4 perspective(f32 fovy, f32 aspect, f32 z_near, f32 z_far); // rh
792 f32mat4 ortho(f32 left, f32 right, f32 bottom, f32 top, f32 z_near, f32 z_far); // rh
793 f32mat4 look_at(const f32vec3& eye, const f32vec3& center, const f32vec3& up); // rh
794
795 // [Matrix Decomposition]
796
797 bool decompose(const f32mat4& m, f32vec3& scale, f32quat& rotation, f32vec3& translation);
798
799 // [Random / Probability]
800
801 f32 uniform_01(); // [0, 1)
802 f32 uniform_01(std::mt19937* gen); // [0, 1)
803
804 f32 uniform_n11(); // [-1, 1)
805 f32 uniform_n11(std::mt19937* gen); // [-1, 1)
806
807 u8 uniform_linear(u8 min, u8 max); // [min, max]
808 u8 uniform_linear(std::mt19937* gen, u8 min, u8 max); // [min, max]
809
810 u32 uniform_linear(u32 min, u32 max); // [min, max]
811 u32 uniform_linear(std::mt19937* gen, u32 min, u32 max); // [min, max]
812
813 i32 uniform_linear(i32 min, i32 max); // [min, max]
814 i32 uniform_linear(std::mt19937* gen, i32 min, i32 max); // [min, max]
815
816 f32 uniform_linear(f32 min, f32 max); // [min, max)
817 f32 uniform_linear(std::mt19937* gen, f32 min, f32 max); // [min, max)
818
819 f32vec2 uniform_linear(const f32vec2& min, const f32vec2& max); // [min, max)
820 f32vec2 uniform_linear(std::mt19937* gen, const f32vec2& min, const f32vec2& max); // [min, max)
821
822 f32vec3 uniform_linear(const f32vec3& min, const f32vec3& max); // [min, max)
823 f32vec3 uniform_linear(std::mt19937* gen, const f32vec3& min, const f32vec3& max); // [min, max)
824
825 f32vec4 uniform_linear(const f32vec4& min, const f32vec4& max); // [min, max)
826 f32vec4 uniform_linear(std::mt19937* gen, const f32vec4& min, const f32vec4& max); // [min, max)
827
828 f32vec2 uniform_circular(f32 radius);
829 f32vec2 uniform_circular(std::mt19937* gen, f32 radius);
830
831 f32vec3 uniform_spherical(f32 radius);
832 f32vec3 uniform_spherical(std::mt19937* gen, f32 radius);
833
834 f32vec2 uniform_disk(f32 radius);
835 f32vec2 uniform_disk(std::mt19937* gen, f32 radius);
836
837 f32vec3 uniform_ball(f32 radius);
838 f32vec3 uniform_ball(std::mt19937* gen, f32 radius);
839
840 f32 gaussian(f32 mean, f32 deviation, f32 min, f32 max);
841 f32 gaussian(std::mt19937* gen, f32 mean, f32 deviation, f32 min, f32 max);
842
843 bool bernoulli(f32 p);
844 bool bernoulli(std::mt19937* gen, f32 p);
845
846 // [Easing]
847
848 f32 saturate(f32 t);
849
850 f32 lerp(f32 a, f32 b, f32 t); // unclamped
851 f32 lerp_01(f32 a, f32 b, f32 t); // clamps t to [0,1]
852
853 f32vec2 lerp(const f32vec2& a, const f32vec2& b, f32 t);
854 f32vec2 lerp_01(const f32vec2& a, const f32vec2& b, f32 t);
855
856 f32vec3 lerp(const f32vec3& a, const f32vec3& b, f32 t);
857 f32vec3 lerp_01(const f32vec3& a, const f32vec3& b, f32 t);
858
859 f32vec4 lerp(const f32vec4& a, const f32vec4& b, f32 t);
860 f32vec4 lerp_01(const f32vec4& a, const f32vec4& b, f32 t);
861
862 f32 inverse_lerp(f32 a, f32 b, f32 v); // unclamped
863 f32 inverse_lerp_01(f32 a, f32 b, f32 v); // clamps result to [0,1]
864
865 f32 remap(f32 in_a, f32 in_b, f32 out_a, f32 out_b, f32 v); // unclamped
866 f32 remap_01(f32 in_a, f32 in_b, f32 out_a, f32 out_b, f32 v); // clamps normalized t to [0,1]
867
868 f32 step(f32 edge, f32 x); // x < edge ? 0 : 1
869
870 f32 smoothstep(f32 t); // unclamped, expects t in [0,1]
871 f32 smoothstep_01(f32 t); // clamps t to [0,1]
872
873 f32 smootherstep(f32 t); // unclamped, expects t in [0,1]
874 f32 smootherstep_01(f32 t); // clamps t to [0,1]
875
876 f32 smoothstep(f32 edge0, f32 edge1, f32 x); // clamps internally (classic)
877 f32 smoothstep_unclamped(f32 edge0, f32 edge1, f32 x); // no clamp of normalized t
878
879 f32 smootherstep(f32 edge0, f32 edge1, f32 x); // clamps internally
880 f32 smootherstep_unclamped(f32 edge0, f32 edge1, f32 x); // no clamp of normalized t
881
882 f32 ease_linear(f32 t);
883 f32 ease_linear_01(f32 t);
884
885 f32 ease_in_quadratic(f32 t);
886 f32 ease_out_quadratic(f32 t);
887 f32 ease_in_out_quadratic(f32 t);
888
889 f32 ease_in_cubic(f32 t);
890 f32 ease_out_cubic(f32 t);
891 f32 ease_in_out_cubic(f32 t);
892
893 f32 ease_in_quartic(f32 t);
894 f32 ease_out_quartic(f32 t);
895 f32 ease_in_out_quartic(f32 t);
896
897 f32 ease_in_quintic(f32 t);
898 f32 ease_out_quintic(f32 t);
899 f32 ease_in_out_quintic(f32 t);
900
901 f32 ease_in_sine(f32 t);
902 f32 ease_out_sine(f32 t);
903 f32 ease_in_out_sine(f32 t);
904
905 f32 ease_in_circular(f32 t);
906 f32 ease_out_circular(f32 t);
907 f32 ease_in_out_circular(f32 t);
908
909 f32 ease_in_exponential(f32 t);
910 f32 ease_out_exponential(f32 t);
911 f32 ease_in_out_exponential(f32 t);
912
913 f32 ease_in_back(f32 t, f32 overshoot = 1.70158f);
914 f32 ease_out_back(f32 t, f32 overshoot = 1.70158f);
915 f32 ease_in_out_back(f32 t, f32 overshoot = 1.70158f);
916
917 f32 ease_in_elastic(f32 t);
918 f32 ease_out_elastic(f32 t);
919 f32 ease_in_out_elastic(f32 t);
920
921 f32 ease_in_bounce(f32 t);
922 f32 ease_out_bounce(f32 t);
923 f32 ease_in_out_bounce(f32 t);
924
925 f32quat nlerp(const f32quat& a, const f32quat& b, f32 t, bool shortest_path = true);
926 f32quat nlerp_01(const f32quat& a, const f32quat& b, f32 t, bool shortest_path = true);
927
928 f32quat slerp(const f32quat& a, const f32quat& b, f32 t, bool shortest_path = true);
929 f32quat slerp_01(const f32quat& a, const f32quat& b, f32 t, bool shortest_path = true);
930
931 // [Color]
932
933 f32 srgb_to_linear(f32 v);
934 f32 linear_to_srgb(f32 v);
935
936 f32vec3 srgb_to_linear(const f32vec3& v);
937 f32vec3 linear_to_srgb(const f32vec3& v);
938
939 f32vec4 srgb_to_linear(const f32vec4& v); // alpha unchanged
940 f32vec4 linear_to_srgb(const f32vec4& v); // alpha unchanged
941
942 f32vec3 saturate(const f32vec3& v);
943 f32vec4 saturate(const f32vec4& v);
944
945 f32 luminance_rec709(const f32vec3& rgb); // dot(rgb, {0.2126,0.7152,0.0722})
946 f32 luminance_rec709(const f32vec4& rgba);
947
948 f32vec3 lerp_linear_rgb(const f32vec3& a, const f32vec3& b, f32 t);
949 f32vec4 lerp_linear_rgba(const f32vec4& a, const f32vec4& b, f32 t);
950
951 f32vec3 rgb_to_hsv(const f32vec3& rgb_linear);
952 f32vec3 hsv_to_rgb(const f32vec3& hsv); // returns linear rgb
953
954 f32vec3 rgb_to_hsl(const f32vec3& rgb_linear);
955 f32vec3 hsl_to_rgb(const f32vec3& hsl); // returns linear rgb
956
957 // [Scalar Angles]
958
959 f32 radians(f32 degrees);
960 f32 degrees(f32 radians);
961
962 // [Scalar Trig]
963
964 f32 sin(f32 n);
965 f32 cos(f32 n);
966 f32 tan(f32 n);
967 f32 asin(f32 n);
968 f32 acos(f32 n);
969 f32 atan(f32 n);
970 f32 atan2(f32 y, f32 x);
971 f32 sinh(f32 n);
972 f32 cosh(f32 n);
973 f32 tanh(f32 n);
974 f32 asinh(f32 n);
975 f32 acosh(f32 n);
976 f32 atanh(f32 n);
977
978 // [Scalar Comparison]
979
980 bool equal(f32 a, f32 b, f32 eps = F32_COMPARE_EPSILON);
981
982 // [Scalar Rounding]
983
984 f32 ceil(f32 n);
985 f32 floor(f32 n);
986 f32 round(f32 n);
987
988 // [Scalar Exponentials & Logarithms]
989
990 f32 exp(f32 n);
991 f32 exp2(f32 n);
992 f32 pow(f32 x, f32 y);
993 f32 log(f32 n);
994 f32 log2(f32 n);
995 f32 log10(f32 n);
996
997 // [Scalar Magnitude]
998
999 f32 abs(f32 n);
1000 f32 sqrt(f32 n);
1001 f32 cbrt(f32 n);
1002
1003 // [Scalar Range / Ordering]
1004
1005 template<class T>
1006 constexpr T min(T a, T b) {
1007 return (b < a) ? b : a;
1008 }
1009
1010 template<class T>
1011 constexpr T max(T a, T b) {
1012 return (a < b) ? b : a;
1013 }
1014
1015 template<class T>
1016 constexpr T clamp(T v, T lo, T hi) {
1017 return (v < lo) ? lo : (hi < v) ? hi : v;
1018 }
1019
1020 f32 clamp_01(f32 t);
1021 f32vec2 clamp_01(const f32vec2& v);
1022 f32vec3 clamp_01(const f32vec3& v);
1023 f32vec4 clamp_01(const f32vec4& v);
1024
1025 // [Scalar Remainder / Wrap]
1026
1027 f32 fmod(f32 x, f32 y);
1028 f32 mod(f32 x, f32 y); // positive modulo
1029 f32 wrap(f32 x, f32 lo, f32 hi);
1030
1031 // [Bitwise / Classification]
1032
1033 bool is_nan(f32 n);
1034 bool is_infinite(f32 n);
1035 bool is_finite(f32 n);
1036 bool sign_bit(f32 n);
1037
1038 // [Swap Utilities]
1039
1040 void swap(f32& a, f32& b);
1041
1042 template<class T2, std::size_t N>
1043 void swap(T2 (&a)[N], T2 (&b)[N]) {
1044 for (std::size_t i = 0; i < N; ++i) {
1045 std::swap(a[i], b[i]);
1046 }
1047 }
1048
1049}
1050
1051#endif // AVARA3D_MATH_H
f32vec2 c0
Definition: Math.h:670
const f32vec2 & operator[](std::size_t i) const
f32vec2 & operator[](std::size_t i)
f32vec3 & operator[](std::size_t i)
f32vec3 c0
Definition: Math.h:679
f32vec4 & operator[](std::size_t i)
f32vec4 c0
Definition: Math.h:689
f32 & operator[](std::size_t i)
f32 & operator[](std::size_t i)
f32 & operator[](std::size_t i)
f32 & operator[](std::size_t i)
i32 & operator[](std::size_t i)
const i32 & operator[](std::size_t i) const
i32 & operator[](std::size_t i)
const i32 & operator[](std::size_t i) const
i32 & operator[](std::size_t i)
u32 & operator[](std::size_t i)
u32 & operator[](std::size_t i)
u32 & operator[](std::size_t i)
u8 & operator[](std::size_t i)
u8 & operator[](std::size_t i)
u8 & operator[](std::size_t i)