Crate nannou::glam[][src]

Expand description

glam

glam is a simple and fast linear algebra library for games and graphics.

Features

SIMD

glam is built with SIMD in mind. Many f32 types use 128-bit SIMD vector types for storage and/or implementation. The use of SIMD generally enables better performance than using primitive numeric types such as f32.

Some glam types use SIMD for storage meaning they are 16 byte aligned, these types include Mat2, Mat3A, Mat4, Quat, Vec3A, Vec4, Affine2 an Affine3A. Types with an A suffix are a SIMD alternative to a scalar type, e.g. Vec3 uses f32 storage and Vec3A uses SIMD storage.

When SIMD is not available on the target the types will maintain 16 byte alignment and internal padding so that object sizes and layouts will not change between architectures. There are scalar math fallback implementations exist when SIMD is not available. It is intended to add support for other SIMD architectures once they appear in stable Rust.

Currently only SSE2 on x86/x86_64 is supported as this is what stable Rust supports.

Vec3A and Mat3A

Vec3A is a SIMD optimized version of the Vec3 type, which due to 16 byte alignment results in Vec3A containing 4 bytes of padding making it 16 bytes in size in total. Mat3A is composed of three Vec3A columns.

Typef32 bytesAlign bytesSize bytesPadding
Vec3124120
Vec3A1216164
Mat3364360
Mat3A36164812

Despite this wasted space the SIMD implementations tend to outperform f32 implementations in mathbench benchmarks.

glam treats Vec3 as the default 3D vector type and Vec3A a special case for optimization. When methods need to return a 3D vector they will generally return Vec3.

There are From trait implementations for converting from Vec4 to a Vec3A and between Vec3 and Vec3A (and vice versa).

use glam::{Vec3, Vec3A, Vec4};

let v4 = Vec4::new(1.0, 2.0, 3.0, 4.0);

// Convert from `Vec4` to `Vec3A`, this is a no-op if SIMD is supported.
let v3a = Vec3A::from(v4);
assert_eq!(Vec3A::new(1.0, 2.0, 3.0), v3a);

// Convert from `Vec3A` to `Vec3`.
let v3 = Vec3::from(v3a);
assert_eq!(Vec3::new(1.0, 2.0, 3.0), v3);

// Convert from `Vec3` to `Vec3A`.
let v3a = Vec3A::from(v3);
assert_eq!(Vec3A::new(1.0, 2.0, 3.0), v3a);

Affine2 and Affine3A

Affine2 and Affine3A are composed of a linear transform matrix and a vector translation. The represent 2D and 3D affine transformations which are commonly used in games.

The table below shows the performance advantage of Affine2 over Mat3A and Mat3A over Mat3.

operationMat3Mat3AAffine2
inverse11.4±0.09ns7.1±0.09ns5.4±0.06ns
mul self10.5±0.04ns5.2±0.05ns4.0±0.05ns
transform point22.7±0.02ns2.7±0.03ns2.8±0.04ns
transform vector22.6±0.01ns2.6±0.03ns2.3±0.02ns

Performance is much closer between Mat4 and Affine3A with the affine type being faster to invert.

operationMat4Affine3A
inverse15.9±0.11ns10.8±0.06ns
mul self7.3±0.05ns7.0±0.06ns
transform point33.6±0.02ns4.3±0.04ns
transform point3a3.0±0.02ns3.0±0.04ns
transform vector34.1±0.02ns3.9±0.04ns
transform vector3a2.8±0.02ns2.8±0.02ns

Benchmarks were taken on an Intel Core i7-4710HQ.

Linear algebra conventions

glam interprets vectors as column matrices (also known as column vectors) meaning when transforming a vector with a matrix the matrix goes on the left.

use glam::{Mat3, Vec3};
let m = Mat3::IDENTITY;
let x = Vec3::X;
let v = m * x;
assert_eq!(v, x);

Matrices are stored in memory in column-major order.

All angles are in radians. Rust provides the f32::to_radians() and f64::to_radians() methods to convert from degrees.

Direct element access

Because some types may internally be implemented using SIMD types, direct access to vector elements is supported by implementing the Deref and DerefMut traits.

use glam::Vec3A;
let mut v = Vec3A::new(1.0, 2.0, 3.0);
assert_eq!(3.0, v.z);
v.z += 1.0;
assert_eq!(4.0, v.z);

Vector swizzles

glam vector types have functions allowing elements of vectors to be reordered, this includes creating a vector of a different size from the vectors elements.

The swizzle functions are implemented using traits to add them to each vector type. This is primarily because there are a lot of swizzle functions which can obfuscate the other vector functions in documentation and so on. The traits are Vec2Swizzles, Vec3Swizzles and Vec4Swizzles.

Note that the Vec3Swizzles implementation for Vec3A will return a Vec3A for 3 element swizzles, all other implementations will return Vec3.

use glam::{swizzles::*, Vec2, Vec3, Vec3A, Vec4};

let v = Vec4::new(1.0, 2.0, 3.0, 4.0);

// Reverse elements of `v`, if SIMD is supported this will use a vector shuffle.
let wzyx = v.wzyx();
assert_eq!(Vec4::new(4.0, 3.0, 2.0, 1.0), wzyx);

// Swizzle the yzw elements of `v` into a `Vec3`
let yzw = v.yzw();
assert_eq!(Vec3::new(2.0, 3.0, 4.0), yzw);

// To swizzle a `Vec4` into a `Vec3A` swizzle the `Vec4` first then convert to
// `Vec3A`. If SIMD is supported this will use a vector shuffle. The last
// element of the shuffled `Vec4` is ignored by the `Vec3A`.
let yzw = Vec3A::from(v.yzwx());
assert_eq!(Vec3A::new(2.0, 3.0, 4.0), yzw);

// You can swizzle from a `Vec4` to a `Vec2`
let xy = v.xy();
assert_eq!(Vec2::new(1.0, 2.0), xy);

// And back again
let yyxx = xy.yyxx();
assert_eq!(Vec4::new(2.0, 2.0, 1.0, 1.0), yyxx);

SIMD and scalar consistency

glam types implement serde Serialize and Deserialize traits to ensure that they will serialize and deserialize exactly the same whether or not SIMD support is being used.

The SIMD versions implement the core::fmt::Debug and core::fmt::Display traits so they print the same as the scalar version.

use glam::Vec4;
let a = Vec4::new(1.0, 2.0, 3.0, 4.0);
assert_eq!(format!("{}", a), "[1, 2, 3, 4]");

Feature gates

All glam dependencies are optional, however some are required for tests and benchmarks.

  • std - the default feature, has no dependencies.
  • approx - traits and macros for approximate float comparisons
  • bytemuck - for casting into slices of bytes
  • libm - required to compile with no_std
  • mint - for interoperating with other 3D math libraries
  • num-traits - required to compile no_std, will be included when enabling the libm feature
  • rand - implementations of Distribution trait for all glam types.
  • serde - implementations of Serialize and Deserialize for all glam types. Note that serialization should work between builds of glam with and without SIMD enabled
  • scalar-math - disables SIMD support and uses native alignment for all types.
  • debug-glam-assert - adds assertions in debug builds which check the validity of parameters passed to glam to help catch runtime errors.
  • glam-assert - adds assertions to all builds which check the validity of parameters passed to glam to help catch runtime errors.

Minimum Supported Rust Version (MSRV)

The minimum supported Rust version is 1.45.0.

Modules

bool

bool vector mask types.

f32

f32 vector, quaternion and matrix types.

f64

f64 vector, quaternion and matrix types.

i32

i32 vector types.

swizzles

Traits adding swizzle methods to all vector types.

u32

u32 vector types.

Macros

const_dmat2

Creates a DMat2 from two column vectors that can be used to initialize a constant value.

const_dmat3

Creates a DMat3 from three column vectors that can be used to initialize a constant value.

const_dmat4

Creates a DMat4 from four column vectors that can be used to initialize a constant value.

const_dquat

Creates a DQuat from x, y, z and w values that can be used to initialize a constant value.

const_dvec2

Creates a DVec2 that can be used to initialize a constant value.

const_dvec3

Creates a DVec3 that can be used to initialize a constant value.

const_dvec4

Creates a DVec4 that can be used to initialize a constant value.

const_ivec2

Creates a IVec2 that can be used to initialize a constant value.

const_ivec3

Creates a IVec3 that can be used to initialize a constant value.

const_ivec4

Creates a IVec4 that can be used to initialize a constant value.

const_m128
const_mat2

Creates a Mat2 from two column vectors that can be used to initialize a constant value.

const_mat3

Creates a Mat3 from three column vectors that can be used to initialize a constant value.

const_mat3a

Creates a Mat3A from three column vectors that can be used to initialize a constant value.

const_mat4

Creates a Mat4 from four column vectors that can be used to initialize a constant value.

const_quat

Creates a Quat from x, y, z and w values that can be used to initialize a constant value.

const_uvec2

Creates a UVec2 that can be used to initialize a constant value.

const_uvec3

Creates a UVec3 that can be used to initialize a constant value.

const_uvec4

Creates a UVec4 that can be used to initialize a constant value.

const_vec2

Creates a Vec2 that can be used to initialize a constant value.

const_vec3

Creates a Vec3 that can be used to initialize a constant value.

const_vec3a

Creates a Vec3A that can be used to initialize a constant value.

const_vec4

Creates a Vec4 that can be used to initialize a constant value.

Structs

Affine2

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.

BVec2

A 2-dimensional boolean vector.

BVec3

A 3-dimensional boolean vector.

BVec3A

A 3-dimensional SIMD vector mask.

BVec4

A 4-dimensional boolean vector.

BVec4A

A 4-dimensional SIMD vector mask.

DAffine2

A 2D affine transform, which can represent translation, rotation, scaling and shear.

DAffine3

A 3D affine transform, which can represent translation, rotation, scaling and shear.

DMat2

A 2x2 column major matrix.

DMat3

A 3x3 column major matrix.

DMat4

A 4x4 column major matrix.

DQuat

A quaternion representing an orientation.

DVec2

A 2-dimensional vector.

DVec3

A 3-dimensional vector.

DVec4

A 4-dimensional vector.

IVec2

A 2-dimensional vector.

IVec3

A 3-dimensional vector.

IVec4

A 4-dimensional vector.

Mat2

A 2x2 column major matrix.

Mat3

A 3x3 column major matrix.

Mat3A

A 3x3 column major matrix.

Mat4

A 4x4 column major matrix.

Quat

A quaternion representing an orientation.

UVec2

A 2-dimensional vector.

UVec3

A 3-dimensional vector.

UVec4

A 4-dimensional vector.

Vec2

A 2-dimensional vector.

Vec3

A 3-dimensional vector without SIMD support.

Vec3A

A 3-dimensional vector with SIMD support.

Vec4

A 4-dimensional vector.

XY
XYZ
XYZW

Enums

EulerRot

Euler rotation sequences.

Traits

Vec2Swizzles

Swizzle methods for 2-dimensional vector types.

Vec3Swizzles

Swizzle methods for 3-dimensional vector types.

Vec4Swizzles

Swizzle methods for 3-dimensional vector types.

Functions

dmat2

Creates a 2x2 matrix from two column vectors.

dmat3

Creates a 3x3 matrix from three column vectors.

dmat4

Creates a 4x4 matrix from four column vectors.

dquat

Creates a quaternion from x, y, z and w values.

dvec2

Creates a 2-dimensional vector.

dvec3

Creates a 3-dimensional vector.

dvec4

Creates a 4-dimensional vector.

ivec2

Creates a 2-dimensional vector.

ivec3

Creates a 3-dimensional vector.

ivec4

Creates a 4-dimensional vector.

mat2

Creates a 2x2 matrix from two column vectors.

mat3

Creates a 3x3 matrix from three column vectors.

mat3a

Creates a 3x3 matrix from three column vectors.

mat4

Creates a 4x4 matrix from four column vectors.

quat

Creates a quaternion from x, y, z and w values.

uvec2

Creates a 2-dimensional vector.

uvec3

Creates a 3-dimensional vector.

uvec4

Creates a 4-dimensional vector.

vec2

Creates a 2-dimensional vector.

vec3

Creates a 3-dimensional vector.

vec3a

Creates a 3-dimensional vector.

vec4

Creates a 4-dimensional vector.