1 // Generated from affine.rs.tera template. Edit the template, not the generated file. 2 3 use crate::{Mat3, Mat3A, Mat4, Quat, Vec3, Vec3A}; 4 use core::ops::{Deref, DerefMut, Mul, MulAssign}; 5 6 /// A 3D affine transform, which can represent translation, rotation, scaling and shear. 7 /// 8 /// This type is 16 byte aligned. 9 #[derive(Copy, Clone)] 10 #[repr(C)] 11 pub struct Affine3A { 12 pub matrix3: Mat3A, 13 pub translation: Vec3A, 14 } 15 16 impl Affine3A { 17 /// The degenerate zero transform. 18 /// 19 /// This transforms any finite vector and point to zero. 20 /// The zero transform is non-invertible. 21 pub const ZERO: Self = Self { 22 matrix3: Mat3A::ZERO, 23 translation: Vec3A::ZERO, 24 }; 25 26 /// The identity transform. 27 /// 28 /// Multiplying a vector with this returns the same vector. 29 pub const IDENTITY: Self = Self { 30 matrix3: Mat3A::IDENTITY, 31 translation: Vec3A::ZERO, 32 }; 33 34 /// All NAN:s. 35 pub const NAN: Self = Self { 36 matrix3: Mat3A::NAN, 37 translation: Vec3A::NAN, 38 }; 39 40 /// Creates an affine transform from three column vectors. 41 #[inline(always)] 42 #[must_use] from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A, w_axis: Vec3A) -> Self43 pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A, w_axis: Vec3A) -> Self { 44 Self { 45 matrix3: Mat3A::from_cols(x_axis, y_axis, z_axis), 46 translation: w_axis, 47 } 48 } 49 50 /// Creates an affine transform from a `[f32; 12]` array stored in column major order. 51 #[inline] 52 #[must_use] from_cols_array(m: &[f32; 12]) -> Self53 pub fn from_cols_array(m: &[f32; 12]) -> Self { 54 Self { 55 matrix3: Mat3A::from_cols_array(&[ 56 m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], 57 ]), 58 translation: Vec3A::from_array([m[9], m[10], m[11]]), 59 } 60 } 61 62 /// Creates a `[f32; 12]` array storing data in column major order. 63 #[inline] 64 #[must_use] to_cols_array(&self) -> [f32; 12]65 pub fn to_cols_array(&self) -> [f32; 12] { 66 let x = &self.matrix3.x_axis; 67 let y = &self.matrix3.y_axis; 68 let z = &self.matrix3.z_axis; 69 let w = &self.translation; 70 [x.x, x.y, x.z, y.x, y.y, y.z, z.x, z.y, z.z, w.x, w.y, w.z] 71 } 72 73 /// Creates an affine transform from a `[[f32; 3]; 4]` 74 /// 3D array stored in column major order. 75 /// If your data is in row major order you will need to `transpose` the returned 76 /// matrix. 77 #[inline] 78 #[must_use] from_cols_array_2d(m: &[[f32; 3]; 4]) -> Self79 pub fn from_cols_array_2d(m: &[[f32; 3]; 4]) -> Self { 80 Self { 81 matrix3: Mat3A::from_cols(m[0].into(), m[1].into(), m[2].into()), 82 translation: m[3].into(), 83 } 84 } 85 86 /// Creates a `[[f32; 3]; 4]` 3D array storing data in 87 /// column major order. 88 /// If you require data in row major order `transpose` the matrix first. 89 #[inline] 90 #[must_use] to_cols_array_2d(&self) -> [[f32; 3]; 4]91 pub fn to_cols_array_2d(&self) -> [[f32; 3]; 4] { 92 [ 93 self.matrix3.x_axis.into(), 94 self.matrix3.y_axis.into(), 95 self.matrix3.z_axis.into(), 96 self.translation.into(), 97 ] 98 } 99 100 /// Creates an affine transform from the first 12 values in `slice`. 101 /// 102 /// # Panics 103 /// 104 /// Panics if `slice` is less than 12 elements long. 105 #[inline] 106 #[must_use] from_cols_slice(slice: &[f32]) -> Self107 pub fn from_cols_slice(slice: &[f32]) -> Self { 108 Self { 109 matrix3: Mat3A::from_cols_slice(&slice[0..9]), 110 translation: Vec3A::from_slice(&slice[9..12]), 111 } 112 } 113 114 /// Writes the columns of `self` to the first 12 elements in `slice`. 115 /// 116 /// # Panics 117 /// 118 /// Panics if `slice` is less than 12 elements long. 119 #[inline] write_cols_to_slice(self, slice: &mut [f32])120 pub fn write_cols_to_slice(self, slice: &mut [f32]) { 121 self.matrix3.write_cols_to_slice(&mut slice[0..9]); 122 self.translation.write_to_slice(&mut slice[9..12]); 123 } 124 125 /// Creates an affine transform that changes scale. 126 /// Note that if any scale is zero the transform will be non-invertible. 127 #[inline] 128 #[must_use] from_scale(scale: Vec3) -> Self129 pub fn from_scale(scale: Vec3) -> Self { 130 Self { 131 matrix3: Mat3A::from_diagonal(scale), 132 translation: Vec3A::ZERO, 133 } 134 } 135 /// Creates an affine transform from the given `rotation` quaternion. 136 #[inline] 137 #[must_use] from_quat(rotation: Quat) -> Self138 pub fn from_quat(rotation: Quat) -> Self { 139 Self { 140 matrix3: Mat3A::from_quat(rotation), 141 translation: Vec3A::ZERO, 142 } 143 } 144 145 /// Creates an affine transform containing a 3D rotation around a normalized 146 /// rotation `axis` of `angle` (in radians). 147 #[inline] 148 #[must_use] from_axis_angle(axis: Vec3, angle: f32) -> Self149 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self { 150 Self { 151 matrix3: Mat3A::from_axis_angle(axis, angle), 152 translation: Vec3A::ZERO, 153 } 154 } 155 156 /// Creates an affine transform containing a 3D rotation around the x axis of 157 /// `angle` (in radians). 158 #[inline] 159 #[must_use] from_rotation_x(angle: f32) -> Self160 pub fn from_rotation_x(angle: f32) -> Self { 161 Self { 162 matrix3: Mat3A::from_rotation_x(angle), 163 translation: Vec3A::ZERO, 164 } 165 } 166 167 /// Creates an affine transform containing a 3D rotation around the y axis of 168 /// `angle` (in radians). 169 #[inline] 170 #[must_use] from_rotation_y(angle: f32) -> Self171 pub fn from_rotation_y(angle: f32) -> Self { 172 Self { 173 matrix3: Mat3A::from_rotation_y(angle), 174 translation: Vec3A::ZERO, 175 } 176 } 177 178 /// Creates an affine transform containing a 3D rotation around the z axis of 179 /// `angle` (in radians). 180 #[inline] 181 #[must_use] from_rotation_z(angle: f32) -> Self182 pub fn from_rotation_z(angle: f32) -> Self { 183 Self { 184 matrix3: Mat3A::from_rotation_z(angle), 185 translation: Vec3A::ZERO, 186 } 187 } 188 189 /// Creates an affine transformation from the given 3D `translation`. 190 #[inline] 191 #[must_use] from_translation(translation: Vec3) -> Self192 pub fn from_translation(translation: Vec3) -> Self { 193 #[allow(clippy::useless_conversion)] 194 Self { 195 matrix3: Mat3A::IDENTITY, 196 translation: translation.into(), 197 } 198 } 199 200 /// Creates an affine transform from a 3x3 matrix (expressing scale, shear and 201 /// rotation) 202 #[inline] 203 #[must_use] from_mat3(mat3: Mat3) -> Self204 pub fn from_mat3(mat3: Mat3) -> Self { 205 #[allow(clippy::useless_conversion)] 206 Self { 207 matrix3: mat3.into(), 208 translation: Vec3A::ZERO, 209 } 210 } 211 212 /// Creates an affine transform from a 3x3 matrix (expressing scale, shear and rotation) 213 /// and a translation vector. 214 /// 215 /// Equivalent to `Affine3A::from_translation(translation) * Affine3A::from_mat3(mat3)` 216 #[inline] 217 #[must_use] from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self218 pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self { 219 #[allow(clippy::useless_conversion)] 220 Self { 221 matrix3: mat3.into(), 222 translation: translation.into(), 223 } 224 } 225 226 /// Creates an affine transform from the given 3D `scale`, `rotation` and 227 /// `translation`. 228 /// 229 /// Equivalent to `Affine3A::from_translation(translation) * 230 /// Affine3A::from_quat(rotation) * Affine3A::from_scale(scale)` 231 #[inline] 232 #[must_use] from_scale_rotation_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self233 pub fn from_scale_rotation_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self { 234 let rotation = Mat3A::from_quat(rotation); 235 #[allow(clippy::useless_conversion)] 236 Self { 237 matrix3: Mat3A::from_cols( 238 rotation.x_axis * scale.x, 239 rotation.y_axis * scale.y, 240 rotation.z_axis * scale.z, 241 ), 242 translation: translation.into(), 243 } 244 } 245 246 /// Creates an affine transform from the given 3D `rotation` and `translation`. 247 /// 248 /// Equivalent to `Affine3A::from_translation(translation) * Affine3A::from_quat(rotation)` 249 #[inline] 250 #[must_use] from_rotation_translation(rotation: Quat, translation: Vec3) -> Self251 pub fn from_rotation_translation(rotation: Quat, translation: Vec3) -> Self { 252 #[allow(clippy::useless_conversion)] 253 Self { 254 matrix3: Mat3A::from_quat(rotation), 255 translation: translation.into(), 256 } 257 } 258 259 /// The given `Mat4` must be an affine transform, 260 /// i.e. contain no perspective transform. 261 #[inline] 262 #[must_use] from_mat4(m: Mat4) -> Self263 pub fn from_mat4(m: Mat4) -> Self { 264 Self { 265 matrix3: Mat3A::from_cols( 266 Vec3A::from_vec4(m.x_axis), 267 Vec3A::from_vec4(m.y_axis), 268 Vec3A::from_vec4(m.z_axis), 269 ), 270 translation: Vec3A::from_vec4(m.w_axis), 271 } 272 } 273 274 /// Extracts `scale`, `rotation` and `translation` from `self`. 275 /// 276 /// The transform is expected to be non-degenerate and without shearing, or the output 277 /// will be invalid. 278 /// 279 /// # Panics 280 /// 281 /// Will panic if the determinant `self.matrix3` is zero or if the resulting scale 282 /// vector contains any zero elements when `glam_assert` is enabled. 283 #[inline] 284 #[must_use] to_scale_rotation_translation(&self) -> (Vec3, Quat, Vec3)285 pub fn to_scale_rotation_translation(&self) -> (Vec3, Quat, Vec3) { 286 use crate::f32::math; 287 let det = self.matrix3.determinant(); 288 glam_assert!(det != 0.0); 289 290 let scale = Vec3::new( 291 self.matrix3.x_axis.length() * math::signum(det), 292 self.matrix3.y_axis.length(), 293 self.matrix3.z_axis.length(), 294 ); 295 296 glam_assert!(scale.cmpne(Vec3::ZERO).all()); 297 298 let inv_scale = scale.recip(); 299 300 #[allow(clippy::useless_conversion)] 301 let rotation = Quat::from_mat3(&Mat3::from_cols( 302 (self.matrix3.x_axis * inv_scale.x).into(), 303 (self.matrix3.y_axis * inv_scale.y).into(), 304 (self.matrix3.z_axis * inv_scale.z).into(), 305 )); 306 307 #[allow(clippy::useless_conversion)] 308 (scale, rotation, self.translation.into()) 309 } 310 311 /// Creates a left-handed view transform using a camera position, an up direction, and a facing 312 /// direction. 313 /// 314 /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`. 315 #[inline] 316 #[must_use] look_to_lh(eye: Vec3, dir: Vec3, up: Vec3) -> Self317 pub fn look_to_lh(eye: Vec3, dir: Vec3, up: Vec3) -> Self { 318 Self::look_to_rh(eye, -dir, up) 319 } 320 321 /// Creates a right-handed view transform using a camera position, an up direction, and a facing 322 /// direction. 323 /// 324 /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`. 325 #[inline] 326 #[must_use] look_to_rh(eye: Vec3, dir: Vec3, up: Vec3) -> Self327 pub fn look_to_rh(eye: Vec3, dir: Vec3, up: Vec3) -> Self { 328 let f = dir.normalize(); 329 let s = f.cross(up).normalize(); 330 let u = s.cross(f); 331 332 Self { 333 matrix3: Mat3A::from_cols( 334 Vec3A::new(s.x, u.x, -f.x), 335 Vec3A::new(s.y, u.y, -f.y), 336 Vec3A::new(s.z, u.z, -f.z), 337 ), 338 translation: Vec3A::new(-eye.dot(s), -eye.dot(u), eye.dot(f)), 339 } 340 } 341 342 /// Creates a left-handed view transform using a camera position, an up direction, and a focal 343 /// point. 344 /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`. 345 /// 346 /// # Panics 347 /// 348 /// Will panic if `up` is not normalized when `glam_assert` is enabled. 349 #[inline] 350 #[must_use] look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self351 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self { 352 glam_assert!(up.is_normalized()); 353 Self::look_to_lh(eye, center - eye, up) 354 } 355 356 /// Creates a right-handed view transform using a camera position, an up direction, and a focal 357 /// point. 358 /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`. 359 /// 360 /// # Panics 361 /// 362 /// Will panic if `up` is not normalized when `glam_assert` is enabled. 363 #[inline] 364 #[must_use] look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self365 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self { 366 glam_assert!(up.is_normalized()); 367 Self::look_to_rh(eye, center - eye, up) 368 } 369 370 /// Transforms the given 3D points, applying shear, scale, rotation and translation. 371 #[inline] transform_point3(&self, rhs: Vec3) -> Vec3372 pub fn transform_point3(&self, rhs: Vec3) -> Vec3 { 373 #[allow(clippy::useless_conversion)] 374 ((self.matrix3.x_axis * rhs.x) 375 + (self.matrix3.y_axis * rhs.y) 376 + (self.matrix3.z_axis * rhs.z) 377 + self.translation) 378 .into() 379 } 380 381 /// Transforms the given 3D vector, applying shear, scale and rotation (but NOT 382 /// translation). 383 /// 384 /// To also apply translation, use [`Self::transform_point3()`] instead. 385 #[inline] 386 #[must_use] transform_vector3(&self, rhs: Vec3) -> Vec3387 pub fn transform_vector3(&self, rhs: Vec3) -> Vec3 { 388 #[allow(clippy::useless_conversion)] 389 ((self.matrix3.x_axis * rhs.x) 390 + (self.matrix3.y_axis * rhs.y) 391 + (self.matrix3.z_axis * rhs.z)) 392 .into() 393 } 394 395 /// Transforms the given [`Vec3A`], applying shear, scale, rotation and translation. 396 #[inline] 397 #[must_use] transform_point3a(&self, rhs: Vec3A) -> Vec3A398 pub fn transform_point3a(&self, rhs: Vec3A) -> Vec3A { 399 self.matrix3 * rhs + self.translation 400 } 401 402 /// Transforms the given [`Vec3A`], applying shear, scale and rotation (but NOT 403 /// translation). 404 /// 405 /// To also apply translation, use [`Self::transform_point3a()`] instead. 406 #[inline] 407 #[must_use] transform_vector3a(&self, rhs: Vec3A) -> Vec3A408 pub fn transform_vector3a(&self, rhs: Vec3A) -> Vec3A { 409 self.matrix3 * rhs 410 } 411 412 /// Returns `true` if, and only if, all elements are finite. 413 /// 414 /// If any element is either `NaN`, positive or negative infinity, this will return 415 /// `false`. 416 #[inline] 417 #[must_use] is_finite(&self) -> bool418 pub fn is_finite(&self) -> bool { 419 self.matrix3.is_finite() && self.translation.is_finite() 420 } 421 422 /// Returns `true` if any elements are `NaN`. 423 #[inline] 424 #[must_use] is_nan(&self) -> bool425 pub fn is_nan(&self) -> bool { 426 self.matrix3.is_nan() || self.translation.is_nan() 427 } 428 429 /// Returns true if the absolute difference of all elements between `self` and `rhs` 430 /// is less than or equal to `max_abs_diff`. 431 /// 432 /// This can be used to compare if two 3x4 matrices contain similar elements. It works 433 /// best when comparing with a known value. The `max_abs_diff` that should be used used 434 /// depends on the values being compared against. 435 /// 436 /// For more see 437 /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). 438 #[inline] 439 #[must_use] abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool440 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool { 441 self.matrix3.abs_diff_eq(rhs.matrix3, max_abs_diff) 442 && self.translation.abs_diff_eq(rhs.translation, max_abs_diff) 443 } 444 445 /// Return the inverse of this transform. 446 /// 447 /// Note that if the transform is not invertible the result will be invalid. 448 #[inline] 449 #[must_use] inverse(&self) -> Self450 pub fn inverse(&self) -> Self { 451 let matrix3 = self.matrix3.inverse(); 452 // transform negative translation by the matrix inverse: 453 let translation = -(matrix3 * self.translation); 454 455 Self { 456 matrix3, 457 translation, 458 } 459 } 460 } 461 462 impl Default for Affine3A { 463 #[inline(always)] default() -> Self464 fn default() -> Self { 465 Self::IDENTITY 466 } 467 } 468 469 impl Deref for Affine3A { 470 type Target = crate::deref::Cols4<Vec3A>; 471 #[inline(always)] deref(&self) -> &Self::Target472 fn deref(&self) -> &Self::Target { 473 unsafe { &*(self as *const Self as *const Self::Target) } 474 } 475 } 476 477 impl DerefMut for Affine3A { 478 #[inline(always)] deref_mut(&mut self) -> &mut Self::Target479 fn deref_mut(&mut self) -> &mut Self::Target { 480 unsafe { &mut *(self as *mut Self as *mut Self::Target) } 481 } 482 } 483 484 impl PartialEq for Affine3A { 485 #[inline] eq(&self, rhs: &Self) -> bool486 fn eq(&self, rhs: &Self) -> bool { 487 self.matrix3.eq(&rhs.matrix3) && self.translation.eq(&rhs.translation) 488 } 489 } 490 491 impl core::fmt::Debug for Affine3A { fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result492 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 493 fmt.debug_struct(stringify!(Affine3A)) 494 .field("matrix3", &self.matrix3) 495 .field("translation", &self.translation) 496 .finish() 497 } 498 } 499 500 impl core::fmt::Display for Affine3A { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result501 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 502 if let Some(p) = f.precision() { 503 write!( 504 f, 505 "[{:.*}, {:.*}, {:.*}, {:.*}]", 506 p, 507 self.matrix3.x_axis, 508 p, 509 self.matrix3.y_axis, 510 p, 511 self.matrix3.z_axis, 512 p, 513 self.translation 514 ) 515 } else { 516 write!( 517 f, 518 "[{}, {}, {}, {}]", 519 self.matrix3.x_axis, self.matrix3.y_axis, self.matrix3.z_axis, self.translation 520 ) 521 } 522 } 523 } 524 525 impl<'a> core::iter::Product<&'a Self> for Affine3A { product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,526 fn product<I>(iter: I) -> Self 527 where 528 I: Iterator<Item = &'a Self>, 529 { 530 iter.fold(Self::IDENTITY, |a, &b| a * b) 531 } 532 } 533 534 impl Mul for Affine3A { 535 type Output = Affine3A; 536 537 #[inline] mul(self, rhs: Affine3A) -> Self::Output538 fn mul(self, rhs: Affine3A) -> Self::Output { 539 Self { 540 matrix3: self.matrix3 * rhs.matrix3, 541 translation: self.matrix3 * rhs.translation + self.translation, 542 } 543 } 544 } 545 546 impl MulAssign for Affine3A { 547 #[inline] mul_assign(&mut self, rhs: Affine3A)548 fn mul_assign(&mut self, rhs: Affine3A) { 549 *self = self.mul(rhs); 550 } 551 } 552 553 impl From<Affine3A> for Mat4 { 554 #[inline] from(m: Affine3A) -> Mat4555 fn from(m: Affine3A) -> Mat4 { 556 Mat4::from_cols( 557 m.matrix3.x_axis.extend(0.0), 558 m.matrix3.y_axis.extend(0.0), 559 m.matrix3.z_axis.extend(0.0), 560 m.translation.extend(1.0), 561 ) 562 } 563 } 564 565 impl Mul<Mat4> for Affine3A { 566 type Output = Mat4; 567 568 #[inline] mul(self, rhs: Mat4) -> Self::Output569 fn mul(self, rhs: Mat4) -> Self::Output { 570 Mat4::from(self) * rhs 571 } 572 } 573 574 impl Mul<Affine3A> for Mat4 { 575 type Output = Mat4; 576 577 #[inline] mul(self, rhs: Affine3A) -> Self::Output578 fn mul(self, rhs: Affine3A) -> Self::Output { 579 self * Mat4::from(rhs) 580 } 581 } 582