Expand description
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:
§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).
| 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
f32types on x86 and aarch64.
§Generics
The underlying types are generic over:
T: The element typeN: The dimensionA: 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.rspage currently doesn’t showwidesupport. See this issue.
§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 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.,
Vec3is__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:
[dependencies]
ggmath = "0.17.1"For no_std support, enable the libm feature:
[dependencies]
ggmath = { version = "0.17.1", features = ["libm"] }§Feature flags
Structs§
- Affine
- An
N-dimensional affine transform which can represent translation, rotation, scaling and shear of typeT. - Aligned
- A marker type specifying SIMD alignment.
- Length
- A marker type to restrict
const N: usizeto2,3and4. - Mask
- An
N-element vector mask optimized for typeT. - Matrix
- An
NxNrow-major matrix of typeT. - Quaternion
- A quaternion representing a rotation.
- Unaligned
- A marker type specifying lack of SIMD alignment.
- Vector
- An
N-dimensional vector of typeT.
Enums§
- Euler
Rot - An Euler rotation order/sequence.
Traits§
- Alignment
- A marker trait controlling SIMD alignment for types.
- Custom
Scalar - A trait to implement
Scalarfor downstream types. - Float
Ext - Extends floating-point primitives with extra functionality.
- NegOne
- A trait for types with a
-1value. - One
- A trait for types with a
1value. - Primitive
Float - A trait for all primitive floating-point types.
- Primitive
Integer - A trait for all primitive integer types.
- Primitive
Signed - A trait for all primitive signed integer types.
- Primitive
Unsigned - A trait for all primitive unsigned integer types.
- Scalar
- A trait for elements of vectors.
- Supported
Length - A marker trait to restrict
const N: usizeto2,3and4. - Zero
- A trait for types with a
0value.
Type Aliases§
- Affine2
- A 2D affine transform which can represent translation, rotation, scaling and shear.
- Affine3
- A 3D affine transform which can represent translation, rotation, scaling and shear.
- Affine2A
- A 2D affine transform which can represent translation, rotation, scaling and shear.
- Affine3A
- A 3D affine transform which can represent translation, rotation, scaling and shear.
- Mask2
- A 2-element vector mask.
- Mask3
- A 3-element vector mask.
- Mask4
- A 4-element vector mask.
- Mask2A
- A 2-element vector mask.
- Mask3A
- A 3-element vector mask.
- Mask4A
- A 4-element vector mask.
- Mat2
- A 2x2 row-major matrix.
- Mat3
- A 3x3 row-major matrix.
- Mat4
- A 4x4 row-major matrix.
- Mat2A
- A 2x2 row-major matrix.
- Mat3A
- A 3x3 row-major matrix.
- Mat4A
- A 4x4 row-major matrix.
- Quat
- A quaternion representing a rotation.
- QuatA
- A quaternion representing a rotation.
- Vec2
- A 2D vector.
- Vec3
- A 3D vector.
- Vec4
- A 4D vector.
- Vec2A
- A 2D vector.
- Vec3A
- A 3D vector.
- Vec4A
- A 4D vector.