Struct vek::mat::repr_simd::row_major::mat4::Mat4

source ·
#[repr(C)]
pub struct Mat4<T> { pub rows: CVec4<Vec4<T>>, }
Expand description

4x4 matrix.

Fields§

§rows: CVec4<Vec4<T>>

Implementations§

source§

impl<T> Mat4<T>

source

pub fn identity() -> Self
where T: Zero + One,

The identity matrix, which is also the default value for square matrices.

assert_eq!(Mat4::<f32>::default(), Mat4::<f32>::identity());
source

pub fn zero() -> Self
where T: Zero,

The matrix with all elements set to zero.

source

pub fn apply<F>(&mut self, f: F)
where T: Copy, F: FnMut(T) -> T,

Applies the function f to each element of this matrix, in-place.

For an example, see the map() method.

source

pub fn apply2<F, S>(&mut self, other: Mat4<S>, f: F)
where T: Copy, F: FnMut(T, S) -> T,

Applies the function f to each element of this matrix, in-place.

For an example, see the map2() method.

source

pub fn numcast<D>(self) -> Option<Mat4<D>>
where T: NumCast, D: NumCast,

Returns a memberwise-converted copy of this matrix, using NumCast.

let m = Mat4::<f32>::identity();
let m: Mat4<i32> = m.numcast().unwrap();
assert_eq!(m, Mat4::identity());
source

pub fn broadcast_diagonal(val: T) -> Self
where T: Zero + Copy,

Initializes a new matrix with elements of the diagonal set to val and the other to zero.

In a way, this is the same as single-argument matrix constructors in GLSL and GLM.

assert_eq!(Mat4::broadcast_diagonal(0), Mat4::zero());
assert_eq!(Mat4::broadcast_diagonal(1), Mat4::identity());
assert_eq!(Mat4::broadcast_diagonal(2), Mat4::new(
    2,0,0,0,
    0,2,0,0,
    0,0,2,0,
    0,0,0,2,
));
source

pub fn with_diagonal(d: Vec4<T>) -> Self
where T: Zero + Copy,

Initializes a matrix by its diagonal, setting other elements to zero.

source

pub fn diagonal(self) -> Vec4<T>

Gets the matrix’s diagonal into a vector.

assert_eq!(Mat4::<u32>::zero().diagonal(), Vec4::zero());
assert_eq!(Mat4::<u32>::identity().diagonal(), Vec4::one());

let mut m = Mat4::zero();
m[(0, 0)] = 1;
m[(1, 1)] = 2;
m[(2, 2)] = 3;
m[(3, 3)] = 4;
assert_eq!(m.diagonal(), Vec4::new(1, 2, 3, 4));
assert_eq!(m.diagonal(), Vec4::iota() + 1);
source

pub fn trace(self) -> T
where T: Add<T, Output = T>,

The sum of the diagonal’s elements.

assert_eq!(Mat4::<u32>::zero().trace(), 0);
assert_eq!(Mat4::<u32>::identity().trace(), 4);
source

pub fn mul_memberwise(self, m: Self) -> Self
where T: Mul<Output = T>,

Multiply elements of this matrix with another’s.


let m = Mat4::new(
    0, 1, 2, 3,
    1, 2, 3, 4,
    2, 3, 4, 5,
    3, 4, 5, 6,
);
let r = Mat4::new(
    0, 1, 4, 9,
    1, 4, 9, 16,
    4, 9, 16, 25,
    9, 16, 25, 36,
);
assert_eq!(m.mul_memberwise(m), r);
source

pub fn row_count(&self) -> usize

Convenience for getting the number of rows of this matrix.

source

pub fn col_count(&self) -> usize

Convenience for getting the number of columns of this matrix.

source

pub const ROW_COUNT: usize = 4usize

Convenience constant representing the number of rows for matrices of this type.

source

pub const COL_COUNT: usize = 4usize

Convenience constant representing the number of columns for matrices of this type.

source

pub fn is_packed(&self) -> bool

Are all elements of this matrix tightly packed together in memory ?

This might not be the case for matrices in the repr_simd module (it depends on the target architecture).

source§

impl<T> Mat4<T>

source

pub fn map_rows<D, F>(self, f: F) -> Mat4<D>
where F: FnMut(Vec4<T>) -> Vec4<D>,

Returns a row-wise-converted copy of this matrix, using the given conversion closure.

use vek::mat::repr_c::row_major::Mat4;

let m = Mat4::<f32>::new(
    0.25, 1.25, 5.56, 8.66,
    8.53, 2.92, 3.86, 9.36,
    1.02, 0.28, 5.52, 6.06,
    6.20, 7.01, 4.90, 5.26
);
let m = m.map_rows(|row| row.map(|x| x.round() as i32));
assert_eq!(m, Mat4::new(
    0, 1, 6, 9,
    9, 3, 4, 9,
    1, 0, 6, 6,
    6, 7, 5, 5
));
source

pub fn into_row_array(self) -> [T; 16]

Converts this matrix into a fixed-size array of elements.

use vek::mat::repr_c::row_major::Mat4;

let m = Mat4::<u32>::new(
     0,  1,  2,  3,
     4,  5,  6,  7,
     8,  9, 10, 11,
    12, 13, 14, 15
);
let array = [
     0,  1,  2,  3,
     4,  5,  6,  7,
     8,  9, 10, 11,
    12, 13, 14, 15
];
assert_eq!(m.into_row_array(), array);
source

pub fn into_row_arrays(self) -> [[T; 4]; 4]

Converts this matrix into a fixed-size array of fixed-size arrays of elements.

use vek::mat::repr_c::row_major::Mat4;

let m = Mat4::<u32>::new(
     0,  1,  2,  3,
     4,  5,  6,  7,
     8,  9, 10, 11,
    12, 13, 14, 15
);
let array = [
    [  0,  1,  2,  3, ],
    [  4,  5,  6,  7, ],
    [  8,  9, 10, 11, ],
    [ 12, 13, 14, 15, ],
];
assert_eq!(m.into_row_arrays(), array);
source

pub fn from_row_array(array: [T; 16]) -> Self

Converts a fixed-size array of elements into a matrix.

use vek::mat::repr_c::row_major::Mat4;

let m = Mat4::<u32>::new(
     0,  1,  2,  3,
     4,  5,  6,  7,
     8,  9, 10, 11,
    12, 13, 14, 15
);
let array = [
     0,  1,  2,  3,
     4,  5,  6,  7,
     8,  9, 10, 11,
    12, 13, 14, 15
];
assert_eq!(m, Mat4::from_row_array(array));
source

pub fn from_row_arrays(array: [[T; 4]; 4]) -> Self

Converts a fixed-size array of fixed-size array of elements into a matrix.

use vek::mat::repr_c::row_major::Mat4;

let m = Mat4::<u32>::new(
     0,  1,  2,  3,
     4,  5,  6,  7,
     8,  9, 10, 11,
    12, 13, 14, 15
);
let array = [
    [  0,  1,  2,  3, ],
    [  4,  5,  6,  7, ],
    [  8,  9, 10, 11, ],
    [ 12, 13, 14, 15, ],
];
assert_eq!(m, Mat4::from_row_arrays(array));
source

pub fn into_col_array(self) -> [T; 16]

Converts this matrix into a fixed-size array of elements.

use vek::mat::repr_c::row_major::Mat4;

let m = Mat4::<u32>::new(
     0,  1,  2,  3,
     4,  5,  6,  7,
     8,  9, 10, 11,
    12, 13, 14, 15
);
let array = [
    0, 4, 8, 12,
    1, 5, 9, 13,
    2, 6, 10, 14,
    3, 7, 11, 15
];
assert_eq!(m.into_col_array(), array);
source

pub fn into_col_arrays(self) -> [[T; 4]; 4]

Converts this matrix into a fixed-size array of fixed-size arrays of elements.

use vek::mat::repr_c::row_major::Mat4;

let m = Mat4::<u32>::new(
     0,  1,  2,  3,
     4,  5,  6,  7,
     8,  9, 10, 11,
    12, 13, 14, 15
);
let array = [
    [ 0, 4,  8, 12, ],
    [ 1, 5,  9, 13, ],
    [ 2, 6, 10, 14, ],
    [ 3, 7, 11, 15, ],
];
assert_eq!(m.into_col_arrays(), array);
source

pub fn from_col_array(array: [T; 16]) -> Self

Converts a fixed-size array of elements into a matrix.

use vek::mat::repr_c::row_major::Mat4;

let m = Mat4::<u32>::new(
     0,  1,  2,  3,
     4,  5,  6,  7,
     8,  9, 10, 11,
    12, 13, 14, 15
);
let array = [
    0, 4, 8, 12,
    1, 5, 9, 13,
    2, 6, 10, 14,
    3, 7, 11, 15
];
assert_eq!(m, Mat4::from_col_array(array));
source

pub fn from_col_arrays(array: [[T; 4]; 4]) -> Self

Converts a fixed-size array of fixed-size arrays of elements into a matrix.

use vek::mat::repr_c::row_major::Mat4;

let m = Mat4::<u32>::new(
     0,  1,  2,  3,
     4,  5,  6,  7,
     8,  9, 10, 11,
    12, 13, 14, 15
);
let array = [
    [ 0, 4,  8, 12, ],
    [ 1, 5,  9, 13, ],
    [ 2, 6, 10, 14, ],
    [ 3, 7, 11, 15, ],
];
assert_eq!(m, Mat4::from_col_arrays(array));
source

pub fn as_row_ptr(&self) -> *const T

Gets a const pointer to this matrix’s elements.

§Panics

Panics if the matrix’s elements are not tightly packed in memory, which may be the case for matrices in the repr_simd module. You may check this with the is_packed() method.

source

pub fn as_mut_row_ptr(&mut self) -> *mut T

Gets a mut pointer to this matrix’s elements.

§Panics

Panics if the matrix’s elements are not tightly packed in memory, which may be the case for matrices in the repr_simd module. You may check this with the is_packed() method.

source

pub fn as_row_slice(&self) -> &[T]

View this matrix as an immutable slice.

§Panics

Panics if the matrix’s elements are not tightly packed in memory, which may be the case for matrices in the repr_simd module. You may check this with the is_packed() method.

source

pub fn as_mut_row_slice(&mut self) -> &mut [T]

View this matrix as a mutable slice.

§Panics

Panics if the matrix’s elements are not tightly packed in memory, which may be the case for matrices in the repr_simd module. You may check this with the is_packed() method.

source§

impl<T> Mat4<T>

source

pub fn gl_should_transpose(&self) -> bool

Gets the transpose parameter to pass to OpenGL glUniformMatrix*() functions.

The return value is a plain bool which you may directly cast to a GLboolean.

This takes &self to prevent surprises when changing the type of matrix you plan to send.

source

pub const GL_SHOULD_TRANSPOSE: bool = true

The transpose parameter to pass to OpenGL glUniformMatrix*() functions.

source§

impl<T> Mat4<T>

source

pub fn new( m00: T, m01: T, m02: T, m03: T, m10: T, m11: T, m12: T, m13: T, m20: T, m21: T, m22: T, m23: T, m30: T, m31: T, m32: T, m33: T ) -> Self

Creates a new 4x4 matrix from elements in a layout-agnostic way.

The parameters are named mij where i is the row index and j the column index. Their order is always the same regardless of the matrix’s layout.

source§

impl<T> Mat4<T>

source

pub fn map<D, F>(self, f: F) -> Mat4<D>
where F: FnMut(T) -> D,

Returns an element-wise-converted copy of this matrix, using the given conversion closure.

use vek::mat::repr_c::row_major::Mat4;

let m = Mat4::<f32>::new(
    0.25, 1.25, 5.56, 8.66,
    8.53, 2.92, 3.86, 9.36,
    1.02, 0.28, 5.52, 6.06,
    6.20, 7.01, 4.90, 5.26
);
let m = m.map(|x| x.round() as i32);
assert_eq!(m, Mat4::new(
    0, 1, 6, 9,
    9, 3, 4, 9,
    1, 0, 6, 6,
    6, 7, 5, 5
));
source

pub fn as_<D>(self) -> Mat4<D>
where T: AsPrimitive<D>, D: 'static + Copy,

Returns a memberwise-converted copy of this matrix, using AsPrimitive.

§Examples
let v = Vec4::new(0_f32, 1., 2., 3.);
let i: Vec4<i32> = v.as_();
assert_eq!(i, Vec4::new(0, 1, 2, 3));
§Safety

In Rust versions before 1.45.0, some uses of the as operator were not entirely safe. In particular, it was undefined behavior if a truncated floating point value could not fit in the target integer type (#10184);

let x: u8 = (1.04E+17).as_(); // UB
source

pub fn map2<D, F, S>(self, other: Mat4<S>, f: F) -> Mat4<D>
where F: FnMut(T, S) -> D,

Applies the function f to each element of two matrices, pairwise, and returns the result.

use vek::mat::repr_c::row_major::Mat4;

let a = Mat4::<f32>::new(
    0.25, 1.25, 2.52, 2.99,
    0.25, 1.25, 2.52, 2.99,
    0.25, 1.25, 2.52, 2.99,
    0.25, 1.25, 2.52, 2.99
);
let b = Mat4::<i32>::new(
    0, 1, 0, 0,
    1, 0, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
);
let m = a.map2(b, |a, b| a.round() as i32 + b);
assert_eq!(m, Mat4::new(
    0, 2, 3, 3,
    1, 1, 3, 3,
    0, 1, 4, 3,
    0, 1, 3, 4
));
source

pub fn transposed(self) -> Self

The matrix’s transpose.

For orthogonal matrices, the transpose is the same as the inverse. All pure rotation matrices are orthogonal, and therefore can be inverted faster by simply computing their transpose.

use std::f32::consts::PI;

let m = Mat4::new(
    0, 1, 2, 3,
    4, 5, 6, 7,
    8, 9, 0, 1,
    2, 3, 4, 5
);
let t = Mat4::new(
    0, 4, 8, 2,
    1, 5, 9, 3,
    2, 6, 0, 4,
    3, 7, 1, 5
);
assert_eq!(m.transposed(), t);
assert_eq!(m, m.transposed().transposed());

// By the way, demonstrate ways to invert a rotation matrix,
// from fastest (specific) to slowest (general-purpose).
let m = Mat4::rotation_x(PI/7.);
let id = Mat4::identity();
assert_relative_eq!(id, m * m.transposed());
assert_relative_eq!(id, m.transposed() * m);
assert_relative_eq!(id, m * m.inverted_affine_transform_no_scale());
assert_relative_eq!(id, m.inverted_affine_transform_no_scale() * m);
assert_relative_eq!(id, m * m.inverted_affine_transform());
assert_relative_eq!(id, m.inverted_affine_transform() * m);
assert_relative_eq!(id, m * m.inverted());
assert_relative_eq!(id, m.inverted() * m);
source

pub fn transpose(&mut self)

Transpose this matrix.


let mut m = Mat4::new(
    0, 1, 2, 3,
    4, 5, 6, 7,
    8, 9, 0, 1,
    2, 3, 4, 5
);
let t = Mat4::new(
    0, 4, 8, 2,
    1, 5, 9, 3,
    2, 6, 0, 4,
    3, 7, 1, 5
);
m.transpose();
assert_eq!(m, t);
source

pub fn determinant(self) -> T
where T: Copy + Mul<T, Output = T> + Sub<T, Output = T> + Add<T, Output = T>,

Get this matrix’s determinant.

A matrix is invertible if its determinant is non-zero.

source

pub fn invert(&mut self)
where T: Real,

Inverts this matrix, blindly assuming that it is invertible. See inverted() for more info.

source

pub fn inverted(self) -> Self
where T: Real,

Returns this matrix’s inverse, blindly assuming that it is invertible.

All affine matrices have inverses; Your matrices may be affine as long as they consist of any combination of pure rotations, translations, scales and shears.

use vek::vec::repr_c::Vec3;
use vek::mat::repr_c::row_major::Mat4 as Rows4;
use vek::mat::repr_c::column_major::Mat4 as Cols4;
use std::f32::consts::PI;

let a = Rows4::scaling_3d(1.77_f32)
    .rotated_3d(PI*4./5., Vec3::new(5., 8., 10.))
    .translated_3d(Vec3::new(1., 2., 3.));
let b = a.inverted();
assert_relative_eq!(a*b, Rows4::identity(), epsilon = 0.000001);
assert_relative_eq!(b*a, Rows4::identity(), epsilon = 0.000001);

let a = Cols4::scaling_3d(1.77_f32)
    .rotated_3d(PI*4./5., Vec3::new(5., 8., 10.))
    .translated_3d(Vec3::new(1., 2., 3.));
let b = a.inverted();
assert_relative_eq!(a*b, Cols4::identity(), epsilon = 0.000001);
assert_relative_eq!(b*a, Cols4::identity(), epsilon = 0.000001);

// Beware, projection matrices are not invertible!
// Notice that we assert _inequality_ below.
let a = Cols4::perspective_rh_zo(60_f32.to_radians(), 16./9., 0.001, 1000.) * a;
let b = a.inverted();
assert_relative_ne!(a*b, Cols4::identity(), epsilon = 0.000001);
assert_relative_ne!(b*a, Cols4::identity(), epsilon = 0.000001);
source

pub fn invert_affine_transform_no_scale(&mut self)
where T: Real,

Returns this matrix’s inverse, blindly assuming that it is an invertible transform matrix which scale is 1.

See inverted_affine_transform_no_scale() for more info.

source

pub fn inverted_affine_transform_no_scale(self) -> Self
where T: Real,

Returns this matrix’s inverse, blindly assuming that it is an invertible transform matrix which scale is 1.

A transform matrix is invertible this way as long as it consists of translations, rotations, and shears. It’s not guaranteed to work if the scale is not 1.

use vek::vec::repr_c::Vec3;
use vek::mat::repr_c::row_major::Mat4 as Rows4;
use vek::mat::repr_c::column_major::Mat4 as Cols4;
use std::f32::consts::PI;

let a = Rows4::rotation_3d(PI*4./5., Vec3::new(5., 8., 10.))
    .translated_3d(Vec3::new(1., 2., 3.));
let b = a.inverted_affine_transform_no_scale();
assert_relative_eq!(a*b, Rows4::identity(), epsilon = 0.000001);
assert_relative_eq!(b*a, Rows4::identity(), epsilon = 0.000001);

let a = Cols4::rotation_3d(PI*4./5., Vec3::new(5., 8., 10.))
    .translated_3d(Vec3::new(1., 2., 3.));
let b = a.inverted_affine_transform_no_scale();
assert_relative_eq!(a*b, Cols4::identity(), epsilon = 0.000001);
assert_relative_eq!(b*a, Cols4::identity(), epsilon = 0.000001);

// Look! It stops working as soon as we add a scale.
// Notice that we assert _inequality_ below.
let a = Rows4::scaling_3d(5_f32)
    .rotated_3d(PI*4./5., Vec3::new(5., 8., 10.))
    .translated_3d(Vec3::new(1., 2., 3.));
let b = a.inverted_affine_transform_no_scale();
assert_relative_ne!(a*b, Rows4::identity(), epsilon = 0.000001);
assert_relative_ne!(b*a, Rows4::identity(), epsilon = 0.000001);
source

pub fn invert_affine_transform(&mut self)
where T: Real,

Inverts this matrix, blindly assuming that it is an invertible transform matrix. See inverted_affine_transform() for more info.

source

pub fn inverted_affine_transform(self) -> Self
where T: Real,

Returns this matrix’s inverse, blindly assuming that it is an invertible transform matrix.

A transform matrix is invertible this way as long as it consists of translations, rotations, scales and shears.

use vek::vec::repr_c::Vec3;
use vek::mat::repr_c::row_major::Mat4 as Rows4;
use vek::mat::repr_c::column_major::Mat4 as Cols4;
use std::f32::consts::PI;

let a = Rows4::scaling_3d(1.77_f32)
    .rotated_3d(PI*4./5., Vec3::new(5., 8., 10.))
    .translated_3d(Vec3::new(1., 2., 3.));
let b = a.inverted_affine_transform();
assert_relative_eq!(a*b, Rows4::identity(), epsilon = 0.000001);
assert_relative_eq!(b*a, Rows4::identity(), epsilon = 0.000001);

let a = Cols4::scaling_3d(1.77_f32)
    .rotated_3d(PI*4./5., Vec3::new(5., 8., 10.))
    .translated_3d(Vec3::new(1., 2., 3.));
let b = a.inverted_affine_transform();
assert_relative_eq!(a*b, Cols4::identity(), epsilon = 0.000001);
assert_relative_eq!(b*a, Cols4::identity(), epsilon = 0.000001);
source

pub fn mul_point<V: Into<Vec3<T>> + From<Vec4<T>>>(self, rhs: V) -> V
where T: Real + MulAdd<T, T, Output = T>,

Shortcut for self * Vec4::from_point(rhs).

source

pub fn mul_direction<V: Into<Vec3<T>> + From<Vec4<T>>>(self, rhs: V) -> V
where T: Real + MulAdd<T, T, Output = T>,

Shortcut for self * Vec4::from_direction(rhs).

source

pub fn translate_2d<V: Into<Vec2<T>>>(&mut self, v: V)
where T: Real + MulAdd<T, T, Output = T>,

Translates this matrix in 2D.

source

pub fn translated_2d<V: Into<Vec2<T>>>(self, v: V) -> Self
where T: Real + MulAdd<T, T, Output = T>,

Returns this matrix translated in 2D.

source

pub fn translation_2d<V: Into<Vec2<T>>>(v: V) -> Self
where T: Zero + One,

Creates a 2D translation matrix.

source

pub fn translate_3d<V: Into<Vec3<T>>>(&mut self, v: V)
where T: Real + MulAdd<T, T, Output = T>,

Translates this matrix in 3D.

source

pub fn translated_3d<V: Into<Vec3<T>>>(self, v: V) -> Self
where T: Real + MulAdd<T, T, Output = T>,

Returns this matrix translated in 3D.

source

pub fn translation_3d<V: Into<Vec3<T>>>(v: V) -> Self
where T: Zero + One,

Creates a 3D translation matrix.

source

pub fn scale_3d<V: Into<Vec3<T>>>(&mut self, v: V)
where T: Real + MulAdd<T, T, Output = T>,

Scales this matrix in 3D.

source

pub fn scaled_3d<V: Into<Vec3<T>>>(self, v: V) -> Self
where T: Real + MulAdd<T, T, Output = T>,

Returns this matrix scaled in 3D.

source

pub fn scaling_3d<V: Into<Vec3<T>>>(v: V) -> Self
where T: Zero + One,

Creates a 3D scaling matrix.

source

pub fn rotate_x(&mut self, angle_radians: T)
where T: Real + MulAdd<T, T, Output = T>,

Rotates this matrix around the X axis.

source

pub fn rotated_x(self, angle_radians: T) -> Self
where T: Real + MulAdd<T, T, Output = T>,

Returns this matrix rotated around the X axis.

source

pub fn rotation_x(angle_radians: T) -> Self
where T: Real,

Creates a matrix that rotates around the X axis.

source

pub fn rotate_y(&mut self, angle_radians: T)
where T: Real + MulAdd<T, T, Output = T>,

Rotates this matrix around the Y axis.

source

pub fn rotated_y(self, angle_radians: T) -> Self
where T: Real + MulAdd<T, T, Output = T>,

Returns this matrix rotated around the Y axis.

source

pub fn rotation_y(angle_radians: T) -> Self
where T: Real,

Creates a matrix that rotates around the Y axis.

source

pub fn rotate_z(&mut self, angle_radians: T)
where T: Real + MulAdd<T, T, Output = T>,

Rotates this matrix around the Z axis.

source

pub fn rotated_z(self, angle_radians: T) -> Self
where T: Real + MulAdd<T, T, Output = T>,

Returns this matrix rotated around the Z axis.

source

pub fn rotation_z(angle_radians: T) -> Self
where T: Real,

Creates a matrix that rotates around the Z axis.

source

pub fn rotate_3d<V: Into<Vec3<T>>>(&mut self, angle_radians: T, axis: V)
where T: Real + MulAdd<T, T, Output = T> + Add<T, Output = T>,

Rotates this matrix around a 3D axis. The axis is not required to be normalized.

source

pub fn rotated_3d<V: Into<Vec3<T>>>(self, angle_radians: T, axis: V) -> Self
where T: Real + MulAdd<T, T, Output = T> + Add<T, Output = T>,

Returns this matrix rotated around a 3D axis. The axis is not required to be normalized.

source

pub fn rotation_3d<V: Into<Vec3<T>>>(angle_radians: T, axis: V) -> Self
where T: Real + Add<T, Output = T>,

Creates a matrix that rotates around a 3D axis. The axis is not required to be normalized.

use std::f32::consts::PI;

let v = Vec4::unit_x();

let m = Mat4::rotation_z(PI);
assert_relative_eq!(m * v, -v);

let m = Mat4::rotation_z(PI * 0.5);
assert_relative_eq!(m * v, Vec4::unit_y());

let m = Mat4::rotation_z(PI * 1.5);
assert_relative_eq!(m * v, -Vec4::unit_y());

let angles = 32;
for i in 0..angles {
    let theta = PI * 2. * (i as f32) / (angles as f32);

    // See what rotating unit vectors do for most angles between 0 and 2*PI.
    // It's helpful to picture this as a right-handed coordinate system.

    let v = Vec4::unit_y();
    let m = Mat4::rotation_x(theta);
    assert_relative_eq!(m * v, Vec4::new(0., theta.cos(), theta.sin(), 0.));

    let v = Vec4::unit_z();
    let m = Mat4::rotation_y(theta);
    assert_relative_eq!(m * v, Vec4::new(theta.sin(), 0., theta.cos(), 0.));

    let v = Vec4::unit_x();
    let m = Mat4::rotation_z(theta);
    assert_relative_eq!(m * v, Vec4::new(theta.cos(), theta.sin(), 0., 0.));

    assert_relative_eq!(Mat4::rotation_x(theta), Mat4::rotation_3d(theta, Vec4::unit_x()));
    assert_relative_eq!(Mat4::rotation_y(theta), Mat4::rotation_3d(theta, Vec4::unit_y()));
    assert_relative_eq!(Mat4::rotation_z(theta), Mat4::rotation_3d(theta, Vec4::unit_z()));
}
source

pub fn rotation_from_to_3d<V: Into<Vec3<T>>>(from: V, to: V) -> Self
where T: Real + Add<T, Output = T>,

Creates a matrix that would rotate a from direction to to.


let (from, to) = (Vec4::<f32>::unit_x(), Vec4::<f32>::unit_z());
let m = Mat4::<f32>::rotation_from_to_3d(from, to);
assert_relative_eq!(m * from, to);

let (from, to) = (Vec4::<f32>::unit_x(), -Vec4::<f32>::unit_x());
let m = Mat4::<f32>::rotation_from_to_3d(from, to);
assert_relative_eq!(m * from, to);
source

pub fn basis_to_local<V: Into<Vec3<T>>>(origin: V, i: V, j: V, k: V) -> Self
where T: Zero + One + Neg<Output = T> + Real + Add<T, Output = T>,

Builds a change of basis matrix that transforms points and directions from any space to the canonical one.

origin is the origin of the child space. i, j and k are all required to be normalized; They are the unit basis vector along the target space x-axis, y-axis and z-axis respectively, expressed in canonical-space coordinates.

    let origin = Vec3::new(1_f32, 2., 3.);
    let i = Vec3::unit_z();
    let j = Vec3::unit_y();
    let k = Vec3::unit_x();
    let m = Mat4::basis_to_local(origin, i, j, k);
    assert_relative_eq!(m.mul_point(origin), Vec3::zero());
    assert_relative_eq!(m.mul_point(origin+i), Vec3::unit_x());
    assert_relative_eq!(m.mul_point(origin+j), Vec3::unit_y());
    assert_relative_eq!(m.mul_point(origin+k), Vec3::unit_z());

    // `local_to_basis` and `basis_to_local` undo each other
    let a = Mat4::<f32>::basis_to_local(origin, i, j, k);
    let b = Mat4::<f32>::local_to_basis(origin, i, j, k);
    assert_relative_eq!(a*b, Mat4::identity());
    assert_relative_eq!(b*a, Mat4::identity());

Slightly more contrived example:

    let origin = Vec3::new(1_f32, 2., 3.);
    let r = Mat4::rotation_3d(3., Vec3::new(2_f32, 1., 3.));
    let i = r.mul_direction(Vec3::unit_x());
    let j = r.mul_direction(Vec3::unit_y());
    let k = r.mul_direction(Vec3::unit_z());
    let m = Mat4::basis_to_local(origin, i, j, k);
    assert_relative_eq!(m.mul_point(origin), Vec3::zero(), epsilon = 0.000001);
    assert_relative_eq!(m.mul_point(origin+i), Vec3::unit_x(), epsilon = 0.000001);
    assert_relative_eq!(m.mul_point(origin+j), Vec3::unit_y(), epsilon = 0.000001);
    assert_relative_eq!(m.mul_point(origin+k), Vec3::unit_z(), epsilon = 0.000001);
source

pub fn local_to_basis<V: Into<Vec3<T>>>(origin: V, i: V, j: V, k: V) -> Self
where T: Zero + One,

Builds a change of basis matrix that transforms points and directions from canonical space to another space.

origin is the origin of the child space. i, j and k are all required to be normalized; They are the unit basis vector along the target space x-axis, y-axis and z-axis respectively, expressed in canonical-space coordinates.

    let origin = Vec3::new(1_f32, 2., 3.);
    let i = Vec3::unit_z();
    let j = Vec3::unit_y();
    let k = Vec3::unit_x();
    let m = Mat4::local_to_basis(origin, i, j, k);
    assert_relative_eq!(origin,   m.mul_point(Vec3::zero()));
    assert_relative_eq!(origin+i, m.mul_point(Vec3::unit_x()));
    assert_relative_eq!(origin+j, m.mul_point(Vec3::unit_y()));
    assert_relative_eq!(origin+k, m.mul_point(Vec3::unit_z()));

    // `local_to_basis` and `basis_to_local` undo each other
    let a = Mat4::<f32>::local_to_basis(origin, i, j, k);
    let b = Mat4::<f32>::basis_to_local(origin, i, j, k);
    assert_relative_eq!(a*b, Mat4::identity());
    assert_relative_eq!(b*a, Mat4::identity());

Slightly more contrived example:

    // Sanity test
    let origin = Vec3::new(1_f32, 2., 3.);
    let r = Mat4::rotation_3d(3., Vec3::new(2_f32, 1., 3.));
    let i = r.mul_direction(Vec3::unit_x());
    let j = r.mul_direction(Vec3::unit_y());
    let k = r.mul_direction(Vec3::unit_z());
    let m = Mat4::local_to_basis(origin, i, j, k);
    assert_relative_eq!(origin,   m.mul_point(Vec3::zero()));
    assert_relative_eq!(origin+i, m.mul_point(Vec3::unit_x()));
    assert_relative_eq!(origin+j, m.mul_point(Vec3::unit_y()));
    assert_relative_eq!(origin+k, m.mul_point(Vec3::unit_z()));
source

pub fn look_at<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self
where T: Real + Add<T, Output = T>,

👎Deprecated since 0.9.7: Use look_at_lh() or look_at_rh() instead depending on your space’s handedness

Builds a “look at” view transform from an eye position, a target position, and up vector. Commonly used for cameras - in short, it maps points from world-space to eye-space.

source

pub fn look_at_lh<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self
where T: Real + Add<T, Output = T>,

Builds a “look at” view transform for left-handed spaces from an eye position, a target position, and up vector. Commonly used for cameras - in short, it maps points from world-space to eye-space.

let eye = Vec4::new(1_f32, 0., 1., 1.);
let target = Vec4::new(2_f32, 0., 2., 1.);
let view = Mat4::<f32>::look_at_lh(eye, target, Vec4::unit_y());
assert_relative_eq!(view * eye, Vec4::unit_w());
assert_relative_eq!(view * target, Vec4::new(0_f32, 0., 2_f32.sqrt(), 1.));
source

pub fn look_at_rh<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self
where T: Real + Add<T, Output = T>,

Builds a “look at” view transform for right-handed spaces from an eye position, a target position, and up vector. Commonly used for cameras - in short, it maps points from world-space to eye-space.

let eye = Vec4::new(1_f32, 0., 1., 1.);
let target = Vec4::new(2_f32, 0., 2., 1.);
let view = Mat4::<f32>::look_at_rh(eye, target, Vec4::unit_y());
assert_relative_eq!(view * eye, Vec4::unit_w());
assert_relative_eq!(view * target, Vec4::new(0_f32, 0., -2_f32.sqrt(), 1.));
source

pub fn model_look_at<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self
where T: Real + Add<T, Output = T>,

👎Deprecated since 0.9.7: Use model_look_at_lh() or model_look_at_rh() instead depending on your space’s handedness

Builds a “look at” model transform from an eye position, a target position, and up vector. Preferred for transforming objects.

source

pub fn model_look_at_lh<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self
where T: Real + Add<T, Output = T>,

Builds a “look at” model transform for left-handed spaces from an eye position, a target position, and up vector. Preferred for transforming objects.

let eye = Vec4::new(1_f32, 0., 1., 1.);
let target = Vec4::new(2_f32, 0., 2., 1.);
let model = Mat4::<f32>::model_look_at_lh(eye, target, Vec4::unit_y());
assert_relative_eq!(model * Vec4::unit_w(), eye);
let d = 2_f32.sqrt();
assert_relative_eq!(model * Vec4::new(0_f32, 0., d, 1.), target);

// A "model" look-at essentially undoes a "view" look-at
let view = Mat4::look_at_lh(eye, target, Vec4::unit_y());
assert_relative_eq!(view * model, Mat4::identity());
assert_relative_eq!(model * view, Mat4::identity());
source

pub fn model_look_at_rh<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self
where T: Real + Add<T, Output = T> + MulAdd<T, T, Output = T>,

Builds a “look at” model transform for right-handed spaces from an eye position, a target position, and up vector. Preferred for transforming objects.

let eye = Vec4::new(1_f32, 0., -1., 1.);
let forward = Vec4::new(0_f32, 0., -1., 0.);
let model = Mat4::<f32>::model_look_at_rh(eye, eye + forward, Vec4::unit_y());
assert_relative_eq!(model * Vec4::unit_w(), eye);
assert_relative_eq!(model * forward, forward);

// A "model" look-at essentially undoes a "view" look-at
let view = Mat4::look_at_rh(eye, eye + forward, Vec4::unit_y());
assert_relative_eq!(view * model, Mat4::identity());
assert_relative_eq!(model * view, Mat4::identity());
source

pub fn orthographic_without_depth_planes(o: FrustumPlanes<T>) -> Self
where T: Real,

Returns an orthographic projection matrix that doesn’t use near and far planes.

source

pub fn orthographic_lh_zo(o: FrustumPlanes<T>) -> Self
where T: Real,

Returns an orthographic projection matrix for left-handed spaces, for a depth clip space ranging from 0 to 1 (GL_DEPTH_ZERO_TO_ONE, hence the _zo suffix).

let m = Mat4::orthographic_lh_zo(FrustumPlanes {
    left: -1_f32, right: 1., bottom: -1., top: 1.,
    near: 0., far: 1.
});
let v = Vec4::new(0_f32, 0., 1., 1.); // "forward"
assert_relative_eq!(m * v, Vec4::new(0., 0., 1., 1.)); // "far"
source

pub fn orthographic_lh_no(o: FrustumPlanes<T>) -> Self
where T: Real,

Returns an orthographic projection matrix for left-handed spaces, for a depth clip space ranging from -1 to 1 (GL_DEPTH_NEGATIVE_ONE_TO_ONE, hence the _no suffix).

let m = Mat4::orthographic_lh_no(FrustumPlanes {
    left: -1_f32, right: 1., bottom: -1., top: 1.,
    near: 0., far: 1.
});
let v = Vec4::new(0_f32, 0., 1., 1.); // "forward"
assert_relative_eq!(m * v, Vec4::new(0., 0., 1., 1.)); // "far"
source

pub fn orthographic_rh_zo(o: FrustumPlanes<T>) -> Self
where T: Real,

Returns an orthographic projection matrix for right-handed spaces, for a depth clip space ranging from 0 to 1 (GL_DEPTH_ZERO_TO_ONE, hence the _zo suffix).

let m = Mat4::orthographic_rh_zo(FrustumPlanes {
    left: -1_f32, right: 1., bottom: -1., top: 1.,
    near: 0., far: 1.
});
let v = Vec4::new(0_f32, 0., -1., 1.); // "forward"
assert_relative_eq!(m * v, Vec4::new(0., 0., 1., 1.)); // "far"
source

pub fn orthographic_rh_no(o: FrustumPlanes<T>) -> Self
where T: Real,

Returns an orthographic projection matrix for right-handed spaces, for a depth clip space ranging from -1 to 1 (GL_DEPTH_NEGATIVE_ONE_TO_ONE, hence the _no suffix).

let m = Mat4::orthographic_rh_no(FrustumPlanes {
    left: -1_f32, right: 1., bottom: -1., top: 1.,
    near: 0., far: 1.
});
let v = Vec4::new(0_f32, 0., -1., 1.); // "forward"
assert_relative_eq!(m * v, Vec4::new(0., 0., 1., 1.)); // "far"
source

pub fn frustum_lh_zo(o: FrustumPlanes<T>) -> Self
where T: Real,

Creates a perspective projection matrix from a frustum (left-handed, zero-to-one depth clip planes).

source

pub fn frustum_lh_no(o: FrustumPlanes<T>) -> Self
where T: Real,

Creates a perspective projection matrix from a frustum (left-handed, negative-one-to-one depth clip planes).

source

pub fn frustum_rh_zo(o: FrustumPlanes<T>) -> Self
where T: Real,

Creates a perspective projection matrix from a frustum (right-handed, zero-to-one depth clip planes).

source

pub fn frustum_rh_no(o: FrustumPlanes<T>) -> Self
where T: Real,

Creates a perspective projection matrix from a frustum (right-handed, negative-one-to-one depth clip planes).

source

pub fn perspective_rh_zo( fov_y_radians: T, aspect_ratio: T, near: T, far: T ) -> Self
where T: Real + FloatConst + Debug,

Creates a perspective projection matrix for right-handed spaces, with zero-to-one depth clip planes.

source

pub fn perspective_lh_zo( fov_y_radians: T, aspect_ratio: T, near: T, far: T ) -> Self
where T: Real + FloatConst + Debug,

Creates a perspective projection matrix for left-handed spaces, with zero-to-one depth clip planes.

source

pub fn perspective_rh_no( fov_y_radians: T, aspect_ratio: T, near: T, far: T ) -> Self
where T: Real + FloatConst + Debug,

Creates a perspective projection matrix for right-handed spaces, with negative-one-to-one depth clip planes.

source

pub fn perspective_lh_no( fov_y_radians: T, aspect_ratio: T, near: T, far: T ) -> Self
where T: Real + FloatConst + Debug,

Creates a perspective projection matrix for left-handed spaces, with negative-one-to-one depth clip planes.

source

pub fn perspective_fov_rh_zo( fov_y_radians: T, width: T, height: T, near: T, far: T ) -> Self
where T: Real + FloatConst + Debug,

Creates a perspective projection matrix for right-handed spaces, with zero-to-one depth clip planes.

§Panics

width, height and fov_y_radians must all be strictly greater than zero.

source

pub fn perspective_fov_lh_zo( fov_y_radians: T, width: T, height: T, near: T, far: T ) -> Self
where T: Real + FloatConst + Debug,

Creates a perspective projection matrix for left-handed spaces, with zero-to-one depth clip planes.

§Panics

width, height and fov_y_radians must all be strictly greater than zero.

source

pub fn perspective_fov_rh_no( fov_y_radians: T, width: T, height: T, near: T, far: T ) -> Self
where T: Real + FloatConst + Debug,

Creates a perspective projection matrix for right-handed spaces, with negative-one-to-one depth clip planes.

§Panics

width, height and fov_y_radians must all be strictly greater than zero.

source

pub fn perspective_fov_lh_no( fov_y_radians: T, width: T, height: T, near: T, far: T ) -> Self
where T: Real + FloatConst + Debug,

Creates a perspective projection matrix for left-handed spaces, with negative-one-to-one depth clip planes.

§Panics

width, height and fov_y_radians must all be strictly greater than zero.

source

pub fn tweaked_infinite_perspective_rh( fov_y_radians: T, aspect_ratio: T, near: T, epsilon: T ) -> Self
where T: Real + FloatConst + Debug,

Creates an infinite perspective projection matrix for right-handed spaces.

Link to PDF

source

pub fn tweaked_infinite_perspective_lh( fov_y_radians: T, aspect_ratio: T, near: T, epsilon: T ) -> Self
where T: Real + FloatConst + Debug,

Creates an infinite perspective projection matrix for left-handed spaces.

source

pub fn infinite_perspective_rh( fov_y_radians: T, aspect_ratio: T, near: T ) -> Self
where T: Real + FloatConst + Debug,

Creates an infinite perspective projection matrix for right-handed spaces.

source

pub fn infinite_perspective_lh( fov_y_radians: T, aspect_ratio: T, near: T ) -> Self
where T: Real + FloatConst + Debug,

Creates an infinite perspective projection matrix for left-handed spaces.

source

pub fn picking_region<V2: Into<Vec2<T>>>( center: V2, delta: V2, viewport: Rect<T, T> ) -> Self
where T: Real + MulAdd<T, T, Output = T>,

GLM’s pickMatrix. Creates a projection matrix that can be used to restrict drawing to a small region of the viewport.

§Panics

delta’s x and y are required to be strictly greater than zero.

source

pub fn world_to_viewport_no<V3>( obj: V3, modelview: Self, proj: Self, viewport: Rect<T, T> ) -> Vec3<T>
where T: Real + MulAdd<T, T, Output = T>, V3: Into<Vec3<T>>,

Projects a world-space coordinate into screen space, for a depth clip space ranging from -1 to 1 (GL_DEPTH_NEGATIVE_ONE_TO_ONE, hence the _no suffix).

source

pub fn world_to_viewport_zo<V3>( obj: V3, modelview: Self, proj: Self, viewport: Rect<T, T> ) -> Vec3<T>
where T: Real + MulAdd<T, T, Output = T>, V3: Into<Vec3<T>>,

Projects a world-space coordinate into screen space, for a depth clip space ranging from 0 to 1 (GL_DEPTH_ZERO_TO_ONE, hence the _zo suffix).

source

pub fn viewport_to_world_zo<V3>( ray: V3, modelview: Self, proj: Self, viewport: Rect<T, T> ) -> Vec3<T>
where T: Real + MulAdd<T, T, Output = T>, V3: Into<Vec3<T>>,

Projects a screen-space coordinate into world space, for a depth clip space ranging from 0 to 1 (GL_DEPTH_ZERO_TO_ONE, hence the _zo suffix).

source

pub fn viewport_to_world_no<V3>( ray: V3, modelview: Self, proj: Self, viewport: Rect<T, T> ) -> Vec3<T>
where T: Real + MulAdd<T, T, Output = T>, V3: Into<Vec3<T>>,

Projects a screen-space coordinate into world space, for a depth clip space ranging from -1 to 1 (GL_DEPTH_NEGATIVE_ONE_TO_ONE, hence the _no suffix).

Trait Implementations§

source§

impl<T: AbsDiffEq> AbsDiffEq for Mat4<T>
where T::Epsilon: Copy,

§

type Epsilon = <T as AbsDiffEq>::Epsilon

Used for specifying relative comparisons.
source§

fn default_epsilon() -> T::Epsilon

The default tolerance to use when testing values that are close together. Read more
source§

fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool

A test for equality that uses the absolute difference to compute the approximate equality of two numbers.
source§

fn abs_diff_ne(&self, other: &Rhs, epsilon: Self::Epsilon) -> bool

The inverse of AbsDiffEq::abs_diff_eq.
source§

impl<T> Add<T> for Mat4<T>
where T: Copy + Add<Output = T>,

§

type Output = Mat4<T>

The resulting type after applying the + operator.
source§

fn add(self, rhs: T) -> Self::Output

Performs the + operation. Read more
source§

impl<T> Add for Mat4<T>
where T: Add<Output = T>,

§

type Output = Mat4<T>

The resulting type after applying the + operator.
source§

fn add(self, rhs: Self) -> Self::Output

Performs the + operation. Read more
source§

impl<T: Add<Output = T> + Copy> AddAssign<T> for Mat4<T>

source§

fn add_assign(&mut self, rhs: T)

Performs the += operation. Read more
source§

impl<T: Add<Output = T> + Copy> AddAssign for Mat4<T>

source§

fn add_assign(&mut self, rhs: Self)

Performs the += operation. Read more
source§

impl<T: Clone> Clone for Mat4<T>

source§

fn clone(&self) -> Mat4<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Mat4<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Zero + One> Default for Mat4<T>

The default value for a square matrix is the identity.

assert_eq!(Mat4::<f32>::default(), Mat4::<f32>::identity());
source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<'de, T> Deserialize<'de> for Mat4<T>
where T: Deserialize<'de>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<T: Display> Display for Mat4<T>

Displays this matrix using the following format:

(i being the number of rows and j the number of columns)

( m00 ... m0j
  ... ... ...
  mi0 ... mij )

Note that elements are not comma-separated. This format doesn’t depend on the matrix’s storage layout.

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Div<T> for Mat4<T>
where T: Copy + Div<Output = T>,

§

type Output = Mat4<T>

The resulting type after applying the / operator.
source§

fn div(self, rhs: T) -> Self::Output

Performs the / operation. Read more
source§

impl<T> Div for Mat4<T>
where T: Div<Output = T>,

§

type Output = Mat4<T>

The resulting type after applying the / operator.
source§

fn div(self, rhs: Self) -> Self::Output

Performs the / operation. Read more
source§

impl<T: Div<Output = T> + Copy> DivAssign<T> for Mat4<T>

source§

fn div_assign(&mut self, rhs: T)

Performs the /= operation. Read more
source§

impl<T: Div<Output = T> + Copy> DivAssign for Mat4<T>

source§

fn div_assign(&mut self, rhs: Self)

Performs the /= operation. Read more
source§

impl<T> From<Mat2<T>> for Mat4<T>
where T: Zero + One,

source§

fn from(m: Mat2<T>) -> Self

Converts to this type from the input type.
source§

impl<T> From<Mat3<T>> for Mat4<T>
where T: Zero + One,

source§

fn from(m: Mat3<T>) -> Self

Converts to this type from the input type.
source§

impl<T> From<Mat4<T>> for Mat2<T>

source§

fn from(m: Mat4<T>) -> Self

Converts to this type from the input type.
source§

impl<T> From<Mat4<T>> for Mat3<T>

source§

fn from(m: Mat4<T>) -> Self

Converts to this type from the input type.
source§

impl<T> From<Mat4<T>> for Mat4<T>

source§

fn from(m: Transpose<T>) -> Self

Converts to this type from the input type.
source§

impl<T> From<Mat4<T>> for Mat4<T>

source§

fn from(m: Transpose<T>) -> Self

Converts to this type from the input type.
source§

impl<T> From<Quaternion<T>> for Mat4<T>
where T: Copy + Zero + One + Mul<Output = T> + Add<Output = T> + Sub<Output = T>,

Rotation matrices can be obtained from quaternions. This implementation only works properly if the quaternion is normalized.

use std::f32::consts::PI;

let angles = 32;
for i in 0..angles {
    let theta = PI * 2. * (i as f32) / (angles as f32);

    assert_relative_eq!(Mat4::rotation_x(theta), Mat4::from(Quaternion::rotation_x(theta)), epsilon = 0.000001);
    assert_relative_eq!(Mat4::rotation_y(theta), Mat4::from(Quaternion::rotation_y(theta)), epsilon = 0.000001);
    assert_relative_eq!(Mat4::rotation_z(theta), Mat4::from(Quaternion::rotation_z(theta)), epsilon = 0.000001);

    assert_relative_eq!(Mat4::rotation_x(theta), Mat4::rotation_3d(theta, Vec4::unit_x()));
    assert_relative_eq!(Mat4::rotation_y(theta), Mat4::rotation_3d(theta, Vec4::unit_y()));
    assert_relative_eq!(Mat4::rotation_z(theta), Mat4::rotation_3d(theta, Vec4::unit_z()));

    // See what rotating unit vectors do for most angles between 0 and 2*PI.
    // It's helpful to picture this as a right-handed coordinate system.

    let v = Vec4::unit_y();
    let m = Mat4::rotation_x(theta);
    assert_relative_eq!(m * v, Vec4::new(0., theta.cos(), theta.sin(), 0.));

    let v = Vec4::unit_z();
    let m = Mat4::rotation_y(theta);
    assert_relative_eq!(m * v, Vec4::new(theta.sin(), 0., theta.cos(), 0.));

    let v = Vec4::unit_x();
    let m = Mat4::rotation_z(theta);
    assert_relative_eq!(m * v, Vec4::new(theta.cos(), theta.sin(), 0., 0.));
}
source§

fn from(q: Quaternion<T>) -> Self

Converts to this type from the input type.
source§

impl<T> From<Transform<T, T, T>> for Mat4<T>
where T: Real + MulAdd<T, T, Output = T>,

A Mat4 can be obtained from a Transform, by rotating, then scaling, then translating.

source§

fn from(xform: Transform<T, T, T>) -> Self

Converts to this type from the input type.
source§

impl<T: Hash> Hash for Mat4<T>

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<T> Index<(usize, usize)> for Mat4<T>

Index this matrix in a layout-agnostic way with an (i, j) (row index, column index) tuple.

Matrices cannot be indexed by Vec2s because that would be likely to cause confusion: should x be the row index (because it’s the first element) or the column index (because it’s a horizontal position) ?

§

type Output = T

The returned type after indexing.
source§

fn index(&self, t: (usize, usize)) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
source§

impl<T> IndexMut<(usize, usize)> for Mat4<T>

source§

fn index_mut(&mut self, t: (usize, usize)) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more
source§

impl<T> Mul<CubicBezier3<T>> for Rows4<T>
where T: Real + MulAdd<T, T, Output = T>,

§

type Output = CubicBezier3<T>

The resulting type after applying the * operator.
source§

fn mul(self, rhs: CubicBezier3<T>) -> CubicBezier3<T>

Performs the * operation. Read more
source§

impl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Mat4<T>> for Mat4<T>

Multiplies a column-major matrix with a row-major matrix.

use vek::mat::row_major::Mat4 as Rows4;
use vek::mat::column_major::Mat4 as Cols4;

let m = Cols4::<u32>::new(
    0, 1, 2, 3,
    4, 5, 6, 7,
    8, 9, 0, 1,
    2, 3, 4, 5
);
let b = Rows4::from(m);
let r = Rows4::<u32>::new(
    26, 32, 18, 24,
    82, 104, 66, 88,
    38, 56, 74, 92,
    54, 68, 42, 56
);
assert_eq!(m * b, r);
assert_eq!(m * Rows4::<u32>::identity(), m.into());
assert_eq!(Cols4::<u32>::identity() * b, m.into());
§

type Output = Mat4<T>

The resulting type after applying the * operator.
source§

fn mul(self, rhs: Transpose<T>) -> Self::Output

Performs the * operation. Read more
source§

impl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Mat4<T>> for Mat4<T>

Multiplies a row-major matrix with a column-major matrix, producing a column-major matrix.

use vek::mat::row_major::Mat4 as Rows4;
use vek::mat::column_major::Mat4 as Cols4;

let m = Rows4::<u32>::new(
    0, 1, 2, 3,
    4, 5, 6, 7,
    8, 9, 0, 1,
    2, 3, 4, 5
);
let b = Cols4::from(m);
let r = Cols4::<u32>::new(
    26, 32, 18, 24,
    82, 104, 66, 88,
    38, 56, 74, 92,
    54, 68, 42, 56
);
assert_eq!(m * b, r);
assert_eq!(m * Cols4::<u32>::identity(), m.into());
assert_eq!(Rows4::<u32>::identity() * b, m.into());
§

type Output = Mat4<T>

The resulting type after applying the * operator.
source§

fn mul(self, rhs: Transpose<T>) -> Self::Output

Performs the * operation. Read more
source§

impl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Mat4<T>> for Vec4<T>

Multiplies a row vector with a row-major matrix, giving a row vector.

With SIMD vectors, this is the most efficient way.

use vek::mat::row_major::Mat4;
use vek::vec::Vec4;

let m = Mat4::new(
    0, 1, 2, 3,
    4, 5, 6, 7,
    8, 9, 0, 1,
    2, 3, 4, 5
);
let v = Vec4::new(0, 1, 2, 3);
let r = Vec4::new(26, 32, 18, 24);
assert_eq!(v * m, r);
§

type Output = Vec4<T>

The resulting type after applying the * operator.
source§

fn mul(self, rhs: Mat4<T>) -> Self::Output

Performs the * operation. Read more
source§

impl<T> Mul<QuadraticBezier3<T>> for Rows4<T>
where T: Real + MulAdd<T, T, Output = T>,

§

type Output = QuadraticBezier3<T>

The resulting type after applying the * operator.
source§

fn mul(self, rhs: QuadraticBezier3<T>) -> QuadraticBezier3<T>

Performs the * operation. Read more
source§

impl<T> Mul<T> for Mat4<T>
where T: Copy + Zero + Add<Output = T> + Mul<Output = T>,

§

type Output = Mat4<T>

The resulting type after applying the * operator.
source§

fn mul(self, rhs: T) -> Self::Output

Performs the * operation. Read more
source§

impl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Vec4<T>> for Mat4<T>

Multiplies a row-major matrix with a column vector, giving a column vector.

use vek::mat::row_major::Mat4;
use vek::vec::Vec4;

let m = Mat4::new(
    0, 1, 2, 3,
    4, 5, 6, 7,
    8, 9, 0, 1,
    2, 3, 4, 5
);
let v = Vec4::new(0, 1, 2, 3);
let r = Vec4::new(14, 38, 12, 26);
assert_eq!(m * v, r);
§

type Output = Vec4<T>

The resulting type after applying the * operator.
source§

fn mul(self, v: Vec4<T>) -> Self::Output

Performs the * operation. Read more
source§

impl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul for Mat4<T>

Multiplies a row-major matrix with another.

use vek::mat::row_major::Mat4;

let m = Mat4::<u32>::new(
    0, 1, 2, 3,
    4, 5, 6, 7,
    8, 9, 0, 1,
    2, 3, 4, 5
);
let r = Mat4::<u32>::new(
    26, 32, 18, 24,
    82, 104, 66, 88,
    38, 56, 74, 92,
    54, 68, 42, 56
);
assert_eq!(m * m, r);
assert_eq!(m, m * Mat4::<u32>::identity());
assert_eq!(m, Mat4::<u32>::identity() * m);
§

type Output = Mat4<T>

The resulting type after applying the * operator.
source§

fn mul(self, rhs: Self) -> Self::Output

Performs the * operation. Read more
source§

impl<T> MulAssign<T> for Mat4<T>
where T: Copy + Zero + Add<Output = T> + Mul<Output = T>,

source§

fn mul_assign(&mut self, rhs: T)

Performs the *= operation. Read more
source§

impl<T> MulAssign for Mat4<T>
where T: Copy + Zero + Add<Output = T> + Mul<Output = T> + MulAdd<T, T, Output = T>,

source§

fn mul_assign(&mut self, rhs: Self)

Performs the *= operation. Read more
source§

impl<T> Neg for Mat4<T>
where T: Neg<Output = T>,

§

type Output = Mat4<T>

The resulting type after applying the - operator.
source§

fn neg(self) -> Self::Output

Performs the unary - operation. Read more
source§

impl<T: Zero + One + Copy + MulAdd<T, T, Output = T>> One for Mat4<T>

source§

fn one() -> Self

Returns the multiplicative identity element of Self, 1. Read more
source§

fn set_one(&mut self)

Sets self to the multiplicative identity element of Self, 1.
source§

impl<T: PartialEq> PartialEq for Mat4<T>

source§

fn eq(&self, other: &Mat4<T>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<T: RelativeEq> RelativeEq for Mat4<T>
where T::Epsilon: Copy,

source§

fn default_max_relative() -> T::Epsilon

The default relative tolerance for testing values that are far-apart. Read more
source§

fn relative_eq( &self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon ) -> bool

A test for equality that uses a relative comparison if the values are far apart.
source§

fn relative_ne( &self, other: &Rhs, epsilon: Self::Epsilon, max_relative: Self::Epsilon ) -> bool

The inverse of RelativeEq::relative_eq.
source§

impl<T> Rem<T> for Mat4<T>
where T: Copy + Rem<Output = T>,

§

type Output = Mat4<T>

The resulting type after applying the % operator.
source§

fn rem(self, rhs: T) -> Self::Output

Performs the % operation. Read more
source§

impl<T> Rem for Mat4<T>
where T: Rem<Output = T>,

§

type Output = Mat4<T>

The resulting type after applying the % operator.
source§

fn rem(self, rhs: Self) -> Self::Output

Performs the % operation. Read more
source§

impl<T: Rem<Output = T> + Copy> RemAssign<T> for Mat4<T>

source§

fn rem_assign(&mut self, rhs: T)

Performs the %= operation. Read more
source§

impl<T: Rem<Output = T> + Copy> RemAssign for Mat4<T>

source§

fn rem_assign(&mut self, rhs: Self)

Performs the %= operation. Read more
source§

impl<T> Serialize for Mat4<T>
where T: Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<T> Sub<T> for Mat4<T>
where T: Copy + Sub<Output = T>,

§

type Output = Mat4<T>

The resulting type after applying the - operator.
source§

fn sub(self, rhs: T) -> Self::Output

Performs the - operation. Read more
source§

impl<T> Sub for Mat4<T>
where T: Sub<Output = T>,

§

type Output = Mat4<T>

The resulting type after applying the - operator.
source§

fn sub(self, rhs: Self) -> Self::Output

Performs the - operation. Read more
source§

impl<T: Sub<Output = T> + Copy> SubAssign<T> for Mat4<T>

source§

fn sub_assign(&mut self, rhs: T)

Performs the -= operation. Read more
source§

impl<T: Sub<Output = T> + Copy> SubAssign for Mat4<T>

source§

fn sub_assign(&mut self, rhs: Self)

Performs the -= operation. Read more
source§

impl<T: UlpsEq> UlpsEq for Mat4<T>
where T::Epsilon: Copy,

source§

fn default_max_ulps() -> u32

The default ULPs to tolerate when testing values that are far-apart. Read more
source§

fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool

A test for equality that uses units in the last place (ULP) if the values are far apart.
source§

fn ulps_ne(&self, other: &Rhs, epsilon: Self::Epsilon, max_ulps: u32) -> bool

The inverse of UlpsEq::ulps_eq.
source§

impl<T: Zero + PartialEq> Zero for Mat4<T>

source§

fn zero() -> Self

Returns the additive identity element of Self, 0. Read more
source§

fn is_zero(&self) -> bool

Returns true if self is equal to the additive identity.
source§

fn set_zero(&mut self)

Sets self to the additive identity element of Self, 0.
source§

impl<T: Copy> Copy for Mat4<T>

source§

impl<T: Eq> Eq for Mat4<T>

source§

impl<T> StructuralPartialEq for Mat4<T>

Auto Trait Implementations§

§

impl<T> Freeze for Mat4<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Mat4<T>
where T: RefUnwindSafe,

§

impl<T> Send for Mat4<T>
where T: Send,

§

impl<T> Sync for Mat4<T>
where T: Sync,

§

impl<T> Unpin for Mat4<T>
where T: Unpin,

§

impl<T> UnwindSafe for Mat4<T>
where T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

source§

impl<T, Rhs> NumAssignOps<Rhs> for T
where T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>,

source§

impl<T, Rhs, Output> NumOps<Rhs, Output> for T
where T: Sub<Rhs, Output = Output> + Mul<Rhs, Output = Output> + Div<Rhs, Output = Output> + Add<Rhs, Output = Output> + Rem<Rhs, Output = Output>,