Expand description
4x4 matrix.
Fields
cols: CVec4<Vec4<T>>
Implementations
sourceimpl<T> Mat4<T>
impl<T> Mat4<T>
sourcepub fn identity() -> Self where
T: Zero + One,
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());
sourcepub fn apply<F>(&mut self, f: F) where
T: Copy,
F: FnMut(T) -> T,
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.
sourcepub fn apply2<F, S>(&mut self, other: Mat4<S>, f: F) where
T: Copy,
F: FnMut(T, S) -> T,
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.
sourcepub fn numcast<D>(self) -> Option<Mat4<D>> where
T: NumCast,
D: NumCast,
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());
sourcepub fn broadcast_diagonal(val: T) -> Self where
T: Zero + Copy,
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,
));
sourcepub fn with_diagonal(d: Vec4<T>) -> Self where
T: Zero + Copy,
pub fn with_diagonal(d: Vec4<T>) -> Self where
T: Zero + Copy,
Initializes a matrix by its diagonal, setting other elements to zero.
sourcepub fn diagonal(self) -> Vec4<T>
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);
sourcepub fn trace(self) -> T where
T: Add<T, Output = T>,
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);
sourcepub fn mul_memberwise(self, m: Self) -> Self where
T: Mul<Output = T>,
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);
sourcepub const ROW_COUNT: usize = 4usize
pub const ROW_COUNT: usize = 4usize
Convenience constant representing the number of rows for matrices of this type.
sourceimpl<T> Mat4<T>
impl<T> Mat4<T>
sourcepub fn map_cols<D, F>(self, f: F) -> Mat4<D> where
F: FnMut(Vec4<T>) -> Vec4<D>,
pub fn map_cols<D, F>(self, f: F) -> Mat4<D> where
F: FnMut(Vec4<T>) -> Vec4<D>,
Returns a column-wise-converted copy of this matrix, using the given conversion closure.
use vek::mat::repr_c::column_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_cols(|col| col.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
));
sourcepub fn into_col_array(self) -> [T; 16]
pub fn into_col_array(self) -> [T; 16]
Converts this matrix into a fixed-size array of elements.
use vek::mat::repr_c::column_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);
sourcepub fn into_col_arrays(self) -> [[T; 4]; 4]
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::column_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);
sourcepub fn from_col_array(array: [T; 16]) -> Self
pub fn from_col_array(array: [T; 16]) -> Self
Converts a fixed-size array of elements into a matrix.
use vek::mat::repr_c::column_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));
sourcepub fn from_col_arrays(array: [[T; 4]; 4]) -> Self
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::column_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));
sourcepub fn into_row_array(self) -> [T; 16]
pub fn into_row_array(self) -> [T; 16]
Converts this matrix into a fixed-size array of elements.
use vek::mat::repr_c::column_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);
sourcepub fn into_row_arrays(self) -> [[T; 4]; 4]
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::column_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);
sourcepub fn from_row_array(array: [T; 16]) -> Self
pub fn from_row_array(array: [T; 16]) -> Self
Converts a fixed-size array of elements into a matrix.
use vek::mat::repr_c::column_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));
sourcepub fn from_row_arrays(array: [[T; 4]; 4]) -> Self
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::column_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));
sourcepub fn as_col_ptr(&self) -> *const T
pub fn as_col_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.
sourcepub fn as_mut_col_ptr(&mut self) -> *mut T
pub fn as_mut_col_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.
sourcepub fn as_col_slice(&self) -> &[T]ⓘNotable traits for &'_ mut [u8]impl<'_> Write for &'_ mut [u8]impl<'_> Read for &'_ [u8]
pub fn as_col_slice(&self) -> &[T]ⓘNotable traits for &'_ mut [u8]impl<'_> Write for &'_ mut [u8]impl<'_> Read for &'_ [u8]
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.
sourcepub fn as_mut_col_slice(&mut self) -> &mut [T]ⓘNotable traits for &'_ mut [u8]impl<'_> Write for &'_ mut [u8]impl<'_> Read for &'_ [u8]
pub fn as_mut_col_slice(&mut self) -> &mut [T]ⓘNotable traits for &'_ mut [u8]impl<'_> Write for &'_ mut [u8]impl<'_> Read for &'_ [u8]
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.
sourceimpl<T> Mat4<T>
impl<T> Mat4<T>
sourcepub fn gl_should_transpose(&self) -> bool
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.
sourcepub const GL_SHOULD_TRANSPOSE: bool = false
pub const GL_SHOULD_TRANSPOSE: bool = false
The transpose
parameter to pass to OpenGL glUniformMatrix*()
functions.
sourceimpl<T> Mat4<T>
impl<T> Mat4<T>
sourcepub 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
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.
sourceimpl<T> Mat4<T>
impl<T> Mat4<T>
sourcepub fn map<D, F>(self, f: F) -> Mat4<D> where
F: FnMut(T) -> D,
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
));
sourcepub fn as_<D>(self) -> Mat4<D> where
T: AsPrimitive<D>,
D: 'static + Copy,
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
sourcepub fn map2<D, F, S>(self, other: Mat4<S>, f: F) -> Mat4<D> where
F: FnMut(T, S) -> D,
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
));
sourcepub fn transposed(self) -> Self
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);
sourcepub fn transpose(&mut self)
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);
sourcepub fn determinant(self) -> T where
T: Copy + Mul<T, Output = T> + Sub<T, Output = T> + Add<T, Output = T>,
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.
sourcepub fn invert(&mut self) where
T: Real,
pub fn invert(&mut self) where
T: Real,
Inverts this matrix, blindly assuming that it is invertible.
See inverted()
for more info.
sourcepub fn inverted(self) -> Self where
T: Real,
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);
sourcepub fn invert_affine_transform_no_scale(&mut self) where
T: Real,
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.
sourcepub fn inverted_affine_transform_no_scale(self) -> Self where
T: Real,
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);
sourcepub fn invert_affine_transform(&mut self) where
T: Real,
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.
sourcepub fn inverted_affine_transform(self) -> Self where
T: Real,
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);
sourcepub fn mul_point<V: Into<Vec3<T>> + From<Vec4<T>>>(self, rhs: V) -> V where
T: Real + MulAdd<T, T, Output = T>,
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)
.
sourcepub fn mul_direction<V: Into<Vec3<T>> + From<Vec4<T>>>(self, rhs: V) -> V where
T: Real + MulAdd<T, T, Output = T>,
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)
.
sourcepub fn translate_2d<V: Into<Vec2<T>>>(&mut self, v: V) where
T: Real + MulAdd<T, T, Output = T>,
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.
sourcepub fn translated_2d<V: Into<Vec2<T>>>(self, v: V) -> Self where
T: Real + MulAdd<T, T, Output = T>,
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.
sourcepub fn translation_2d<V: Into<Vec2<T>>>(v: V) -> Self where
T: Zero + One,
pub fn translation_2d<V: Into<Vec2<T>>>(v: V) -> Self where
T: Zero + One,
Creates a 2D translation matrix.
sourcepub fn translate_3d<V: Into<Vec3<T>>>(&mut self, v: V) where
T: Real + MulAdd<T, T, Output = T>,
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.
sourcepub fn translated_3d<V: Into<Vec3<T>>>(self, v: V) -> Self where
T: Real + MulAdd<T, T, Output = T>,
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.
sourcepub fn translation_3d<V: Into<Vec3<T>>>(v: V) -> Self where
T: Zero + One,
pub fn translation_3d<V: Into<Vec3<T>>>(v: V) -> Self where
T: Zero + One,
Creates a 3D translation matrix.
sourcepub fn scale_3d<V: Into<Vec3<T>>>(&mut self, v: V) where
T: Real + MulAdd<T, T, Output = T>,
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.
sourcepub fn scaled_3d<V: Into<Vec3<T>>>(self, v: V) -> Self where
T: Real + MulAdd<T, T, Output = T>,
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.
sourcepub fn scaling_3d<V: Into<Vec3<T>>>(v: V) -> Self where
T: Zero + One,
pub fn scaling_3d<V: Into<Vec3<T>>>(v: V) -> Self where
T: Zero + One,
Creates a 3D scaling matrix.
sourcepub fn rotate_x(&mut self, angle_radians: T) where
T: Real + MulAdd<T, T, Output = T>,
pub fn rotate_x(&mut self, angle_radians: T) where
T: Real + MulAdd<T, T, Output = T>,
Rotates this matrix around the X axis.
sourcepub fn rotated_x(self, angle_radians: T) -> Self where
T: Real + MulAdd<T, T, Output = T>,
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.
sourcepub fn rotation_x(angle_radians: T) -> Self where
T: Real,
pub fn rotation_x(angle_radians: T) -> Self where
T: Real,
Creates a matrix that rotates around the X axis.
sourcepub fn rotate_y(&mut self, angle_radians: T) where
T: Real + MulAdd<T, T, Output = T>,
pub fn rotate_y(&mut self, angle_radians: T) where
T: Real + MulAdd<T, T, Output = T>,
Rotates this matrix around the Y axis.
sourcepub fn rotated_y(self, angle_radians: T) -> Self where
T: Real + MulAdd<T, T, Output = T>,
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.
sourcepub fn rotation_y(angle_radians: T) -> Self where
T: Real,
pub fn rotation_y(angle_radians: T) -> Self where
T: Real,
Creates a matrix that rotates around the Y axis.
sourcepub fn rotate_z(&mut self, angle_radians: T) where
T: Real + MulAdd<T, T, Output = T>,
pub fn rotate_z(&mut self, angle_radians: T) where
T: Real + MulAdd<T, T, Output = T>,
Rotates this matrix around the Z axis.
sourcepub fn rotated_z(self, angle_radians: T) -> Self where
T: Real + MulAdd<T, T, Output = T>,
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.
sourcepub fn rotation_z(angle_radians: T) -> Self where
T: Real,
pub fn rotation_z(angle_radians: T) -> Self where
T: Real,
Creates a matrix that rotates around the Z axis.
sourcepub 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>,
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.
sourcepub 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>,
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.
sourcepub fn rotation_3d<V: Into<Vec3<T>>>(angle_radians: T, axis: V) -> Self where
T: Real + Add<T, Output = T>,
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()));
}
sourcepub fn rotation_from_to_3d<V: Into<Vec3<T>>>(from: V, to: V) -> Self where
T: Real + Add<T, Output = T>,
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);
sourcepub 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>,
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);
sourcepub fn local_to_basis<V: Into<Vec3<T>>>(origin: V, i: V, j: V, k: V) -> Self where
T: Zero + One,
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()));
sourcepub 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
pub fn look_at<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self where
T: Real + Add<T, Output = T>,
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.
sourcepub fn look_at_lh<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self where
T: Real + Add<T, Output = T>,
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.));
sourcepub fn look_at_rh<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self where
T: Real + Add<T, Output = T>,
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.));
sourcepub 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
pub fn model_look_at<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self where
T: Real + Add<T, Output = T>,
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.
sourcepub fn model_look_at_lh<V: Into<Vec3<T>>>(eye: V, target: V, up: V) -> Self where
T: Real + Add<T, Output = T>,
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());
sourcepub 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>,
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());
sourcepub fn orthographic_without_depth_planes(o: FrustumPlanes<T>) -> Self where
T: Real,
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.
sourcepub fn orthographic_lh_zo(o: FrustumPlanes<T>) -> Self where
T: Real,
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"
sourcepub fn orthographic_lh_no(o: FrustumPlanes<T>) -> Self where
T: Real,
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"
sourcepub fn orthographic_rh_zo(o: FrustumPlanes<T>) -> Self where
T: Real,
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"
sourcepub fn orthographic_rh_no(o: FrustumPlanes<T>) -> Self where
T: Real,
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"
sourcepub fn frustum_lh_zo(o: FrustumPlanes<T>) -> Self where
T: Real,
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).
sourcepub fn frustum_lh_no(o: FrustumPlanes<T>) -> Self where
T: Real,
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).
sourcepub fn frustum_rh_zo(o: FrustumPlanes<T>) -> Self where
T: Real,
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).
sourcepub fn frustum_rh_no(o: FrustumPlanes<T>) -> Self where
T: Real,
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).
sourcepub fn perspective_rh_zo(
fov_y_radians: T,
aspect_ratio: T,
near: T,
far: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn perspective_lh_zo(
fov_y_radians: T,
aspect_ratio: T,
near: T,
far: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn perspective_rh_no(
fov_y_radians: T,
aspect_ratio: T,
near: T,
far: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn perspective_lh_no(
fov_y_radians: T,
aspect_ratio: T,
near: T,
far: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn perspective_fov_rh_zo(
fov_y_radians: T,
width: T,
height: T,
near: T,
far: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn perspective_fov_lh_zo(
fov_y_radians: T,
width: T,
height: T,
near: T,
far: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn perspective_fov_rh_no(
fov_y_radians: T,
width: T,
height: T,
near: T,
far: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn perspective_fov_lh_no(
fov_y_radians: T,
width: T,
height: T,
near: T,
far: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn tweaked_infinite_perspective_rh(
fov_y_radians: T,
aspect_ratio: T,
near: T,
epsilon: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn tweaked_infinite_perspective_lh(
fov_y_radians: T,
aspect_ratio: T,
near: T,
epsilon: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn infinite_perspective_rh(
fov_y_radians: T,
aspect_ratio: T,
near: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn infinite_perspective_lh(
fov_y_radians: T,
aspect_ratio: T,
near: T
) -> Self where
T: Real + FloatConst + Debug,
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.
sourcepub fn picking_region<V2: Into<Vec2<T>>>(
center: V2,
delta: V2,
viewport: Rect<T, T>
) -> Self where
T: Real + MulAdd<T, T, Output = T>,
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.
sourcepub 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>>,
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).
sourcepub 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>>,
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).
sourcepub 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>>,
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).
sourcepub 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>>,
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
sourceimpl<T: AbsDiffEq> AbsDiffEq<Mat4<T>> for Mat4<T> where
T::Epsilon: Copy,
impl<T: AbsDiffEq> AbsDiffEq<Mat4<T>> for Mat4<T> where
T::Epsilon: Copy,
sourcefn default_epsilon() -> T::Epsilon
fn default_epsilon() -> T::Epsilon
The default tolerance to use when testing values that are close together. Read more
sourcefn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool
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. Read more
sourcefn abs_diff_ne(&self, other: &Rhs, epsilon: Self::Epsilon) -> bool
fn abs_diff_ne(&self, other: &Rhs, epsilon: Self::Epsilon) -> bool
The inverse of AbsDiffEq::abs_diff_eq
.
sourceimpl<T: Add<Output = T> + Copy> AddAssign<Mat4<T>> for Mat4<T>
impl<T: Add<Output = T> + Copy> AddAssign<Mat4<T>> for Mat4<T>
sourcefn add_assign(&mut self, rhs: Self)
fn add_assign(&mut self, rhs: Self)
Performs the +=
operation. Read more
sourceimpl<T: Add<Output = T> + Copy> AddAssign<T> for Mat4<T>
impl<T: Add<Output = T> + Copy> AddAssign<T> for Mat4<T>
sourcefn add_assign(&mut self, rhs: T)
fn add_assign(&mut self, rhs: T)
Performs the +=
operation. Read more
sourceimpl<T: Zero + One> Default for Mat4<T>
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());
sourceimpl<'de, T> Deserialize<'de> for Mat4<T> where
T: Deserialize<'de>,
impl<'de, T> Deserialize<'de> for Mat4<T> where
T: Deserialize<'de>,
sourcefn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
sourceimpl<T: Display> Display for Mat4<T>
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.
sourceimpl<T: Div<Output = T> + Copy> DivAssign<Mat4<T>> for Mat4<T>
impl<T: Div<Output = T> + Copy> DivAssign<Mat4<T>> for Mat4<T>
sourcefn div_assign(&mut self, rhs: Self)
fn div_assign(&mut self, rhs: Self)
Performs the /=
operation. Read more
sourceimpl<T: Div<Output = T> + Copy> DivAssign<T> for Mat4<T>
impl<T: Div<Output = T> + Copy> DivAssign<T> for Mat4<T>
sourcefn div_assign(&mut self, rhs: T)
fn div_assign(&mut self, rhs: T)
Performs the /=
operation. Read more
sourceimpl<T> From<Quaternion<T>> for Mat4<T> where
T: Copy + Zero + One + Mul<Output = T> + Add<Output = T> + Sub<Output = T>,
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.));
}
sourcefn from(q: Quaternion<T>) -> Self
fn from(q: Quaternion<T>) -> Self
Converts to this type from the input type.
sourceimpl<T> From<Transform<T, T, T>> for Mat4<T> where
T: Real + MulAdd<T, T, Output = T>,
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.
sourceimpl<T> Index<(usize, usize)> for Mat4<T>
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 Vec2
s 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) ?
sourceimpl<T> Mul<CubicBezier3<T>> for Cols4<T> where
T: Real + MulAdd<T, T, Output = T>,
impl<T> Mul<CubicBezier3<T>> for Cols4<T> where
T: Real + MulAdd<T, T, Output = T>,
type Output = CubicBezier3<T>
type Output = CubicBezier3<T>
The resulting type after applying the *
operator.
sourcefn mul(self, rhs: CubicBezier3<T>) -> CubicBezier3<T>
fn mul(self, rhs: CubicBezier3<T>) -> CubicBezier3<T>
Performs the *
operation. Read more
sourceimpl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Mat4<T>> for Vec4<T>
impl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Mat4<T>> for Vec4<T>
Multiplies a row vector with a column-major matrix, giving a row vector.
use vek::mat::column_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);
sourceimpl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Mat4<T>> for Mat4<T>
impl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Mat4<T>> for Mat4<T>
Multiplies a column-major matrix with another.
use vek::mat::column_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);
sourceimpl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Mat4<T>> for Mat4<T>
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());
sourceimpl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Mat4<T>> for Mat4<T>
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());
sourceimpl<T> Mul<QuadraticBezier3<T>> for Cols4<T> where
T: Real + MulAdd<T, T, Output = T>,
impl<T> Mul<QuadraticBezier3<T>> for Cols4<T> where
T: Real + MulAdd<T, T, Output = T>,
type Output = QuadraticBezier3<T>
type Output = QuadraticBezier3<T>
The resulting type after applying the *
operator.
sourcefn mul(self, rhs: QuadraticBezier3<T>) -> QuadraticBezier3<T>
fn mul(self, rhs: QuadraticBezier3<T>) -> QuadraticBezier3<T>
Performs the *
operation. Read more
sourceimpl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Vec4<T>> for Mat4<T>
impl<T: MulAdd<T, T, Output = T> + Mul<Output = T> + Copy> Mul<Vec4<T>> for Mat4<T>
Multiplies a column-major matrix with a column vector, giving a column vector.
With SIMD vectors, this is the most efficient way.
use vek::mat::column_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);
sourceimpl<T> MulAssign<Mat4<T>> for Mat4<T> where
T: Copy + Zero + Add<Output = T> + Mul<Output = T> + MulAdd<T, T, Output = T>,
impl<T> MulAssign<Mat4<T>> for Mat4<T> where
T: Copy + Zero + Add<Output = T> + Mul<Output = T> + MulAdd<T, T, Output = T>,
sourcefn mul_assign(&mut self, rhs: Self)
fn mul_assign(&mut self, rhs: Self)
Performs the *=
operation. Read more
sourceimpl<T> MulAssign<T> for Mat4<T> where
T: Copy + Zero + Add<Output = T> + Mul<Output = T>,
impl<T> MulAssign<T> for Mat4<T> where
T: Copy + Zero + Add<Output = T> + Mul<Output = T>,
sourcefn mul_assign(&mut self, rhs: T)
fn mul_assign(&mut self, rhs: T)
Performs the *=
operation. Read more
sourceimpl<T: RelativeEq> RelativeEq<Mat4<T>> for Mat4<T> where
T::Epsilon: Copy,
impl<T: RelativeEq> RelativeEq<Mat4<T>> for Mat4<T> where
T::Epsilon: Copy,
sourcefn default_max_relative() -> T::Epsilon
fn default_max_relative() -> T::Epsilon
The default relative tolerance for testing values that are far-apart. Read more
sourcefn relative_eq(
&self,
other: &Self,
epsilon: T::Epsilon,
max_relative: T::Epsilon
) -> bool
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.
sourcefn relative_ne(
&self,
other: &Rhs,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon
) -> bool
fn relative_ne(
&self,
other: &Rhs,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon
) -> bool
The inverse of RelativeEq::relative_eq
.
sourceimpl<T: Rem<Output = T> + Copy> RemAssign<Mat4<T>> for Mat4<T>
impl<T: Rem<Output = T> + Copy> RemAssign<Mat4<T>> for Mat4<T>
sourcefn rem_assign(&mut self, rhs: Self)
fn rem_assign(&mut self, rhs: Self)
Performs the %=
operation. Read more
sourceimpl<T: Rem<Output = T> + Copy> RemAssign<T> for Mat4<T>
impl<T: Rem<Output = T> + Copy> RemAssign<T> for Mat4<T>
sourcefn rem_assign(&mut self, rhs: T)
fn rem_assign(&mut self, rhs: T)
Performs the %=
operation. Read more
sourceimpl<T: Sub<Output = T> + Copy> SubAssign<Mat4<T>> for Mat4<T>
impl<T: Sub<Output = T> + Copy> SubAssign<Mat4<T>> for Mat4<T>
sourcefn sub_assign(&mut self, rhs: Self)
fn sub_assign(&mut self, rhs: Self)
Performs the -=
operation. Read more
sourceimpl<T: Sub<Output = T> + Copy> SubAssign<T> for Mat4<T>
impl<T: Sub<Output = T> + Copy> SubAssign<T> for Mat4<T>
sourcefn sub_assign(&mut self, rhs: T)
fn sub_assign(&mut self, rhs: T)
Performs the -=
operation. Read more
sourceimpl<T: UlpsEq> UlpsEq<Mat4<T>> for Mat4<T> where
T::Epsilon: Copy,
impl<T: UlpsEq> UlpsEq<Mat4<T>> for Mat4<T> where
T::Epsilon: Copy,
impl<T: Copy> Copy for Mat4<T>
impl<T: Eq> Eq for Mat4<T>
impl<T> StructuralEq for Mat4<T>
impl<T> StructuralPartialEq for Mat4<T>
Auto Trait Implementations
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
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more