| 1 | use std::{ |
| 2 | f32, |
| 3 | ops::{Add, AddAssign, Div, DivAssign, Index, Mul, MulAssign, Neg, Sub, SubAssign}, |
| 4 | slice, |
| 5 | }; |
| 6 | |
| 7 | use skia_bindings::{self as sb, SkM44, SkV2, SkV3, SkV4}; |
| 8 | |
| 9 | use crate::{prelude::*, private::is_finite, scalar, Matrix, Rect}; |
| 10 | |
| 11 | #[repr (C)] |
| 12 | #[derive (Copy, Clone, PartialEq, Default, Debug)] |
| 13 | pub struct V2 { |
| 14 | pub x: f32, |
| 15 | pub y: f32, |
| 16 | } |
| 17 | |
| 18 | native_transmutable!(SkV2, V2, v2_layout); |
| 19 | |
| 20 | impl V2 { |
| 21 | pub const fn new(x: f32, y: f32) -> Self { |
| 22 | Self { x, y } |
| 23 | } |
| 24 | |
| 25 | pub fn dot(self, b: Self) -> scalar { |
| 26 | self.x * b.x + self.y * b.y |
| 27 | } |
| 28 | |
| 29 | pub fn cross(self, b: Self) -> scalar { |
| 30 | self.x * b.y - self.y * b.x |
| 31 | } |
| 32 | |
| 33 | #[must_use ] |
| 34 | pub fn normalize(self) -> Self { |
| 35 | self * (1.0 / self.length()) |
| 36 | } |
| 37 | |
| 38 | pub fn length_squared(self) -> scalar { |
| 39 | Self::dot(self, self) |
| 40 | } |
| 41 | |
| 42 | pub fn length(self) -> scalar { |
| 43 | self.length_squared().sqrt() |
| 44 | } |
| 45 | |
| 46 | const COMPONENTS: usize = 2; |
| 47 | |
| 48 | pub fn as_array(&self) -> &[f32; Self::COMPONENTS] { |
| 49 | unsafe { slice::from_raw_parts(&self.x, Self::COMPONENTS) } |
| 50 | .try_into() |
| 51 | .unwrap() |
| 52 | } |
| 53 | |
| 54 | pub fn as_mut_array(&mut self) -> &mut [f32; Self::COMPONENTS] { |
| 55 | unsafe { slice::from_raw_parts_mut(&mut self.x, Self::COMPONENTS) } |
| 56 | .try_into() |
| 57 | .unwrap() |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | impl Neg for V2 { |
| 62 | type Output = Self; |
| 63 | |
| 64 | fn neg(self) -> Self::Output { |
| 65 | Self::new(-self.x, -self.y) |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | impl Add for V2 { |
| 70 | type Output = Self; |
| 71 | |
| 72 | fn add(self, v: Self) -> Self::Output { |
| 73 | Self::new(self.x + v.x, self.y + v.y) |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | impl Sub for V2 { |
| 78 | type Output = Self; |
| 79 | |
| 80 | fn sub(self, v: Self) -> Self::Output { |
| 81 | Self::new(self.x - v.x, self.y - v.y) |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | impl Mul for V2 { |
| 86 | type Output = Self; |
| 87 | |
| 88 | fn mul(self, v: Self) -> Self::Output { |
| 89 | Self::new(self.x * v.x, self.y * v.y) |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | impl Mul<scalar> for V2 { |
| 94 | type Output = Self; |
| 95 | |
| 96 | fn mul(self, s: scalar) -> Self::Output { |
| 97 | Self::new(self.x * s, self.y * s) |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | impl Mul<V2> for scalar { |
| 102 | type Output = V2; |
| 103 | |
| 104 | fn mul(self, v: V2) -> Self::Output { |
| 105 | V2::new(x:v.x * self, y:v.y * self) |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | impl Div<V2> for scalar { |
| 110 | type Output = V2; |
| 111 | |
| 112 | fn div(self, v: V2) -> Self::Output { |
| 113 | V2::new(self / v.x, self / v.y) |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | impl Div<scalar> for V2 { |
| 118 | type Output = V2; |
| 119 | fn div(self, s: scalar) -> Self::Output { |
| 120 | V2::new(self.x / s, self.y / s) |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | impl AddAssign for V2 { |
| 125 | fn add_assign(&mut self, v: Self) { |
| 126 | *self = *self + v |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | impl SubAssign for V2 { |
| 131 | fn sub_assign(&mut self, v: Self) { |
| 132 | *self = *self - v |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | impl MulAssign for V2 { |
| 137 | fn mul_assign(&mut self, v: Self) { |
| 138 | *self = *self * v |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | impl MulAssign<scalar> for V2 { |
| 143 | fn mul_assign(&mut self, s: scalar) { |
| 144 | *self = *self * s |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | impl DivAssign<scalar> for V2 { |
| 149 | fn div_assign(&mut self, s: scalar) { |
| 150 | *self = *self / s |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | #[repr (C)] |
| 155 | #[derive (Copy, Clone, PartialEq, Default, Debug)] |
| 156 | pub struct V3 { |
| 157 | pub x: f32, |
| 158 | pub y: f32, |
| 159 | pub z: f32, |
| 160 | } |
| 161 | |
| 162 | native_transmutable!(SkV3, V3, v3_layout); |
| 163 | |
| 164 | impl V3 { |
| 165 | pub const fn new(x: f32, y: f32, z: f32) -> Self { |
| 166 | Self { x, y, z } |
| 167 | } |
| 168 | |
| 169 | pub fn dot(&self, b: &Self) -> scalar { |
| 170 | self.x * b.x + self.y * b.y + self.z * b.z |
| 171 | } |
| 172 | |
| 173 | #[must_use ] |
| 174 | pub fn cross(&self, b: &Self) -> Self { |
| 175 | Self::new( |
| 176 | self.y * b.z - self.z * b.y, |
| 177 | self.z * b.x - self.x * b.z, |
| 178 | self.x * b.y - self.y * b.x, |
| 179 | ) |
| 180 | } |
| 181 | |
| 182 | #[must_use ] |
| 183 | pub fn normalize(&self) -> Self { |
| 184 | *self * (1.0 / self.length()) |
| 185 | } |
| 186 | |
| 187 | pub fn length_squared(&self) -> scalar { |
| 188 | Self::dot(self, self) |
| 189 | } |
| 190 | |
| 191 | pub fn length(&self) -> scalar { |
| 192 | Self::dot(self, self).sqrt() |
| 193 | } |
| 194 | |
| 195 | const COMPONENTS: usize = 3; |
| 196 | |
| 197 | pub fn as_array(&self) -> &[f32; Self::COMPONENTS] { |
| 198 | unsafe { slice::from_raw_parts(&self.x, Self::COMPONENTS) } |
| 199 | .try_into() |
| 200 | .unwrap() |
| 201 | } |
| 202 | |
| 203 | pub fn as_mut_array(&mut self) -> &mut [f32; Self::COMPONENTS] { |
| 204 | unsafe { slice::from_raw_parts_mut(&mut self.x, Self::COMPONENTS) } |
| 205 | .try_into() |
| 206 | .unwrap() |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | impl Neg for V3 { |
| 211 | type Output = Self; |
| 212 | |
| 213 | fn neg(self) -> Self::Output { |
| 214 | Self::new(-self.x, -self.y, -self.z) |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | impl Add for V3 { |
| 219 | type Output = Self; |
| 220 | |
| 221 | fn add(self, v: Self) -> Self::Output { |
| 222 | Self::new(self.x + v.x, self.y + v.y, self.z + v.z) |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | impl Sub for V3 { |
| 227 | type Output = Self; |
| 228 | |
| 229 | fn sub(self, v: Self) -> Self::Output { |
| 230 | Self::new(self.x - v.x, self.y - v.y, self.z - v.z) |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | impl Mul for V3 { |
| 235 | type Output = Self; |
| 236 | |
| 237 | fn mul(self, v: Self) -> Self::Output { |
| 238 | Self::new(self.x * v.x, self.y * v.y, self.z * v.z) |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | impl Mul<scalar> for V3 { |
| 243 | type Output = Self; |
| 244 | |
| 245 | fn mul(self, s: scalar) -> Self::Output { |
| 246 | Self::new(self.x * s, self.y * s, self.z * s) |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | impl Mul<V3> for scalar { |
| 251 | type Output = V3; |
| 252 | |
| 253 | fn mul(self, v: V3) -> Self::Output { |
| 254 | V3::new(x:v.x * self, y:v.y * self, z:v.z * self) |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | impl AddAssign for V3 { |
| 259 | fn add_assign(&mut self, v: Self) { |
| 260 | *self = *self + v |
| 261 | } |
| 262 | } |
| 263 | |
| 264 | impl SubAssign for V3 { |
| 265 | fn sub_assign(&mut self, v: Self) { |
| 266 | *self = *self - v |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | impl MulAssign for V3 { |
| 271 | fn mul_assign(&mut self, v: Self) { |
| 272 | *self = *self * v |
| 273 | } |
| 274 | } |
| 275 | |
| 276 | impl MulAssign<scalar> for V3 { |
| 277 | fn mul_assign(&mut self, s: scalar) { |
| 278 | *self = *self * s |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | #[repr (C)] |
| 283 | #[derive (Copy, Clone, PartialEq, Default, Debug)] |
| 284 | pub struct V4 { |
| 285 | pub x: f32, |
| 286 | pub y: f32, |
| 287 | pub z: f32, |
| 288 | pub w: f32, |
| 289 | } |
| 290 | |
| 291 | native_transmutable!(SkV4, V4, v4_layout); |
| 292 | |
| 293 | impl V4 { |
| 294 | pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self { |
| 295 | Self { x, y, z, w } |
| 296 | } |
| 297 | |
| 298 | pub fn length_squared(&self) -> scalar { |
| 299 | Self::dot(self, self) |
| 300 | } |
| 301 | |
| 302 | pub fn length(&self) -> scalar { |
| 303 | scalar::sqrt(Self::dot(self, self)) |
| 304 | } |
| 305 | |
| 306 | pub fn dot(&self, b: &Self) -> scalar { |
| 307 | self.x * b.x + self.y * b.y + self.z * b.z + self.w * b.w |
| 308 | } |
| 309 | |
| 310 | pub fn normalize(&self) -> Self { |
| 311 | (*self) * (1.0 / self.length()) |
| 312 | } |
| 313 | |
| 314 | const COMPONENTS: usize = 4; |
| 315 | |
| 316 | pub fn as_array(&self) -> &[f32; Self::COMPONENTS] { |
| 317 | unsafe { slice::from_raw_parts(&self.x, Self::COMPONENTS) } |
| 318 | .try_into() |
| 319 | .unwrap() |
| 320 | } |
| 321 | |
| 322 | pub fn as_mut_array(&mut self) -> &mut [f32; Self::COMPONENTS] { |
| 323 | unsafe { slice::from_raw_parts_mut(&mut self.x, Self::COMPONENTS) } |
| 324 | .try_into() |
| 325 | .unwrap() |
| 326 | } |
| 327 | } |
| 328 | |
| 329 | impl Neg for V4 { |
| 330 | type Output = Self; |
| 331 | |
| 332 | fn neg(self) -> Self::Output { |
| 333 | Self::new(-self.x, -self.y, -self.z, -self.w) |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | impl Add for V4 { |
| 338 | type Output = Self; |
| 339 | |
| 340 | fn add(self, v: Self) -> Self::Output { |
| 341 | Self::new(self.x + v.x, self.y + v.y, self.z + v.z, self.w + v.w) |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | impl Sub for V4 { |
| 346 | type Output = Self; |
| 347 | |
| 348 | fn sub(self, v: Self) -> Self::Output { |
| 349 | Self::new(self.x - v.x, self.y - v.y, self.z - v.z, self.w - v.w) |
| 350 | } |
| 351 | } |
| 352 | |
| 353 | impl Mul for V4 { |
| 354 | type Output = Self; |
| 355 | |
| 356 | fn mul(self, v: Self) -> Self::Output { |
| 357 | Self::new(self.x * v.x, self.y * v.y, self.z * v.z, self.w * v.w) |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | impl Mul<scalar> for V4 { |
| 362 | type Output = Self; |
| 363 | |
| 364 | fn mul(self, s: scalar) -> Self::Output { |
| 365 | Self::new(self.x * s, self.y * s, self.z * s, self.w * s) |
| 366 | } |
| 367 | } |
| 368 | |
| 369 | impl Mul<V4> for scalar { |
| 370 | type Output = V4; |
| 371 | |
| 372 | fn mul(self, v: V4) -> Self::Output { |
| 373 | V4::new(x:v.x * self, y:v.y * self, z:v.z * self, w:v.w * self) |
| 374 | } |
| 375 | } |
| 376 | |
| 377 | impl AddAssign for V4 { |
| 378 | fn add_assign(&mut self, v: Self) { |
| 379 | *self = *self + v |
| 380 | } |
| 381 | } |
| 382 | |
| 383 | impl SubAssign for V4 { |
| 384 | fn sub_assign(&mut self, v: Self) { |
| 385 | *self = *self - v |
| 386 | } |
| 387 | } |
| 388 | |
| 389 | impl MulAssign for V4 { |
| 390 | fn mul_assign(&mut self, v: Self) { |
| 391 | *self = *self * v |
| 392 | } |
| 393 | } |
| 394 | |
| 395 | impl MulAssign<scalar> for V4 { |
| 396 | fn mul_assign(&mut self, s: scalar) { |
| 397 | *self = *self * s |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | impl Index<usize> for V4 { |
| 402 | type Output = f32; |
| 403 | |
| 404 | fn index(&self, index: usize) -> &Self::Output { |
| 405 | &self.as_array()[index] |
| 406 | } |
| 407 | } |
| 408 | |
| 409 | #[repr (C)] |
| 410 | #[derive (Clone, Debug)] |
| 411 | pub struct M44 { |
| 412 | mat: [f32; Self::COMPONENTS], |
| 413 | } |
| 414 | |
| 415 | native_transmutable!(SkM44, M44, m44_layout); |
| 416 | |
| 417 | impl Default for M44 { |
| 418 | fn default() -> Self { |
| 419 | Self::new_identity() |
| 420 | } |
| 421 | } |
| 422 | |
| 423 | impl PartialEq for M44 { |
| 424 | fn eq(&self, other: &Self) -> bool { |
| 425 | unsafe { sb::C_SkM44_equals(self.native(), other.native()) } |
| 426 | } |
| 427 | } |
| 428 | |
| 429 | impl M44 { |
| 430 | const COMPONENTS: usize = 16; |
| 431 | |
| 432 | pub const fn new_identity() -> Self { |
| 433 | Self { |
| 434 | mat: [ |
| 435 | 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, |
| 436 | ], |
| 437 | } |
| 438 | } |
| 439 | |
| 440 | pub fn concat(a: &Self, b: &Self) -> Self { |
| 441 | let mut m = Self::default(); |
| 442 | m.set_concat(a, b); |
| 443 | m |
| 444 | } |
| 445 | |
| 446 | pub const fn nan() -> Self { |
| 447 | Self { |
| 448 | mat: [f32::NAN; Self::COMPONENTS], |
| 449 | } |
| 450 | } |
| 451 | |
| 452 | #[allow (clippy::too_many_arguments)] |
| 453 | pub const fn new( |
| 454 | m0: scalar, |
| 455 | m4: scalar, |
| 456 | m8: scalar, |
| 457 | m12: scalar, |
| 458 | m1: scalar, |
| 459 | m5: scalar, |
| 460 | m9: scalar, |
| 461 | m13: scalar, |
| 462 | m2: scalar, |
| 463 | m6: scalar, |
| 464 | m10: scalar, |
| 465 | m14: scalar, |
| 466 | m3: scalar, |
| 467 | m7: scalar, |
| 468 | m11: scalar, |
| 469 | m15: scalar, |
| 470 | ) -> Self { |
| 471 | Self { |
| 472 | mat: [ |
| 473 | m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, |
| 474 | ], |
| 475 | } |
| 476 | } |
| 477 | |
| 478 | pub fn rows(r0: &V4, r1: &V4, r2: &V4, r3: &V4) -> Self { |
| 479 | let mut m = Self::default(); |
| 480 | m.set_row(0, r0); |
| 481 | m.set_row(1, r1); |
| 482 | m.set_row(2, r2); |
| 483 | m.set_row(3, r3); |
| 484 | m |
| 485 | } |
| 486 | |
| 487 | pub fn cols(c0: &V4, c1: &V4, c2: &V4, c3: &V4) -> Self { |
| 488 | let mut m = Self::default(); |
| 489 | m.set_col(0, c0); |
| 490 | m.set_col(1, c1); |
| 491 | m.set_col(2, c2); |
| 492 | m.set_col(3, c3); |
| 493 | m |
| 494 | } |
| 495 | |
| 496 | pub fn row_major(r: &[scalar; Self::COMPONENTS]) -> Self { |
| 497 | Self::new( |
| 498 | r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], |
| 499 | r[14], r[15], |
| 500 | ) |
| 501 | } |
| 502 | |
| 503 | pub fn col_major(c: &[scalar; Self::COMPONENTS]) -> Self { |
| 504 | Self::new( |
| 505 | c[0], c[4], c[8], c[12], c[1], c[5], c[9], c[13], c[2], c[6], c[10], c[14], c[3], c[7], |
| 506 | c[11], c[15], |
| 507 | ) |
| 508 | } |
| 509 | |
| 510 | pub fn translate(x: scalar, y: scalar, z: scalar) -> Self { |
| 511 | Self::new( |
| 512 | 1.0, 0.0, 0.0, x, 0.0, 1.0, 0.0, y, 0.0, 0.0, 1.0, z, 0.0, 0.0, 0.0, 1.0, |
| 513 | ) |
| 514 | } |
| 515 | |
| 516 | pub fn scale(x: scalar, y: scalar, z: scalar) -> Self { |
| 517 | Self::new( |
| 518 | x, 0.0, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, 0.0, z, 0.0, 0.0, 0.0, 0.0, 1.0, |
| 519 | ) |
| 520 | } |
| 521 | |
| 522 | pub fn rotate(axis: V3, radians: scalar) -> Self { |
| 523 | let mut m = Self::default(); |
| 524 | m.set_rotate(axis, radians); |
| 525 | m |
| 526 | } |
| 527 | |
| 528 | pub fn rect_to_rect(src: impl AsRef<Rect>, dst: impl AsRef<Rect>) -> Self { |
| 529 | let (src, dst) = (src.as_ref(), dst.as_ref()); |
| 530 | Self::construct(|m| unsafe { sb::C_SkM44_RectToRect(src.native(), dst.native(), m) }) |
| 531 | } |
| 532 | |
| 533 | pub fn look_at(eye: &V3, center: &V3, up: &V3) -> Self { |
| 534 | Self::construct(|m| unsafe { |
| 535 | sb::C_SkM44_LookAt(eye.native(), center.native(), up.native(), m) |
| 536 | }) |
| 537 | } |
| 538 | |
| 539 | pub fn perspective(near: f32, far: f32, angle: f32) -> Self { |
| 540 | Self::construct(|m| unsafe { sb::C_SkM44_Perspective(near, far, angle, m) }) |
| 541 | } |
| 542 | |
| 543 | pub fn get_col_major(&self, v: &mut [scalar; Self::COMPONENTS]) { |
| 544 | v.copy_from_slice(&self.mat) |
| 545 | } |
| 546 | |
| 547 | pub fn get_row_major(&self, v: &mut [scalar; Self::COMPONENTS]) { |
| 548 | unsafe { self.native().getRowMajor(v.as_mut_ptr()) } |
| 549 | } |
| 550 | |
| 551 | #[deprecated (since = "0.30.0" , note = "use M44::col_major() instead" )] |
| 552 | pub fn set_col_major(&mut self, v: &[scalar; Self::COMPONENTS]) -> &mut Self { |
| 553 | *self = Self::col_major(v); |
| 554 | self |
| 555 | } |
| 556 | |
| 557 | #[deprecated (since = "0.30.0" , note = "use M44::row_major() instead" )] |
| 558 | pub fn set_row_major(&mut self, v: &[scalar; Self::COMPONENTS]) -> &mut Self { |
| 559 | *self = Self::row_major(v); |
| 560 | self |
| 561 | } |
| 562 | |
| 563 | #[allow (clippy::too_many_arguments)] |
| 564 | #[deprecated (since = "0.30.0" , note = "use Self::new() instead" )] |
| 565 | pub fn set_44( |
| 566 | &mut self, |
| 567 | m0: scalar, |
| 568 | m1: scalar, |
| 569 | m2: scalar, |
| 570 | m3: scalar, |
| 571 | m4: scalar, |
| 572 | m5: scalar, |
| 573 | m6: scalar, |
| 574 | m7: scalar, |
| 575 | m8: scalar, |
| 576 | m9: scalar, |
| 577 | m10: scalar, |
| 578 | m11: scalar, |
| 579 | m12: scalar, |
| 580 | m13: scalar, |
| 581 | m14: scalar, |
| 582 | m15: scalar, |
| 583 | ) -> &mut Self { |
| 584 | *self = Self::new( |
| 585 | m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, |
| 586 | ); |
| 587 | self |
| 588 | } |
| 589 | |
| 590 | pub fn rc(&self, r: usize, c: usize) -> scalar { |
| 591 | assert!(r <= 3); |
| 592 | assert!(c <= 3); |
| 593 | self.mat[c * 4 + r] |
| 594 | } |
| 595 | |
| 596 | pub fn set_rc(&mut self, r: usize, c: usize, value: scalar) { |
| 597 | assert!(r <= 3); |
| 598 | assert!(c <= 3); |
| 599 | self.mat[c * 4 + r] = value; |
| 600 | } |
| 601 | |
| 602 | pub fn row(&self, i: usize) -> V4 { |
| 603 | assert!(i <= 3); |
| 604 | V4::new( |
| 605 | self.mat[i], |
| 606 | self.mat[i + 4], |
| 607 | self.mat[i + 8], |
| 608 | self.mat[i + 12], |
| 609 | ) |
| 610 | } |
| 611 | |
| 612 | pub fn col(&self, i: usize) -> V4 { |
| 613 | assert!(i <= 3); |
| 614 | V4::new( |
| 615 | self.mat[i * 4], |
| 616 | self.mat[i * 4 + 1], |
| 617 | self.mat[i * 4 + 2], |
| 618 | self.mat[i * 4 + 3], |
| 619 | ) |
| 620 | } |
| 621 | |
| 622 | pub fn set_row(&mut self, i: usize, v: &V4) { |
| 623 | assert!(i <= 3); |
| 624 | self.mat[i] = v.x; |
| 625 | self.mat[i + 4] = v.y; |
| 626 | self.mat[i + 8] = v.z; |
| 627 | self.mat[i + 12] = v.w; |
| 628 | } |
| 629 | |
| 630 | pub fn set_col(&mut self, i: usize, v: &V4) { |
| 631 | assert!(i <= 3); |
| 632 | self.mat[(i * 4)..(i * 4 + V4::COMPONENTS)].copy_from_slice(v.as_array()); |
| 633 | } |
| 634 | |
| 635 | pub fn set_identity(&mut self) -> &mut Self { |
| 636 | *self = Self { |
| 637 | mat: [ |
| 638 | 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, |
| 639 | ], |
| 640 | }; |
| 641 | self |
| 642 | } |
| 643 | |
| 644 | pub fn set_translate(&mut self, x: scalar, y: scalar, z: scalar) -> &mut Self { |
| 645 | *self = Self { |
| 646 | mat: [ |
| 647 | 1.0, 0.0, 0.0, x, 0.0, 1.0, 0.0, y, 0.0, 0.0, 1.0, z, 0.0, 0.0, 0.0, 1.0, |
| 648 | ], |
| 649 | }; |
| 650 | self |
| 651 | } |
| 652 | |
| 653 | pub fn set_scale(&mut self, x: scalar, y: scalar, z: scalar) -> &mut Self { |
| 654 | *self = Self { |
| 655 | mat: [ |
| 656 | x, 0.0, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, 0.0, z, 0.0, 0.0, 0.0, 0.0, 1.0, |
| 657 | ], |
| 658 | }; |
| 659 | self |
| 660 | } |
| 661 | |
| 662 | pub fn set_rotate_unit_sin_cos( |
| 663 | &mut self, |
| 664 | axis: V3, |
| 665 | sin_angle: scalar, |
| 666 | cos_angle: scalar, |
| 667 | ) -> &mut Self { |
| 668 | unsafe { |
| 669 | self.native_mut() |
| 670 | .setRotateUnitSinCos(axis.into_native(), sin_angle, cos_angle) |
| 671 | }; |
| 672 | self |
| 673 | } |
| 674 | |
| 675 | pub fn set_rotate_unit(&mut self, axis: V3, radians: scalar) -> &mut Self { |
| 676 | self.set_rotate_unit_sin_cos(axis, radians.sin(), radians.cos()) |
| 677 | } |
| 678 | |
| 679 | pub fn set_rotate(&mut self, axis: V3, radians: scalar) -> &mut Self { |
| 680 | unsafe { self.native_mut().setRotate(axis.into_native(), radians) }; |
| 681 | self |
| 682 | } |
| 683 | |
| 684 | #[deprecated (since = "0.30.0" , note = "use M44::col_major() and M44::set_concat()" )] |
| 685 | pub fn set_concat_16(&mut self, a: &M44, col_major: &[scalar; Self::COMPONENTS]) -> &mut Self { |
| 686 | self.set_concat(a, &Self::col_major(col_major)) |
| 687 | } |
| 688 | |
| 689 | pub fn set_concat(&mut self, a: &M44, b: &M44) -> &mut Self { |
| 690 | unsafe { |
| 691 | self.native_mut().setConcat(a.native(), b.native()); |
| 692 | } |
| 693 | self |
| 694 | } |
| 695 | |
| 696 | #[deprecated (since = "0.30.0" , note = "use M44::col_major() and M44::pre_concat()" )] |
| 697 | #[allow (deprecated)] |
| 698 | pub fn pre_concat_16(&mut self, col_major: &[scalar; Self::COMPONENTS]) -> &mut Self { |
| 699 | self.set_concat_16(&self.clone(), col_major) |
| 700 | } |
| 701 | |
| 702 | pub fn pre_concat(&mut self, m: &M44) -> &mut Self { |
| 703 | unsafe { |
| 704 | let self_ptr = self.native() as *const _; |
| 705 | self.native_mut().setConcat(self_ptr, m.native()); |
| 706 | } |
| 707 | self |
| 708 | } |
| 709 | |
| 710 | pub fn post_concat(&mut self, m: &M44) -> &mut Self { |
| 711 | unsafe { |
| 712 | let self_ptr = self.native() as *const _; |
| 713 | self.native_mut().setConcat(m.native(), self_ptr); |
| 714 | } |
| 715 | self |
| 716 | } |
| 717 | |
| 718 | pub fn normalize_perspective(&mut self) { |
| 719 | unsafe { self.native_mut().normalizePerspective() } |
| 720 | } |
| 721 | |
| 722 | pub fn is_finite(&self) -> bool { |
| 723 | is_finite(&self.mat) |
| 724 | } |
| 725 | |
| 726 | #[must_use ] |
| 727 | pub fn invert(&self) -> Option<M44> { |
| 728 | let mut m = Self::default(); |
| 729 | unsafe { self.native().invert(m.native_mut()) }.if_true_some(m) |
| 730 | } |
| 731 | |
| 732 | #[must_use ] |
| 733 | pub fn transpose(&self) -> Self { |
| 734 | Self::construct(|m| unsafe { sb::C_SkM44_transpose(self.native(), m) }) |
| 735 | } |
| 736 | |
| 737 | pub fn dump(&self) { |
| 738 | unsafe { self.native().dump() } |
| 739 | } |
| 740 | |
| 741 | pub fn map(&self, x: f32, y: f32, z: f32, w: f32) -> V4 { |
| 742 | V4::from_native_c(unsafe { sb::C_SkM44_map(self.native(), x, y, z, w) }) |
| 743 | } |
| 744 | |
| 745 | pub fn to_m33(&self) -> Matrix { |
| 746 | let m = &self.mat; |
| 747 | Matrix::new_all(m[0], m[4], m[12], m[1], m[5], m[13], m[3], m[7], m[15]) |
| 748 | } |
| 749 | |
| 750 | pub fn pre_translate( |
| 751 | &mut self, |
| 752 | x: scalar, |
| 753 | y: scalar, |
| 754 | z: impl Into<Option<scalar>>, |
| 755 | ) -> &mut Self { |
| 756 | unsafe { |
| 757 | self.native_mut() |
| 758 | .preTranslate(x, y, z.into().unwrap_or(0.0)) |
| 759 | }; |
| 760 | self |
| 761 | } |
| 762 | |
| 763 | pub fn post_translate( |
| 764 | &mut self, |
| 765 | x: scalar, |
| 766 | y: scalar, |
| 767 | z: impl Into<Option<scalar>>, |
| 768 | ) -> &mut Self { |
| 769 | unsafe { |
| 770 | self.native_mut() |
| 771 | .postTranslate(x, y, z.into().unwrap_or(0.0)) |
| 772 | }; |
| 773 | self |
| 774 | } |
| 775 | |
| 776 | pub fn pre_scale(&mut self, x: scalar, y: scalar) -> &mut Self { |
| 777 | unsafe { self.native_mut().preScale(x, y) }; |
| 778 | self |
| 779 | } |
| 780 | |
| 781 | pub fn pre_scale_xyz(&mut self, x: scalar, y: scalar, z: scalar) -> &mut Self { |
| 782 | unsafe { self.native_mut().preScale1(x, y, z) }; |
| 783 | self |
| 784 | } |
| 785 | } |
| 786 | |
| 787 | impl Mul for &M44 { |
| 788 | type Output = M44; |
| 789 | |
| 790 | fn mul(self, m: Self) -> Self::Output { |
| 791 | M44::concat(self, b:m) |
| 792 | } |
| 793 | } |
| 794 | |
| 795 | impl Mul<V4> for &M44 { |
| 796 | type Output = V4; |
| 797 | |
| 798 | fn mul(self, v: V4) -> Self::Output { |
| 799 | self.map(v.x, v.y, v.z, v.w) |
| 800 | } |
| 801 | } |
| 802 | |
| 803 | impl Mul<V3> for &M44 { |
| 804 | type Output = V3; |
| 805 | |
| 806 | fn mul(self, v: V3) -> Self::Output { |
| 807 | let v4: V4 = self.map(v.x, v.y, v.z, w:0.0); |
| 808 | V3::new(v4.x, v4.y, v4.z) |
| 809 | } |
| 810 | } |
| 811 | |
| 812 | impl From<&Matrix> for M44 { |
| 813 | fn from(src: &Matrix) -> Self { |
| 814 | use crate::matrix::Member::*; |
| 815 | |
| 816 | Self::new( |
| 817 | m0:src[ScaleX], |
| 818 | m4:src[SkewX], |
| 819 | m8:0.0, |
| 820 | m12:src[TransX], |
| 821 | m1:src[SkewY], |
| 822 | m5:src[ScaleY], |
| 823 | m9:0.0, |
| 824 | m13:src[TransY], |
| 825 | m2:0.0, |
| 826 | m6:0.0, |
| 827 | m10:1.0, |
| 828 | m14:0.0, |
| 829 | m3:src[Persp0], |
| 830 | m7:src[Persp1], |
| 831 | m11:0.0, |
| 832 | m15:src[Persp2], |
| 833 | ) |
| 834 | } |
| 835 | } |
| 836 | |
| 837 | impl From<Matrix> for M44 { |
| 838 | fn from(m: Matrix) -> Self { |
| 839 | M44::from(&m) |
| 840 | } |
| 841 | } |
| 842 | |
| 843 | #[cfg (test)] |
| 844 | mod tests { |
| 845 | use crate::{matrix, Matrix, Rect, M44}; |
| 846 | |
| 847 | #[test ] |
| 848 | pub fn convert_from_matrix_and_back() { |
| 849 | // taken from skulpin's physics example. |
| 850 | let vr = Rect::new(-4.5, -4.0, 4.5, 2.0); |
| 851 | let dst = Rect::new(0.0, 0.0, 1350.0, 900.0); |
| 852 | |
| 853 | let m = Matrix::from_rect_to_rect(vr, dst, matrix::ScaleToFit::Center).unwrap(); |
| 854 | let m44 = M44::from(m); |
| 855 | let m3 = m44.to_m33(); |
| 856 | assert_eq!(m, m3); |
| 857 | } |
| 858 | } |
| 859 | |