Struct vek::mat::repr_simd::row_major::mat4::Mat4 [−][src]
Expand description
4x4 matrix.
Fields
rows: CVec4<Vec4<T>>
Implementations
The identity matrix, which is also the default value for square matrices.
assert_eq!(Mat4::<f32>::default(), Mat4::<f32>::identity());
Applies the function f to each element of this matrix, in-place.
For an example, see the map()
method.
Applies the function f to each element of this matrix, in-place.
For an example, see the map2()
method.
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());
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,
));
Initializes a matrix by its diagonal, setting other elements to zero.
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);
The sum of the diagonal’s elements.
assert_eq!(Mat4::<u32>::zero().trace(), 0);
assert_eq!(Mat4::<u32>::identity().trace(), 4);
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);
Convenience constant representing the number of rows for matrices of this type.
Convenience constant representing the number of columns for matrices of this type.
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
));
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);
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);
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));
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));
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);
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);
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));
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));
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.
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.
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.
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.
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.
The transpose
parameter to pass to OpenGL glUniformMatrix*()
functions.
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.
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
));
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
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
));
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);
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);
Get this matrix’s determinant.
A matrix is invertible if its determinant is non-zero.
Inverts this matrix, blindly assuming that it is invertible.
See inverted()
for more info.
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);
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.
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);
Inverts this matrix, blindly assuming that it is an invertible transform matrix.
See inverted_affine_transform()
for more info.
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);
Shortcut for self * Vec4::from_point(rhs)
.
Shortcut for self * Vec4::from_direction(rhs)
.
Translates this matrix in 2D.
Returns this matrix translated in 2D.
Creates a 2D translation matrix.
Translates this matrix in 3D.
Returns this matrix translated in 3D.
Creates a 3D translation matrix.
Scales this matrix in 3D.
Returns this matrix scaled in 3D.
Creates a 3D scaling matrix.
Rotates this matrix around the X axis.
Returns this matrix rotated around the X axis.
Creates a matrix that rotates around the X axis.
Rotates this matrix around the Y axis.
Returns this matrix rotated around the Y axis.
Creates a matrix that rotates around the Y axis.
Rotates this matrix around the Z axis.
Returns this matrix rotated around the Z axis.
Creates a matrix that rotates around the Z axis.
Rotates this matrix around a 3D axis. The axis is not required to be normalized.
Returns this matrix rotated around a 3D axis. The axis is not required to be normalized.
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()));
}
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);
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);
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()));
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
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.
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.));
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.));
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
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.
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());
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());
Returns an orthographic projection matrix that doesn’t use near and far planes.
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"
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"
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"
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"
Creates a perspective projection matrix from a frustum (left-handed, zero-to-one depth clip planes).
Creates a perspective projection matrix from a frustum (left-handed, negative-one-to-one depth clip planes).
Creates a perspective projection matrix from a frustum (right-handed, zero-to-one depth clip planes).
Creates a perspective projection matrix from a frustum (right-handed, negative-one-to-one depth clip planes).
pub 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.
pub 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.
pub 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.
pub 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.
pub 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.
pub 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.
pub 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.
pub 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.
pub 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.
pub 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.
pub 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.
pub 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.
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.
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).
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).
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).
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
The default tolerance to use when testing values that are close together. Read more
A test for equality that uses the absolute difference to compute the approximate equality of two numbers. Read more
The inverse of AbsDiffEq::abs_diff_eq
.
Performs the +=
operation. Read more
Performs the +=
operation. Read more
The default value for a square matrix is the identity.
assert_eq!(Mat4::<f32>::default(), Mat4::<f32>::identity());
fn 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
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.
Performs the /=
operation. Read more
Performs the /=
operation. Read more
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.));
}
Performs the conversion.
A Mat4
can be obtained from a Transform
, by rotating, then scaling, then
translating.
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) ?
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());
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);
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);
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());
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);
Performs the *=
operation. Read more
Performs the *=
operation. Read more
The default relative tolerance for testing values that are far-apart. Read more
A test for equality that uses a relative comparison if the values are far apart.
The inverse of RelativeEq::relative_eq
.
Performs the %=
operation. Read more
Performs the %=
operation. Read more
Performs the -=
operation. Read more
Performs the -=
operation. Read more
The default ULPs to tolerate when testing values that are far-apart. Read more
A test for equality that uses units in the last place (ULP) if the values are far apart.
Auto Trait Implementations
impl<T> RefUnwindSafe for Mat4<T> where
T: RefUnwindSafe,
impl<T> UnwindSafe for Mat4<T> where
T: UnwindSafe,
Blanket Implementations
Mutably borrows from an owned value. Read more