aboutsummaryrefslogtreecommitdiff
path: root/src/f32/sse2/mat4.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/f32/sse2/mat4.rs')
-rw-r--r--src/f32/sse2/mat4.rs102
1 files changed, 76 insertions, 26 deletions
diff --git a/src/f32/sse2/mat4.rs b/src/f32/sse2/mat4.rs
index aa69493..490b981 100644
--- a/src/f32/sse2/mat4.rs
+++ b/src/f32/sse2/mat4.rs
@@ -1,6 +1,8 @@
// Generated from mat.rs.tera template. Edit the template, not the generated file.
-use crate::{sse2::*, swizzles::*, DMat4, EulerRot, Mat3, Mat3A, Quat, Vec3, Vec3A, Vec4};
+use crate::{
+ f32::math, sse2::*, swizzles::*, DMat4, EulerRot, Mat3, Mat3A, Quat, Vec3, Vec3A, Vec4,
+};
#[cfg(not(target_arch = "spirv"))]
use core::fmt;
use core::iter::{Product, Sum};
@@ -11,12 +13,9 @@ use core::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;
-#[cfg(feature = "libm")]
-#[allow(unused_imports)]
-use num_traits::Float;
-
-/// Creates a 4x4 matrix from column vectors.
+/// Creates a 4x4 matrix from four column vectors.
#[inline(always)]
+#[must_use]
pub const fn mat4(x_axis: Vec4, y_axis: Vec4, z_axis: Vec4, w_axis: Vec4) -> Mat4 {
Mat4::from_cols(x_axis, y_axis, z_axis, w_axis)
}
@@ -32,7 +31,7 @@ pub const fn mat4(x_axis: Vec4, y_axis: Vec4, z_axis: Vec4, w_axis: Vec4) -> Mat
/// using methods such as [`Self::from_translation()`], [`Self::from_quat()`],
/// [`Self::from_scale()`] and [`Self::from_scale_rotation_translation()`].
///
-/// Othographic projections can be created using the methods [`Self::orthographic_lh()`] for
+/// Orthographic projections can be created using the methods [`Self::orthographic_lh()`] for
/// left-handed coordinate systems and [`Self::orthographic_rh()`] for right-handed
/// systems. The resulting matrix is also an affine transformation.
///
@@ -71,6 +70,7 @@ impl Mat4 {
#[allow(clippy::too_many_arguments)]
#[inline(always)]
+ #[must_use]
const fn new(
m00: f32,
m01: f32,
@@ -97,8 +97,9 @@ impl Mat4 {
}
}
- /// Creates a 4x4 matrix from two column vectors.
+ /// Creates a 4x4 matrix from four column vectors.
#[inline(always)]
+ #[must_use]
pub const fn from_cols(x_axis: Vec4, y_axis: Vec4, z_axis: Vec4, w_axis: Vec4) -> Self {
Self {
x_axis,
@@ -112,6 +113,7 @@ impl Mat4 {
/// If your data is stored in row major you will need to `transpose` the returned
/// matrix.
#[inline]
+ #[must_use]
pub const fn from_cols_array(m: &[f32; 16]) -> Self {
Self::new(
m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13],
@@ -122,6 +124,7 @@ impl Mat4 {
/// Creates a `[f32; 16]` array storing data in column major order.
/// If you require data in row major order `transpose` the matrix first.
#[inline]
+ #[must_use]
pub const fn to_cols_array(&self) -> [f32; 16] {
let [x_axis_x, x_axis_y, x_axis_z, x_axis_w] = self.x_axis.to_array();
let [y_axis_x, y_axis_y, y_axis_z, y_axis_w] = self.y_axis.to_array();
@@ -138,6 +141,7 @@ impl Mat4 {
/// If your data is in row major order you will need to `transpose` the returned
/// matrix.
#[inline]
+ #[must_use]
pub const fn from_cols_array_2d(m: &[[f32; 4]; 4]) -> Self {
Self::from_cols(
Vec4::from_array(m[0]),
@@ -150,6 +154,7 @@ impl Mat4 {
/// Creates a `[[f32; 4]; 4]` 4D array storing data in column major order.
/// If you require data in row major order `transpose` the matrix first.
#[inline]
+ #[must_use]
pub const fn to_cols_array_2d(&self) -> [[f32; 4]; 4] {
[
self.x_axis.to_array(),
@@ -162,6 +167,7 @@ impl Mat4 {
/// Creates a 4x4 matrix with its diagonal set to `diagonal` and all other entries set to 0.
#[doc(alias = "scale")]
#[inline]
+ #[must_use]
pub const fn from_diagonal(diagonal: Vec4) -> Self {
// diagonal.x, diagonal.y etc can't be done in a const-context
let [x, y, z, w] = diagonal.to_array();
@@ -171,6 +177,7 @@ impl Mat4 {
}
#[inline]
+ #[must_use]
fn quat_to_axes(rotation: Quat) -> (Vec4, Vec4, Vec4) {
glam_assert!(rotation.is_normalized());
@@ -204,6 +211,7 @@ impl Mat4 {
///
/// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn from_scale_rotation_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self {
let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
Self::from_cols(
@@ -223,6 +231,7 @@ impl Mat4 {
///
/// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn from_rotation_translation(rotation: Quat, translation: Vec3) -> Self {
let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
Self::from_cols(x_axis, y_axis, z_axis, Vec4::from((translation, 1.0)))
@@ -236,12 +245,13 @@ impl Mat4 {
/// Will panic if the determinant of `self` is zero or if the resulting scale vector
/// contains any zero elements when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn to_scale_rotation_translation(&self) -> (Vec3, Quat, Vec3) {
let det = self.determinant();
glam_assert!(det != 0.0);
let scale = Vec3::new(
- self.x_axis.length() * det.signum(),
+ self.x_axis.length() * math::signum(det),
self.y_axis.length(),
self.z_axis.length(),
);
@@ -270,6 +280,7 @@ impl Mat4 {
///
/// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn from_quat(rotation: Quat) -> Self {
let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
Self::from_cols(x_axis, y_axis, z_axis, Vec4::W)
@@ -281,6 +292,7 @@ impl Mat4 {
/// The resulting matrix can be used to transform 3D points and vectors. See
/// [`Self::transform_point3()`] and [`Self::transform_vector3()`].
#[inline]
+ #[must_use]
pub fn from_mat3(m: Mat3) -> Self {
Self::from_cols(
Vec4::from((m.x_axis, 0.0)),
@@ -296,6 +308,7 @@ impl Mat4 {
/// The resulting matrix can be used to transform 3D points and vectors. See
/// [`Self::transform_point3()`] and [`Self::transform_vector3()`].
#[inline]
+ #[must_use]
pub fn from_mat3a(m: Mat3A) -> Self {
Self::from_cols(
Vec4::from((m.x_axis, 0.0)),
@@ -310,6 +323,7 @@ impl Mat4 {
/// The resulting matrix can be used to transform 3D points and vectors. See
/// [`Self::transform_point3()`] and [`Self::transform_vector3()`].
#[inline]
+ #[must_use]
pub fn from_translation(translation: Vec3) -> Self {
Self::from_cols(
Vec4::X,
@@ -329,10 +343,11 @@ impl Mat4 {
///
/// Will panic if `axis` is not normalized when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
glam_assert!(axis.is_normalized());
- let (sin, cos) = angle.sin_cos();
+ let (sin, cos) = math::sin_cos(angle);
let axis_sin = axis.mul(sin);
let axis_sq = axis.mul(axis);
let omc = 1.0 - cos;
@@ -362,12 +377,13 @@ impl Mat4 {
)
}
- #[inline]
/// Creates a affine transformation matrix containing a rotation from the given euler
/// rotation sequence and angles (in radians).
///
/// The resulting matrix can be used to transform 3D points and vectors. See
/// [`Self::transform_point3()`] and [`Self::transform_vector3()`].
+ #[inline]
+ #[must_use]
pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
let quat = Quat::from_euler(order, a, b, c);
Self::from_quat(quat)
@@ -379,8 +395,9 @@ impl Mat4 {
/// The resulting matrix can be used to transform 3D points and vectors. See
/// [`Self::transform_point3()`] and [`Self::transform_vector3()`].
#[inline]
+ #[must_use]
pub fn from_rotation_x(angle: f32) -> Self {
- let (sina, cosa) = angle.sin_cos();
+ let (sina, cosa) = math::sin_cos(angle);
Self::from_cols(
Vec4::X,
Vec4::new(0.0, cosa, sina, 0.0),
@@ -395,8 +412,9 @@ impl Mat4 {
/// The resulting matrix can be used to transform 3D points and vectors. See
/// [`Self::transform_point3()`] and [`Self::transform_vector3()`].
#[inline]
+ #[must_use]
pub fn from_rotation_y(angle: f32) -> Self {
- let (sina, cosa) = angle.sin_cos();
+ let (sina, cosa) = math::sin_cos(angle);
Self::from_cols(
Vec4::new(cosa, 0.0, -sina, 0.0),
Vec4::Y,
@@ -411,8 +429,9 @@ impl Mat4 {
/// The resulting matrix can be used to transform 3D points and vectors. See
/// [`Self::transform_point3()`] and [`Self::transform_vector3()`].
#[inline]
+ #[must_use]
pub fn from_rotation_z(angle: f32) -> Self {
- let (sina, cosa) = angle.sin_cos();
+ let (sina, cosa) = math::sin_cos(angle);
Self::from_cols(
Vec4::new(cosa, sina, 0.0, 0.0),
Vec4::new(-sina, cosa, 0.0, 0.0),
@@ -430,6 +449,7 @@ impl Mat4 {
///
/// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn from_scale(scale: Vec3) -> Self {
// Do not panic as long as any component is non-zero
glam_assert!(scale.cmpne(Vec3::ZERO).any());
@@ -448,6 +468,7 @@ impl Mat4 {
///
/// Panics if `slice` is less than 16 elements long.
#[inline]
+ #[must_use]
pub const fn from_cols_slice(slice: &[f32]) -> Self {
Self::new(
slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
@@ -486,6 +507,7 @@ impl Mat4 {
///
/// Panics if `index` is greater than 3.
#[inline]
+ #[must_use]
pub fn col(&self, index: usize) -> Vec4 {
match index {
0 => self.x_axis,
@@ -518,6 +540,7 @@ impl Mat4 {
///
/// Panics if `index` is greater than 3.
#[inline]
+ #[must_use]
pub fn row(&self, index: usize) -> Vec4 {
match index {
0 => Vec4::new(self.x_axis.x, self.y_axis.x, self.z_axis.x, self.w_axis.x),
@@ -531,6 +554,7 @@ impl Mat4 {
/// Returns `true` if, and only if, all elements are finite.
/// If any element is either `NaN`, positive or negative infinity, this will return `false`.
#[inline]
+ #[must_use]
pub fn is_finite(&self) -> bool {
self.x_axis.is_finite()
&& self.y_axis.is_finite()
@@ -540,13 +564,14 @@ impl Mat4 {
/// Returns `true` if any elements are `NaN`.
#[inline]
+ #[must_use]
pub fn is_nan(&self) -> bool {
self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan() || self.w_axis.is_nan()
}
/// Returns the transpose of `self`.
- #[must_use]
#[inline]
+ #[must_use]
pub fn transpose(&self) -> Self {
unsafe {
// Based on https://github.com/microsoft/DirectXMath `XMMatrixTranspose`
@@ -565,6 +590,7 @@ impl Mat4 {
}
/// Returns the determinant of `self`.
+ #[must_use]
pub fn determinant(&self) -> f32 {
unsafe {
// Based on https://github.com/g-truc/glm `glm_mat4_determinant_lowp`
@@ -758,6 +784,7 @@ impl Mat4 {
///
/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
#[inline]
+ #[must_use]
pub fn look_to_lh(eye: Vec3, dir: Vec3, up: Vec3) -> Self {
Self::look_to_rh(eye, -dir, up)
}
@@ -767,6 +794,7 @@ impl Mat4 {
///
/// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
#[inline]
+ #[must_use]
pub fn look_to_rh(eye: Vec3, dir: Vec3, up: Vec3) -> Self {
let f = dir.normalize();
let s = f.cross(up).normalize();
@@ -788,6 +816,7 @@ impl Mat4 {
///
/// Will panic if `up` is not normalized when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
glam_assert!(up.is_normalized());
Self::look_to_lh(eye, center.sub(eye), up)
@@ -810,6 +839,7 @@ impl Mat4 {
/// This is the same as the OpenGL `gluPerspective` function.
/// See <https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml>
#[inline]
+ #[must_use]
pub fn perspective_rh_gl(
fov_y_radians: f32,
aspect_ratio: f32,
@@ -817,7 +847,7 @@ impl Mat4 {
z_far: f32,
) -> Self {
let inv_length = 1.0 / (z_near - z_far);
- let f = 1.0 / (0.5 * fov_y_radians).tan();
+ let f = 1.0 / math::tan(0.5 * fov_y_radians);
let a = f / aspect_ratio;
let b = (z_near + z_far) * inv_length;
let c = (2.0 * z_near * z_far) * inv_length;
@@ -836,9 +866,10 @@ impl Mat4 {
/// Will panic if `z_near` or `z_far` are less than or equal to zero when `glam_assert` is
/// enabled.
#[inline]
+ #[must_use]
pub fn perspective_lh(fov_y_radians: f32, aspect_ratio: f32, z_near: f32, z_far: f32) -> Self {
glam_assert!(z_near > 0.0 && z_far > 0.0);
- let (sin_fov, cos_fov) = (0.5 * fov_y_radians).sin_cos();
+ let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
let h = cos_fov / sin_fov;
let w = h / aspect_ratio;
let r = z_far / (z_far - z_near);
@@ -857,9 +888,10 @@ impl Mat4 {
/// Will panic if `z_near` or `z_far` are less than or equal to zero when `glam_assert` is
/// enabled.
#[inline]
+ #[must_use]
pub fn perspective_rh(fov_y_radians: f32, aspect_ratio: f32, z_near: f32, z_far: f32) -> Self {
glam_assert!(z_near > 0.0 && z_far > 0.0);
- let (sin_fov, cos_fov) = (0.5 * fov_y_radians).sin_cos();
+ let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
let h = cos_fov / sin_fov;
let w = h / aspect_ratio;
let r = z_far / (z_near - z_far);
@@ -877,9 +909,10 @@ impl Mat4 {
///
/// Will panic if `z_near` is less than or equal to zero when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn perspective_infinite_lh(fov_y_radians: f32, aspect_ratio: f32, z_near: f32) -> Self {
glam_assert!(z_near > 0.0);
- let (sin_fov, cos_fov) = (0.5 * fov_y_radians).sin_cos();
+ let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
let h = cos_fov / sin_fov;
let w = h / aspect_ratio;
Self::from_cols(
@@ -896,13 +929,14 @@ impl Mat4 {
///
/// Will panic if `z_near` is less than or equal to zero when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn perspective_infinite_reverse_lh(
fov_y_radians: f32,
aspect_ratio: f32,
z_near: f32,
) -> Self {
glam_assert!(z_near > 0.0);
- let (sin_fov, cos_fov) = (0.5 * fov_y_radians).sin_cos();
+ let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
let h = cos_fov / sin_fov;
let w = h / aspect_ratio;
Self::from_cols(
@@ -916,9 +950,10 @@ impl Mat4 {
/// Creates an infinite right-handed perspective projection matrix with
/// `[0,1]` depth range.
#[inline]
+ #[must_use]
pub fn perspective_infinite_rh(fov_y_radians: f32, aspect_ratio: f32, z_near: f32) -> Self {
glam_assert!(z_near > 0.0);
- let f = 1.0 / (0.5 * fov_y_radians).tan();
+ let f = 1.0 / math::tan(0.5 * fov_y_radians);
Self::from_cols(
Vec4::new(f / aspect_ratio, 0.0, 0.0, 0.0),
Vec4::new(0.0, f, 0.0, 0.0),
@@ -930,13 +965,14 @@ impl Mat4 {
/// Creates an infinite reverse right-handed perspective projection matrix
/// with `[0,1]` depth range.
#[inline]
+ #[must_use]
pub fn perspective_infinite_reverse_rh(
fov_y_radians: f32,
aspect_ratio: f32,
z_near: f32,
) -> Self {
glam_assert!(z_near > 0.0);
- let f = 1.0 / (0.5 * fov_y_radians).tan();
+ let f = 1.0 / math::tan(0.5 * fov_y_radians);
Self::from_cols(
Vec4::new(f / aspect_ratio, 0.0, 0.0, 0.0),
Vec4::new(0.0, f, 0.0, 0.0),
@@ -950,6 +986,7 @@ impl Mat4 {
/// See
/// <https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml>
#[inline]
+ #[must_use]
pub fn orthographic_rh_gl(
left: f32,
right: f32,
@@ -975,6 +1012,7 @@ impl Mat4 {
/// Creates a left-handed orthographic projection matrix with `[0,1]` depth range.
#[inline]
+ #[must_use]
pub fn orthographic_lh(
left: f32,
right: f32,
@@ -1001,6 +1039,7 @@ impl Mat4 {
/// Creates a right-handed orthographic projection matrix with `[0,1]` depth range.
#[inline]
+ #[must_use]
pub fn orthographic_rh(
left: f32,
right: f32,
@@ -1032,6 +1071,7 @@ impl Mat4 {
///
/// This method assumes that `self` contains a projective transform.
#[inline]
+ #[must_use]
pub fn project_point3(&self, rhs: Vec3) -> Vec3 {
let mut res = self.x_axis.mul(rhs.x);
res = self.y_axis.mul(rhs.y).add(res);
@@ -1054,6 +1094,7 @@ impl Mat4 {
///
/// Will panic if the 3rd row of `self` is not `(0, 0, 0, 1)` when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn transform_point3(&self, rhs: Vec3) -> Vec3 {
glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
let mut res = self.x_axis.mul(rhs.x);
@@ -1074,6 +1115,7 @@ impl Mat4 {
///
/// Will panic if the 3rd row of `self` is not `(0, 0, 0, 1)` when `glam_assert` is enabled.
#[inline]
+ #[must_use]
pub fn transform_vector3(&self, rhs: Vec3) -> Vec3 {
glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
let mut res = self.x_axis.mul(rhs.x);
@@ -1082,10 +1124,11 @@ impl Mat4 {
res.xyz()
}
- /// Transforms the given `Vec3A` as 3D point.
+ /// Transforms the given [`Vec3A`] as 3D point.
///
- /// This is the equivalent of multiplying the `Vec3A` as a 4D vector where `w` is `1.0`.
+ /// This is the equivalent of multiplying the [`Vec3A`] as a 4D vector where `w` is `1.0`.
#[inline]
+ #[must_use]
pub fn transform_point3a(&self, rhs: Vec3A) -> Vec3A {
glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
let mut res = self.x_axis.mul(rhs.xxxx());
@@ -1095,10 +1138,11 @@ impl Mat4 {
res.into()
}
- /// Transforms the give `Vec3A` as 3D vector.
+ /// Transforms the give [`Vec3A`] as 3D vector.
///
- /// This is the equivalent of multiplying the `Vec3A` as a 4D vector where `w` is `0.0`.
+ /// This is the equivalent of multiplying the [`Vec3A`] as a 4D vector where `w` is `0.0`.
#[inline]
+ #[must_use]
pub fn transform_vector3a(&self, rhs: Vec3A) -> Vec3A {
glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
let mut res = self.x_axis.mul(rhs.xxxx());
@@ -1109,6 +1153,7 @@ impl Mat4 {
/// Transforms a 4D vector.
#[inline]
+ #[must_use]
pub fn mul_vec4(&self, rhs: Vec4) -> Vec4 {
let mut res = self.x_axis.mul(rhs.xxxx());
res = res.add(self.y_axis.mul(rhs.yyyy()));
@@ -1119,6 +1164,7 @@ impl Mat4 {
/// Multiplies two 4x4 matrices.
#[inline]
+ #[must_use]
pub fn mul_mat4(&self, rhs: &Self) -> Self {
Self::from_cols(
self.mul(rhs.x_axis),
@@ -1130,6 +1176,7 @@ impl Mat4 {
/// Adds two 4x4 matrices.
#[inline]
+ #[must_use]
pub fn add_mat4(&self, rhs: &Self) -> Self {
Self::from_cols(
self.x_axis.add(rhs.x_axis),
@@ -1141,6 +1188,7 @@ impl Mat4 {
/// Subtracts two 4x4 matrices.
#[inline]
+ #[must_use]
pub fn sub_mat4(&self, rhs: &Self) -> Self {
Self::from_cols(
self.x_axis.sub(rhs.x_axis),
@@ -1152,6 +1200,7 @@ impl Mat4 {
/// Multiplies a 4x4 matrix by a scalar.
#[inline]
+ #[must_use]
pub fn mul_scalar(&self, rhs: f32) -> Self {
Self::from_cols(
self.x_axis.mul(rhs),
@@ -1171,6 +1220,7 @@ impl Mat4 {
/// For more see
/// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
#[inline]
+ #[must_use]
pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
&& self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)