1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
//! A fast linear algebra library for games and graphics.
//!
//! - Vectors: [`Vec2<T>`], [`Vec3<T>`], [`Vec4<T>`]
//! - Square Matrices: [`Mat2<T>`], [`Mat3<T>`], [`Mat4<T>`]
//! - Quaternions: [`Quat<T>`]
//! - Affine Transforms: [`Affine2<T>`], [`Affine3<T>`]
//! - Masks: [`Mask2<T>`], [`Mask3<T>`], [`Mask4<T>`]
//!
//! SIMD variants:
//!
//! - Vectors: [`Vec2A<T>`], [`Vec3A<T>`], [`Vec4A<T>`]
//! - Square Matrices: [`Mat2A<T>`], [`Mat3A<T>`], [`Mat4A<T>`]
//! - Quaternions: [`QuatA<T>`]
//! - Affine Transforms: [`Affine2A<T>`], [`Affine3A<T>`]
//! - Masks: [`Mask2A<T>`], [`Mask3A<T>`], [`Mask4A<T>`]
//!
//! Underlying generic types:
//!
//! - [`Vector<N, T, A>`]
//! - [`Matrix<N, T, A>`]
//! - [`Quaternion<T, A>`]
//! - [`Affine<N, T, A>`]
//! - [`Mask<N, T, A>`]
//!
//! # SIMD
//!
//! SIMD variants use specialization to have appropriate alignment and to use
//! explicit SIMD in function implementations.
//!
//! SIMD results in faster computations, but can actually hurt performance if
//! the bottleneck is memory bandwidth rather than computation throughput. For
//! maximum performance, there are both SIMD, non-SIMD and SoA types
//! ([see below](#soa)).
//!
//! | Type | [`Vec3<f32>`] | [`Vec3A<f32>`] | [`Mat3<f32>`] | [`Mat3A<f32>`] |
//! | ----------------- | ------------- | -------------- | ------------- | -------------- |
//! | Size (bytes) | 12 | 16 | 36 | 48 |
//! | Alignment (bytes) | 4 | 16 | 4 | 16 |
//! | Padding (bytes) | 0 | 4 | 0 | 12 |
//!
//! | Type | [`Vec4<f32>`] | [`Vec4A<f32>`] | [`Mat4<f32>`] | [`Mat4A<f32>`] |
//! | ----------------- | ------------- | -------------- | ------------- | -------------- |
//! | Size (bytes) | 16 | 16 | 64 | 64 |
//! | Alignment (bytes) | 4 | 16 | 4 | 16 |
//! | Padding (bytes) | 0 | 0 | 0 | 0 |
//!
//! > This table is true only for target architectures that have SIMD and are
//! > supported. Types incompatible with SIMD use fallback implementations.
//! > Currently support is limited to [`f32`] types on x86 and aarch64.
//!
//! # Generics
//!
//! The underlying types are generic over:
//!
//! - `T`: The element type
//! - `N`: The dimension
//! - `A`: The alignment mode (SIMD or non-SIMD)
//!
//! The traits [`PrimitiveFloat`], [`PrimitiveInteger`], [`PrimitiveSigned`] and
//! [`PrimitiveUnsigned`] give generic contexts access to most primitive
//! functionality. These traits do not expose functions directly, they only
//! enable functionality for vectors, matrices, etc. For complete primitive
//! generics, add the [`num-primitive`] crate as an optional dependency.
//!
//! # Affine transforms
//!
//! An affine transform contains a linear transformation and a translation
//! vector. It can represent scale, rotation, shear and translation, but cannot
//! represent projections. [`Affine2<T>`] is equivalent to [`Mat3<T>`], and
//! [`Affine3<T>`] is equivalent to [`Mat4<T>`].
//!
//! Affine transforms take less memory than matrices and perform better for
//! select operations (see [benchmark results]).
//!
//! | Type | [`Affine2<f32>`] | [`Mat3<f32>`] | [`Affine2A<f32>`] | [`Mat3A<f32>`] |
//! | ----------------- | ---------------- | ------------- | ----------------- | -------------- |
//! | Size (bytes) | 24 | 36 | 32 | 48 |
//! | Alignment (bytes) | 4 | 4 | 16 | 16 |
//!
//! | Type | [`Affine3<f32>`] | [`Mat4<f32>`] | [`Affine3A<f32>`] | [`Mat4A<f32>`] |
//! | ----------------- | ---------------- | ------------- | ----------------- | -------------- |
//! | Size (bytes) | 48 | 64 | 64 | 64 |
//! | Alignment (bytes) | 4 | 4 | 16 | 16 |
//!
//! > This table is true only for target architectures that have SIMD and are
//! > supported.
//!
//! # Masks
//!
//! Masks are boolean vectors optimized for specific vector types. For example,
//! [`Mask3A<f32>`] performs better than [`Vec3A<bool>`] for operations
//! involving [`Vec3A<f32>`].
//!
//! # SoA
//!
//! SoA, or Structure of Arrays, refers to math types where each element `T`
//! contains multiple values. For example, [`Vec3<f32x4>`] represents four 3D
//! vectors, stored in memory as:
//!
//! `x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4`
//!
//! SoA is faster than standard SIMD. For example, computing the dot product for
//! [`Vec3<f32>`] is quite slow because SIMD is not built for horizontal
//! operations, while for [`Vec3<f32x4>`] it is much faster because each element
//! is a SIMD register and there are no horizontal operations.
//!
//! However, SoA requires that algorithms are designed to process multiple
//! values at the same time, which can be quite challenging. Because of this, it
//! is best to only use SoA for performance-critical algorithms.
//!
//! SoA is supported through an optional dependency for the [`wide`] crate.
//! Almost all functionality that exists for standard types also exists for SoA
//! types.
//!
//! > [The `docs.rs` page] currently doesn't show [`wide`] support. See
//! > [this issue](https://github.com/Noam2Stein/ggmath/issues/45).
//!
//! # Fixed-point numbers
//!
//! Currently, there is only basic support for fixed-point numbers, through the
//! [`fixed`] feature flag which implements [`Scalar`] for [`fixed`] types. See
//! [this issue](https://github.com/Noam2Stein/ggmath/issues/46) for better
//! fixed-point number support.
//!
//! # Linear algebra conventions
//!
//! [`ggmath`] is coordinate-system agnostic, and should work for both
//! right-handed and left-handed coordinate systems.
//!
//! [`ggmath`] uses left-multiplication, meaning to transform a vector by a
//! matrix (or quaternion) you write `vector * matrix` and not
//! `matrix * vector`. This means matrices are stored in row-major order.
//!
//! # Why another math crate?
//!
//! [`ggmath`] exists because existing similar libraries are missing certain
//! features:
//!
//! - SIMD alignment (e.g., `Vec3` is `__m128`, important for performance)
//! - Generics (over primitives or arbitrary types, avoids macros)
//! - SoA (niche, but important for game engines)
//! - Fixed-point numbers (niche too, but important for game engines that aim to
//! be flexible)
//!
//! Existing similar libraries:
//!
//! - [`glam`]: Supports SIMD alignment, but does not use generics, and as a
//! result SoA and fixed-point numbers are out of scope.
//!
//! - [`ultraviolet`]: Supports SoA, but does not support SIMD alignment because
//! its types are simple scalar structs. Does not use generics, and as a
//! result fixed-point numbers are probably out of scope.
//!
//! - [`cgmath`]: Supports generics (could also support SoA and fixed-point
//! numbers) but does not support SIMD alignment, because its types are simple
//! scalar structs.
//!
//! - [`nalgebra`]: Less graphics oriented and thus has a larger, more
//! complicated API more suitable for general linear algebra.
//!
//! [`ggmath`] has a design where types are generic over `N` and `T`, but also
//! whether SIMD alignment is enabled or disabled, enabling it to support both
//! SIMD alignment and generics. Changing existing libraries to use this design
//! would be out of scope.
//!
//! # Usage
//!
//! Rust must be updated to version `1.95.0` or later.
//!
//! Add this to your Cargo.toml:
//!
//! ```toml
//! [dependencies]
//! ggmath = "0.17.1"
//! ```
//!
//! For [`no_std`] support, enable the [`libm`] feature:
//!
//! ```toml
//! [dependencies]
//! ggmath = { version = "0.17.1", features = ["libm"] }
//! ```
//!
//! # Feature flags
//!
//! - [`bytemuck`]: Implements [`bytemuck`] traits for [`ggmath`] types.
//!
//! - [`fixed`]: Implements [`Scalar`] for fixed-point numbers.
//!
//! - [`libm`]: Uses [`libm`] instead of [`std`] as the backend for
//! floating-point functions. This makes the crate [`no_std`].
//!
//! - [`mint`]: Implements conversions between [`ggmath`] and [`mint`] types.
//!
//! - [`rand`]: Implements [`rand`] traits for [`ggmath`] types.
//!
//! - [`serde`]: Implements [`Serialize`] and [`Deserialize`] for [`ggmath`]
//! types.
//!
//! - [`wide`]: Implements functionality for SoA types.
//!
//! [`ggmath`]: crate
//! [`num-primitive`]: https://crates.io/crates/num-primitive
//!
//! [benchmark results]: https://github.com/Noam2Stein/ggmath/blob/main/BENCH_RESULTS.md
//!
//! [`wide`]: https://crates.io/crates/wide
//! [The `docs.rs` page]: https://docs.rs/ggmath
//!
//! [`fixed`]: https://crates.io/crates/fixed
//!
//! [`glam`]: https://crates.io/crates/glam
//! [`ultraviolet`]: https://crates.io/crates/ultraviolet
//! [`cgmath`]: https://crates.io/crates/cgmath
//! [`nalgebra`]: https://crates.io/crates/nalgebra
//!
//! [`no_std`]: https://docs.rust-embedded.org/book/intro/no-std.html
//! [`libm`]: https://crates.io/crates/libm
//!
//! [`bytemuck`]: https://crates.io/crates/bytemuck
//! [`std`]: https://doc.rust-lang.org/std
//! [`mint`]: https://crates.io/crates/mint
//! [`rand`]: https://crates.io/crates/rand
//! [`serde`]: https://crates.io/crates/serde
//! [`Serialize`]: https://docs.rs/serde/latest/serde/trait.Serialize.html
//! [`Deserialize`]: https://docs.rs/serde/latest/serde/trait.Deserialize.html
pub use crate::;