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