1use crate::ffi;
18use crate::misc::AsF32;
19use std::f32::consts::PI;
20use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Range, Sub, SubAssign};
21
22#[cfg(feature = "with_serde")]
23use serde::{Deserialize, Serialize};
24
25make_rslice!(RSliceVec4, Vector4, ffi::MemFree);
26
27macro_rules! optional_serde_struct {
28 ($def:item) => {
29 cfg_if::cfg_if! {
30 if #[cfg(feature = "with_serde")] {
31 #[repr(C)]
32 #[derive(Default, Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
33 $def
34 } else {
35 #[repr(C)]
36 #[derive(Default, Debug, Copy, Clone, PartialEq)]
37 $def
38 }
39 }
40 };
41}
42
43optional_serde_struct! {
44 pub struct Vector2 {
45 pub x: f32,
46 pub y: f32,
47 }
48}
49
50#[cfg(feature = "convert_mint")]
51impl From<mint::Vector2<f32>> for Vector2 {
52 fn from(v: mint::Vector2<f32>) -> Vector2 {
53 Vector2 { x: v.x, y: v.y }
54 }
55}
56
57#[cfg(feature = "convert_mint")]
58impl From<mint::Point2<f32>> for Vector2 {
59 fn from(v: mint::Point2<f32>) -> Vector2 {
60 Vector2 { x: v.x, y: v.y }
61 }
62}
63
64#[cfg(feature = "convert_mint")]
65impl From<Vector2> for mint::Vector2<f32> {
66 fn from(v: Vector2) -> Self {
67 Self { x: v.x, y: v.y }
68 }
69}
70
71impl From<ffi::Vector2> for Vector2 {
72 fn from(v: ffi::Vector2) -> Vector2 {
73 unsafe { std::mem::transmute(v) }
74 }
75}
76
77impl From<Vector2> for ffi::Vector2 {
78 fn from(v: Vector2) -> Self {
79 unsafe { std::mem::transmute(v) }
80 }
81}
82
83impl From<&Vector2> for ffi::Vector2 {
84 fn from(v: &Vector2) -> ffi::Vector2 {
85 ffi::Vector2 { x: v.x, y: v.y }
86 }
87}
88
89#[inline]
91pub fn lerp(v0: f32, v1: f32, amount: f32) -> f32 {
92 v0 + amount * (v1 - v0)
93}
94
95#[inline]
97pub fn rvec2<T1: AsF32, T2: AsF32>(x: T1, y: T2) -> Vector2 {
98 Vector2::new(x.as_f32(), y.as_f32())
99}
100
101#[inline]
103pub fn rvec3<T1: AsF32, T2: AsF32, T3: AsF32>(x: T1, y: T2, z: T3) -> Vector3 {
104 Vector3::new(x.as_f32(), y.as_f32(), z.as_f32())
105}
106
107#[inline]
109pub fn rquat<T1: AsF32, T2: AsF32, T3: AsF32, T4: AsF32>(x: T1, y: T2, z: T3, w: T4) -> Quaternion {
110 Quaternion::new(x.as_f32(), y.as_f32(), z.as_f32(), w.as_f32())
111}
112
113#[inline]
115pub fn rrect<T1: AsF32, T2: AsF32, T3: AsF32, T4: AsF32>(
116 x: T1,
117 y: T2,
118 width: T3,
119 height: T4,
120) -> Rectangle {
121 Rectangle::new(x.as_f32(), y.as_f32(), width.as_f32(), height.as_f32())
122}
123
124impl Vector2 {
125 const ZERO: Vector2 = Vector2 { x: 0.0, y: 0.0 };
127
128 const ONE: Vector2 = Vector2 { x: 1.0, y: 1.0 };
130
131 pub const fn new(x: f32, y: f32) -> Vector2 {
133 Vector2 { x, y }
134 }
135
136 #[inline]
138 pub const fn zero() -> Vector2 {
139 Vector2 { x: 0.0, y: 0.0 }
140 }
141
142 #[inline]
144 pub const fn one() -> Vector2 {
145 Vector2 { x: 1.0, y: 1.0 }
146 }
147
148 pub fn length(&self) -> f32 {
150 ((self.x * self.x) + (self.y * self.y)).sqrt()
151 }
152
153 pub fn length_sqr(&self) -> f32 {
155 (self.x * self.x) + (self.y * self.y)
156 }
157
158 pub fn dot(&self, v: Vector2) -> f32 {
160 self.x * v.x + self.y * v.y
161 }
162
163 pub fn distance_to(&self, v: Vector2) -> f32 {
165 ((self.x - v.x) * (self.x - v.x) + (self.y - v.y) * (self.y - v.y)).sqrt()
166 }
167
168 pub fn angle_to(&self, v: Vector2) -> f32 {
170 let mut result = (v.y - self.y).atan2(v.x - self.x);
171 if result < 0.0 {
172 result += 2.0 * PI;
173 }
174 result
175 }
176
177 pub fn scale(&mut self, scale: f32) {
179 *self *= scale;
180 }
181
182 pub fn scale_by(&self, scale: f32) -> Vector2 {
184 *self * scale
185 }
186
187 pub fn normalize(&mut self) {
189 *self = self.normalized();
190 }
191
192 pub fn normalized(&self) -> Vector2 {
194 let length_sqr = self.length_sqr();
195 if length_sqr == 0.0 {
196 return *self;
197 }
198 *self / length_sqr.sqrt()
199 }
200
201 pub fn rotate(&mut self, angle: f32) {
203 let cos_res = angle.cos();
204 let sin_res = angle.sin();
205
206 let result = Vector2::new(
207 self.x * cos_res - self.y * sin_res,
208 self.x * sin_res + self.y * cos_res,
209 );
210
211 self.x = result.x;
212 self.y = result.y;
213 }
214
215 pub fn rotated(&self, angle: f32) -> Vector2 {
217 let cos_res = angle.cos();
218 let sin_res = angle.sin();
219
220 Vector2::new(
221 self.x * cos_res - self.y * sin_res,
222 self.x * sin_res + self.y * cos_res,
223 )
224 }
225
226 pub fn lerp(&self, v: Vector2, amount: f32) -> Vector2 {
228 Vector2 {
229 x: self.x + amount * (v.x - self.x),
230 y: self.y + amount * (v.y - self.y),
231 }
232 }
233
234 pub fn clamp(&self, num: Range<f32>) -> Vector2 {
236 Vector2 {
237 x: self.x.clamp(num.start, num.end),
238 y: self.y.clamp(num.start, num.end),
239 }
240 }
241}
242
243impl From<(f32, f32)> for Vector2 {
244 #[inline]
245 fn from((x, y): (f32, f32)) -> Vector2 {
246 Vector2 { x, y }
247 }
248}
249
250impl Add for Vector2 {
251 type Output = Vector2;
252 fn add(self, v: Vector2) -> Self {
253 Vector2 {
254 x: self.x + v.x,
255 y: self.y + v.y,
256 }
257 }
258}
259
260impl Add<f32> for Vector2 {
261 type Output = Vector2;
262 fn add(self, value: f32) -> Self {
263 Vector2 {
264 x: self.x + value,
265 y: self.y + value,
266 }
267 }
268}
269
270impl AddAssign for Vector2 {
271 fn add_assign(&mut self, v: Vector2) {
272 *self = *self + v;
273 }
274}
275
276impl AddAssign<f32> for Vector2 {
277 fn add_assign(&mut self, value: f32) {
278 *self = *self + value;
279 }
280}
281
282impl Sub for Vector2 {
283 type Output = Vector2;
284 fn sub(self, v: Vector2) -> Self {
285 Vector2 {
286 x: self.x - v.x,
287 y: self.y - v.y,
288 }
289 }
290}
291
292impl Sub<f32> for Vector2 {
293 type Output = Vector2;
294 fn sub(self, value: f32) -> Self {
295 Vector2 {
296 x: self.x - value,
297 y: self.y - value,
298 }
299 }
300}
301
302impl SubAssign for Vector2 {
303 fn sub_assign(&mut self, v: Vector2) {
304 *self = *self - v;
305 }
306}
307
308impl SubAssign<f32> for Vector2 {
309 fn sub_assign(&mut self, value: f32) {
310 *self = *self - value;
311 }
312}
313
314impl Mul for Vector2 {
315 type Output = Vector2;
316 fn mul(self, v: Vector2) -> Self {
317 Vector2 {
318 x: self.x * v.x,
319 y: self.y * v.y,
320 }
321 }
322}
323
324impl Mul<f32> for Vector2 {
325 type Output = Vector2;
326 fn mul(self, value: f32) -> Self {
327 Vector2 {
328 x: self.x * value,
329 y: self.y * value,
330 }
331 }
332}
333
334impl MulAssign for Vector2 {
335 fn mul_assign(&mut self, v: Vector2) {
336 *self = *self * v;
337 }
338}
339
340impl MulAssign<f32> for Vector2 {
341 fn mul_assign(&mut self, value: f32) {
342 *self = *self * value;
343 }
344}
345
346impl Div for Vector2 {
347 type Output = Vector2;
348 fn div(self, v: Vector2) -> Self {
349 Vector2 {
350 x: self.x / v.x,
351 y: self.y / v.y,
352 }
353 }
354}
355
356impl Div<f32> for Vector2 {
357 type Output = Vector2;
358 fn div(self, value: f32) -> Self {
359 Vector2 {
360 x: self.x / value,
361 y: self.y / value,
362 }
363 }
364}
365
366impl DivAssign for Vector2 {
367 fn div_assign(&mut self, v: Vector2) {
368 *self = *self / v;
369 }
370}
371
372impl DivAssign<f32> for Vector2 {
373 fn div_assign(&mut self, value: f32) {
374 *self = *self / value;
375 }
376}
377
378impl Neg for Vector2 {
379 type Output = Vector2;
380 fn neg(self) -> Self {
381 Vector2 {
382 x: -self.x,
383 y: -self.y,
384 }
385 }
386}
387
388optional_serde_struct! {
389 pub struct Vector3 {
390 pub x: f32,
391 pub y: f32,
392 pub z: f32,
393 }
394}
395
396#[cfg(feature = "convert_mint")]
397impl From<mint::Vector3<f32>> for Vector3 {
398 fn from(v: mint::Vector3<f32>) -> Vector3 {
399 Vector3 {
400 x: v.x,
401 y: v.y,
402 z: v.z,
403 }
404 }
405}
406
407#[cfg(feature = "convert_mint")]
408impl From<mint::Point3<f32>> for Vector3 {
409 fn from(v: mint::Point3<f32>) -> Vector3 {
410 Vector3 {
411 x: v.x,
412 y: v.y,
413 z: v.z,
414 }
415 }
416}
417
418#[cfg(feature = "convert_mint")]
419impl From<Vector3> for mint::Vector3<f32> {
420 fn from(v: Vector3) -> Self {
421 Self {
422 x: v.x,
423 y: v.y,
424 z: v.z,
425 }
426 }
427}
428
429impl From<ffi::Vector3> for Vector3 {
430 fn from(v: ffi::Vector3) -> Vector3 {
431 unsafe { std::mem::transmute(v) }
432 }
433}
434
435impl From<Vector3> for ffi::Vector3 {
436 fn from(v: Vector3) -> Self {
437 unsafe { std::mem::transmute(v) }
438 }
439}
440
441impl From<&Vector3> for ffi::Vector3 {
442 fn from(v: &Vector3) -> ffi::Vector3 {
443 ffi::Vector3 {
444 x: v.x,
445 y: v.y,
446 z: v.z,
447 }
448 }
449}
450
451impl Vector3 {
452 pub const fn new(x: f32, y: f32, z: f32) -> Vector3 {
454 Vector3 { x, y, z }
455 }
456
457 pub fn up() -> Vector3 {
458 Vector3::new(0.0, 1.0, 0.0)
459 }
460
461 pub fn forward() -> Vector3 {
462 Vector3::new(0.0, 0.0, 1.0)
463 }
464
465 pub fn right() -> Vector3 {
466 Vector3::new(1.0, 0.0, 0.0)
467 }
468
469 pub fn left() -> Vector3 {
470 Vector3::new(-1.0, 0.0, 0.0)
471 }
472
473 pub fn zero() -> Vector3 {
475 Vector3 {
476 x: 0.0,
477 y: 0.0,
478 z: 0.0,
479 }
480 }
481
482 pub fn one() -> Vector3 {
484 Vector3 {
485 x: 1.0,
486 y: 1.0,
487 z: 1.0,
488 }
489 }
490
491 pub fn cross(&self, v: Vector3) -> Vector3 {
493 Vector3 {
494 x: self.y * v.z - self.z * v.y,
495 y: self.z * v.x - self.x * v.z,
496 z: self.x * v.y - self.y * v.x,
497 }
498 }
499
500 pub fn perpendicular(&self) -> Vector3 {
502 let mut min = self.x.abs();
503 let mut cardinal_axis = Vector3 {
504 x: 1.0,
505 y: 0.0,
506 z: 0.0,
507 };
508
509 if self.y.abs() < min {
510 min = self.y.abs();
511 cardinal_axis = Vector3 {
512 x: 0.0,
513 y: 1.0,
514 z: 0.0,
515 };
516 }
517
518 if self.z.abs() < min {
519 cardinal_axis = Vector3 {
520 x: 0.0,
521 y: 0.0,
522 z: 1.0,
523 };
524 }
525
526 self.cross(cardinal_axis)
527 }
528
529 pub fn length(&self) -> f32 {
531 (self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
532 }
533
534 pub fn dot(&self, v: Vector3) -> f32 {
536 self.x * v.x + self.y * v.y + self.z * v.z
537 }
538
539 pub fn distance_to(&self, v: Vector3) -> f32 {
541 let dx = v.x - self.x;
542 let dy = v.y - self.y;
543 let dz = v.z - self.z;
544 (dx * dx + dy * dy + dz * dz).sqrt()
545 }
546
547 pub fn scale(&mut self, scale: f32) {
549 *self *= scale;
550 }
551
552 pub fn scale_by(&self, scale: f32) -> Vector3 {
554 *self * scale
555 }
556
557 pub fn normalize(&mut self) {
559 *self = self.normalized();
560 }
561
562 pub fn normalized(&self) -> Vector3 {
564 let mut length = self.length();
565 if length == 0.0 {
566 length = 1.0;
567 }
568 let ilength = 1.0 / length;
569
570 Vector3 {
571 x: self.x * ilength,
572 y: self.y * ilength,
573 z: self.z * ilength,
574 }
575 }
576
577 pub fn ortho_normalize(&mut self, v: &mut Vector3) {
579 *self = self.normalized();
580 let vn = self.cross(*v).normalized();
581 *v = vn.cross(*self);
582 }
583
584 pub fn transform(&mut self, mat: Matrix) {
586 *self = self.transform_with(mat);
587 }
588
589 pub fn transform_with(&self, mat: Matrix) -> Vector3 {
591 Vector3 {
592 x: mat.m0 * self.x + mat.m4 * self.y + mat.m8 * self.z + mat.m12,
593 y: mat.m1 * self.x + mat.m5 * self.y + mat.m9 * self.z + mat.m13,
594 z: mat.m2 * self.x + mat.m6 * self.y + mat.m10 * self.z + mat.m14,
595 }
596 }
597
598 pub fn rotate(&mut self, q: Quaternion) {
600 *self = self.rotate_by(q);
601 }
602
603 pub fn rotate_by(&self, q: Quaternion) -> Vector3 {
605 Vector3 {
606 x: self.x * (q.x * q.x + q.w * q.w - q.y * q.y - q.z * q.z)
607 + self.y * (2.0 * q.x * q.y - 2.0 * q.w * q.z)
608 + self.z * (2.0 * q.x * q.z + 2.0 * q.w * q.y),
609 y: self.x * (2.0 * q.w * q.z + 2.0 * q.x * q.y)
610 + self.y * (q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z)
611 + self.z * (-2.0 * q.w * q.x + 2.0 * q.y * q.z),
612 z: self.x * (-2.0 * q.w * q.y + 2.0 * q.x * q.z)
613 + self.y * (2.0 * q.w * q.x + 2.0 * q.y * q.z)
614 + self.z * (q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z),
615 }
616 }
617
618 pub fn lerp(&self, v: Vector3, amount: f32) -> Vector3 {
620 Vector3 {
621 x: self.x + amount * (v.x - self.x),
622 y: self.y + amount * (v.y - self.y),
623 z: self.z + amount * (v.z - self.z),
624 }
625 }
626
627 pub fn reflect(&mut self, normal: Vector3) {
629 *self = self.reflect_from(normal);
630 }
631
632 pub fn reflect_from(&self, normal: Vector3) -> Vector3 {
634 let dot_product = self.dot(normal);
635 Vector3 {
636 x: self.x - (2.0 * normal.x) * dot_product,
637 y: self.y - (2.0 * normal.y) * dot_product,
638 z: self.z - (2.0 * normal.z) * dot_product,
639 }
640 }
641
642 pub fn min(&self, v: Vector3) -> Vector3 {
644 Vector3 {
645 x: self.x.min(v.x),
646 y: self.y.min(v.y),
647 z: self.z.min(v.z),
648 }
649 }
650
651 pub fn max(&self, v: Vector3) -> Vector3 {
653 Vector3 {
654 x: self.x.max(v.x),
655 y: self.y.max(v.y),
656 z: self.z.max(v.z),
657 }
658 }
659
660 pub fn barycenter(&self, a: Vector3, b: Vector3, c: Vector3) -> Vector3 {
662 let v0 = b - a;
663 let v1 = c - a;
664 let v2 = *self - a;
665 let d00 = v0.dot(v0);
666 let d01 = v0.dot(v1);
667 let d11 = v1.dot(v1);
668 let d20 = v2.dot(v0);
669 let d21 = v2.dot(v1);
670 let denom = d00 * d11 - d01 * d01;
671
672 let y = (d11 * d20 - d01 * d21) / denom;
673 let z = (d00 * d21 - d01 * d20) / denom;
674 Vector3 {
675 x: 1.0 - (z + y),
676 y,
677 z,
678 }
679 }
680
681 pub fn to_array(&self) -> [f32; 3] {
683 [self.x, self.y, self.z]
684 }
685
686 pub fn clamp(&self, num: Range<f32>) -> Vector3 {
688 Vector3 {
689 x: self.x.clamp(num.start, num.end),
690 y: self.y.clamp(num.start, num.end),
691 z: self.z.clamp(num.start, num.end),
692 }
693 }
694}
695
696impl From<(f32, f32, f32)> for Vector3 {
697 #[inline]
698 fn from((x, y, z): (f32, f32, f32)) -> Vector3 {
699 Vector3 { x, y, z }
700 }
701}
702
703impl Add for Vector3 {
704 type Output = Vector3;
705 fn add(self, v: Vector3) -> Self {
706 Vector3 {
707 x: self.x + v.x,
708 y: self.y + v.y,
709 z: self.z + v.z,
710 }
711 }
712}
713
714impl Add<f32> for Vector3 {
715 type Output = Vector3;
716 fn add(self, value: f32) -> Self {
717 Vector3 {
718 x: self.x + value,
719 y: self.y + value,
720 z: self.z + value,
721 }
722 }
723}
724
725impl AddAssign for Vector3 {
726 fn add_assign(&mut self, v: Vector3) {
727 *self = *self + v;
728 }
729}
730
731impl AddAssign<f32> for Vector3 {
732 fn add_assign(&mut self, value: f32) {
733 *self = *self + value;
734 }
735}
736
737impl Sub for Vector3 {
738 type Output = Vector3;
739 fn sub(self, v: Vector3) -> Self {
740 Vector3 {
741 x: self.x - v.x,
742 y: self.y - v.y,
743 z: self.z - v.z,
744 }
745 }
746}
747
748impl Sub<f32> for Vector3 {
749 type Output = Vector3;
750 fn sub(self, value: f32) -> Self {
751 Vector3 {
752 x: self.x - value,
753 y: self.y - value,
754 z: self.z - value,
755 }
756 }
757}
758
759impl SubAssign for Vector3 {
760 fn sub_assign(&mut self, v: Vector3) {
761 *self = *self - v;
762 }
763}
764
765impl SubAssign<f32> for Vector3 {
766 fn sub_assign(&mut self, value: f32) {
767 *self = *self - value;
768 }
769}
770
771impl Mul for Vector3 {
772 type Output = Vector3;
773 fn mul(self, v: Vector3) -> Self {
774 Vector3 {
775 x: self.x * v.x,
776 y: self.y * v.y,
777 z: self.z * v.z,
778 }
779 }
780}
781
782impl Mul<f32> for Vector3 {
783 type Output = Vector3;
784 fn mul(self, value: f32) -> Self {
785 Vector3 {
786 x: self.x * value,
787 y: self.y * value,
788 z: self.z * value,
789 }
790 }
791}
792
793impl MulAssign for Vector3 {
794 fn mul_assign(&mut self, v: Vector3) {
795 *self = *self * v;
796 }
797}
798
799impl MulAssign<f32> for Vector3 {
800 fn mul_assign(&mut self, value: f32) {
801 *self = *self * value;
802 }
803}
804
805impl Div for Vector3 {
806 type Output = Vector3;
807 fn div(self, v: Vector3) -> Self {
808 Vector3 {
809 x: self.x / v.x,
810 y: self.y / v.y,
811 z: self.z / v.z,
812 }
813 }
814}
815
816impl Div<f32> for Vector3 {
817 type Output = Vector3;
818 fn div(self, value: f32) -> Self {
819 Vector3 {
820 x: self.x / value,
821 y: self.y / value,
822 z: self.z / value,
823 }
824 }
825}
826
827impl DivAssign for Vector3 {
828 fn div_assign(&mut self, v: Vector3) {
829 *self = *self / v;
830 }
831}
832
833impl DivAssign<f32> for Vector3 {
834 fn div_assign(&mut self, value: f32) {
835 *self = *self / value;
836 }
837}
838
839impl Neg for Vector3 {
840 type Output = Vector3;
841 fn neg(self) -> Self {
842 Vector3 {
843 x: -self.x,
844 y: -self.y,
845 z: -self.z,
846 }
847 }
848}
849
850optional_serde_struct! {
851 pub struct Vector4 {
852 pub x: f32,
853 pub y: f32,
854 pub z: f32,
855 pub w: f32,
856 }
857}
858
859pub type Quaternion = Vector4;
860
861#[cfg(feature = "convert_mint")]
862impl From<mint::Vector4<f32>> for Vector4 {
863 fn from(v: mint::Vector4<f32>) -> Vector4 {
864 Vector4 {
865 x: v.x,
866 y: v.y,
867 z: v.z,
868 w: v.w,
869 }
870 }
871}
872
873#[cfg(feature = "convert_mint")]
874impl From<Vector4> for mint::Vector4<f32> {
875 fn from(v: Vector4) -> Self {
876 mint::Vector4 {
877 x: v.x,
878 y: v.y,
879 z: v.z,
880 w: v.w,
881 }
882 }
883}
884
885impl From<ffi::Vector4> for Vector4 {
886 fn from(v: ffi::Vector4) -> Vector4 {
887 unsafe { std::mem::transmute(v) }
888 }
889}
890
891impl From<Vector4> for ffi::Vector4 {
892 fn from(v: Vector4) -> ffi::Vector4 {
893 unsafe { std::mem::transmute(v) }
894 }
895}
896
897impl From<&Vector4> for ffi::Vector4 {
898 fn from(v: &Vector4) -> ffi::Vector4 {
899 ffi::Vector4 {
900 x: v.x,
901 y: v.y,
902 z: v.z,
903 w: v.w,
904 }
905 }
906}
907
908impl Quaternion {
909 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Quaternion {
911 Quaternion { x, y, z, w }
912 }
913
914 pub fn identity() -> Quaternion {
916 Quaternion {
917 x: 0.0,
918 y: 0.0,
919 z: 0.0,
920 w: 1.0,
921 }
922 }
923
924 pub fn from_vec3_pair(from: Vector3, to: Vector3) -> Quaternion {
926 let cross = from.cross(to);
927 Quaternion {
928 x: cross.x,
929 y: cross.y,
930 z: cross.z,
931 w: 1.0 + from.dot(to),
932 }
933 .normalized()
934 }
935
936 pub fn from_matrix(mat: Matrix) -> Quaternion {
938 let trace = mat.trace();
939
940 if trace > 0.0 {
941 let s = (trace + 1.0).sqrt() * 2.0;
942 let inv_s = 1.0 / s;
943
944 Quaternion {
945 w: s * 0.25,
946 x: (mat.m6 - mat.m9) * inv_s,
947 y: (mat.m8 - mat.m2) * inv_s,
948 z: (mat.m1 - mat.m4) * inv_s,
949 }
950 } else {
951 let m00 = mat.m0;
952 let m11 = mat.m5;
953 let m22 = mat.m10;
954
955 if m00 > m11 && m00 > m22 {
956 let s = (1.0 + m00 - m11 - m22).sqrt() * 2.0;
957 let inv_s = 1.0 / s;
958
959 Quaternion {
960 w: (mat.m6 - mat.m9) * inv_s,
961 x: s * 0.25,
962 y: (mat.m4 + mat.m1) * inv_s,
963 z: (mat.m8 + mat.m2) * inv_s,
964 }
965 } else if m11 > m22 {
966 let s = (1.0 + m11 - m00 - m22).sqrt() * 2.0;
967 let inv_s = 1.0 / s;
968
969 Quaternion {
970 w: (mat.m8 - mat.m2) * inv_s,
971 x: (mat.m4 + mat.m1) * inv_s,
972 y: s * 0.25,
973 z: (mat.m9 + mat.m6) * inv_s,
974 }
975 } else {
976 let s = (1.0 + m22 - m00 - m11).sqrt() * 2.0;
977 let inv_s = 1.0 / s;
978
979 Quaternion {
980 w: (mat.m1 - mat.m4) * inv_s,
981 x: (mat.m8 + mat.m2) * inv_s,
982 y: (mat.m9 + mat.m6) * inv_s,
983 z: s * 0.25,
984 }
985 }
986 }
987 }
988
989 pub fn to_matrix(&self) -> Matrix {
991 let x = self.x;
992 let y = self.y;
993 let z = self.z;
994 let w = self.w;
995
996 let x2 = x + x;
997 let y2 = y + y;
998 let z2 = z + z;
999
1000 let length = self.length();
1001 let length_squared = length * length;
1002
1003 let xx = x * x2 / length_squared;
1004 let xy = x * y2 / length_squared;
1005 let xz = x * z2 / length_squared;
1006
1007 let yy = y * y2 / length_squared;
1008 let yz = y * z2 / length_squared;
1009 let zz = z * z2 / length_squared;
1010
1011 let wx = w * x2 / length_squared;
1012 let wy = w * y2 / length_squared;
1013 let wz = w * z2 / length_squared;
1014
1015 Matrix {
1016 m0: 1.0 - (yy + zz),
1017 m1: xy - wz,
1018 m2: xz + wy,
1019 m3: 0.0,
1020 m4: xy + wz,
1021 m5: 1.0 - (xx + zz),
1022 m6: yz - wx,
1023 m7: 0.0,
1024 m8: xz - wy,
1025 m9: yz + wx,
1026 m10: 1.0 - (xx + yy),
1027 m11: 0.0,
1028 m12: 0.0,
1029 m13: 0.0,
1030 m14: 0.0,
1031 m15: 1.0,
1032 }
1033 }
1034
1035 pub fn from_euler(pitch: f32, yaw: f32, roll: f32) -> Quaternion {
1037 let x0 = (pitch * 0.5).cos();
1038 let x1 = (pitch * 0.5).sin();
1039 let y0 = (yaw * 0.5).cos();
1040 let y1 = (yaw * 0.5).sin();
1041 let z0 = (roll * 0.5).cos();
1042 let z1 = (roll * 0.5).sin();
1043
1044 Quaternion {
1045 x: (x1 * y0 * z0) - (x0 * y1 * z1),
1046 y: (x0 * y1 * z0) + (x1 * y0 * z1),
1047 z: (x0 * y0 * z1) - (x1 * y1 * z0),
1048 w: (x0 * y0 * z0) + (x1 * y1 * z1),
1049 }
1050 }
1051
1052 pub fn to_euler(&self) -> Vector3 {
1054 let x0 = 2.0 * (self.w * self.x + self.y * self.z);
1056 let x1 = 1.0 - 2.0 * (self.x * self.x + self.y * self.y);
1057
1058 let mut y0 = 2.0 * (self.w * self.y - self.z * self.x);
1060 y0 = if y0 > 1.0 { 1.0 } else { y0 };
1061 y0 = if y0 < -1.0 { -1.0 } else { y0 };
1062
1063 let z0 = 2.0 * (self.w * self.z + self.x * self.y);
1065 let z1 = 1.0 - 2.0 * (self.y * self.y + self.z * self.z);
1066
1067 Vector3 {
1068 x: x0.atan2(x1),
1069 y: y0.asin(),
1070 z: z0.atan2(z1),
1071 }
1072 }
1073
1074 pub fn from_axis_angle(axis: Vector3, angle: f32) -> Quaternion {
1076 let mut result = Quaternion::identity();
1077 let mut axis = axis;
1078 let mut angle = angle;
1079
1080 if axis.length() != 0.0 {
1081 angle *= 0.5;
1082 }
1083
1084 axis.normalize();
1085
1086 let sinres = angle.sin();
1087 let cosres = angle.cos();
1088
1089 result.x = axis.x * sinres;
1090 result.y = axis.y * sinres;
1091 result.z = axis.z * sinres;
1092 result.w = cosres;
1093 result.normalized()
1094 }
1095
1096 pub fn to_axis_angle(&self) -> (Vector3, f32) {
1098 let mut q = *self;
1099 if q.w.abs() > 1.0 {
1100 q = q.normalized();
1101 }
1102
1103 let mut res_axis = Vector3::zero();
1104 let res_angle = 2.0 * q.w.acos();
1105 let den = (1.0 - q.w * q.w).sqrt();
1106
1107 if den > 0.0001 {
1108 res_axis.x = q.x / den;
1109 res_axis.y = q.y / den;
1110 res_axis.z = q.z / den;
1111 } else {
1112 res_axis.x = 1.0;
1115 }
1116
1117 (res_axis, res_angle)
1118 }
1119
1120 pub fn length(&self) -> f32 {
1122 (self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w).sqrt()
1123 }
1124
1125 pub fn normalized(&self) -> Quaternion {
1127 let mut length = self.length();
1128 if length == 0.0 {
1129 length = 1.0;
1130 }
1131 let ilength = 1.0 / length;
1132
1133 Quaternion {
1134 x: self.x * ilength,
1135 y: self.y * ilength,
1136 z: self.z * ilength,
1137 w: self.w * ilength,
1138 }
1139 }
1140
1141 pub fn inverted(&self) -> Quaternion {
1143 let mut result = *self;
1144 let length = self.length();
1145 let length_sq = length * length;
1146
1147 if length_sq != 0.0 {
1148 let i = 1.0 / length_sq;
1149 result.x *= -i;
1150 result.y *= -i;
1151 result.z *= -i;
1152 result.w *= i;
1153 }
1154 result
1155 }
1156
1157 pub fn lerp(&self, q: Quaternion, amount: f32) -> Quaternion {
1159 Quaternion {
1160 x: self.x + amount * (q.x - self.x),
1161 y: self.y + amount * (q.y - self.y),
1162 z: self.z + amount * (q.z - self.z),
1163 w: self.w + amount * (q.w - self.w),
1164 }
1165 }
1166
1167 pub fn nlerp(&self, q: Quaternion, amount: f32) -> Quaternion {
1169 self.lerp(q, amount).normalized()
1170 }
1171
1172 pub fn slerp(&self, q: Quaternion, amount: f32) -> Quaternion {
1174 let cos_half_theta = self.x * q.x + self.y * q.y + self.z * q.z + self.w * q.w;
1175
1176 if cos_half_theta.abs() >= 1.0 {
1177 *self
1178 } else if cos_half_theta > 0.95 {
1179 self.nlerp(q, amount)
1180 } else {
1181 let half_theta = cos_half_theta.acos();
1182 let sin_half_theta = (1.0 - cos_half_theta * cos_half_theta).sqrt();
1183
1184 if sin_half_theta.abs() < 0.001 {
1185 Quaternion {
1186 x: (self.x * 0.5 + q.x * 0.5),
1187 y: (self.y * 0.5 + q.y * 0.5),
1188 z: (self.z * 0.5 + q.z * 0.5),
1189 w: (self.w * 0.5 + q.w * 0.5),
1190 }
1191 } else {
1192 let ratio_a = ((1.0 - amount) * half_theta).sin() / sin_half_theta;
1193 let ratio_b = (amount * half_theta).sin() / sin_half_theta;
1194
1195 Quaternion {
1196 x: (self.x * ratio_a + q.x * ratio_b),
1197 y: (self.y * ratio_a + q.y * ratio_b),
1198 z: (self.z * ratio_a + q.z * ratio_b),
1199 w: (self.w * ratio_a + q.w * ratio_b),
1200 }
1201 }
1202 }
1203 }
1204
1205 pub fn transform(&self, mat: Matrix) -> Quaternion {
1207 Quaternion {
1208 x: mat.m0 * self.x + mat.m4 * self.y + mat.m8 * self.z + mat.m12 * self.w,
1209 y: mat.m1 * self.x + mat.m5 * self.y + mat.m9 * self.z + mat.m13 * self.w,
1210 z: mat.m2 * self.x + mat.m6 * self.y + mat.m10 * self.z + mat.m14 * self.w,
1211 w: mat.m3 * self.x + mat.m7 * self.y + mat.m11 * self.z + mat.m15 * self.w,
1212 }
1213 }
1214
1215 pub fn clamp(&self, num: Range<f32>) -> Quaternion {
1217 Quaternion {
1218 x: self.x.clamp(num.start, num.end),
1219 y: self.y.clamp(num.start, num.end),
1220 z: self.z.clamp(num.start, num.end),
1221 w: self.w.clamp(num.start, num.end),
1222 }
1223 }
1224}
1225
1226#[cfg(feature = "convert_mint")]
1227impl From<mint::Quaternion<f32>> for Quaternion {
1228 fn from(q: mint::Quaternion<f32>) -> Quaternion {
1229 Quaternion {
1230 x: q.v.x,
1231 y: q.v.y,
1232 z: q.v.z,
1233 w: q.s,
1234 }
1235 }
1236}
1237
1238#[cfg(feature = "convert_mint")]
1239impl From<Quaternion> for mint::Quaternion<f32> {
1240 fn from(q: Quaternion) -> Self {
1241 Self {
1242 v: mint::Vector3 {
1243 x: q.x,
1244 y: q.y,
1245 z: q.z,
1246 },
1247 s: q.w,
1248 }
1249 }
1250}
1251
1252impl From<(f32, f32, f32, f32)> for Quaternion {
1253 #[inline]
1254 fn from((x, y, z, w): (f32, f32, f32, f32)) -> Quaternion {
1255 Quaternion { x, y, z, w }
1256 }
1257}
1258
1259impl Mul for Quaternion {
1260 type Output = Quaternion;
1261 fn mul(self, q: Quaternion) -> Quaternion {
1262 let qax = self.x;
1263 let qay = self.y;
1264 let qaz = self.z;
1265 let qaw = self.w;
1266 let qbx = q.x;
1267 let qby = q.y;
1268 let qbz = q.z;
1269 let qbw = q.w;
1270
1271 Quaternion {
1272 x: (qax * qbw) + (qaw * qbx) + (qay * qbz) - (qaz * qby),
1273 y: (qay * qbw) + (qaw * qby) + (qaz * qbx) - (qax * qbz),
1274 z: (qaz * qbw) + (qaw * qbz) + (qax * qby) - (qay * qbx),
1275 w: (qaw * qbw) - (qax * qbx) - (qay * qby) - (qaz * qbz),
1276 }
1277 }
1278}
1279
1280impl MulAssign for Quaternion {
1281 fn mul_assign(&mut self, q: Quaternion) {
1282 *self = *self * q;
1283 }
1284}
1285
1286optional_serde_struct! {
1287 pub struct Matrix {
1288 pub m0: f32,
1289 pub m4: f32,
1290 pub m8: f32,
1291 pub m12: f32,
1292 pub m1: f32,
1293 pub m5: f32,
1294 pub m9: f32,
1295 pub m13: f32,
1296 pub m2: f32,
1297 pub m6: f32,
1298 pub m10: f32,
1299 pub m14: f32,
1300 pub m3: f32,
1301 pub m7: f32,
1302 pub m11: f32,
1303 pub m15: f32,
1304 }
1305}
1306
1307impl From<ffi::Matrix> for Matrix {
1308 fn from(r: ffi::Matrix) -> Matrix {
1309 unsafe { std::mem::transmute(r) }
1310 }
1311}
1312
1313impl From<Matrix> for ffi::Matrix {
1314 fn from(v: Matrix) -> Self {
1315 unsafe { std::mem::transmute(v) }
1316 }
1317}
1318
1319impl From<&Matrix> for ffi::Matrix {
1320 fn from(v: &Matrix) -> Self {
1321 ffi::Matrix {
1322 m0: v.m0,
1323 m4: v.m4,
1324 m8: v.m8,
1325 m12: v.m12,
1326 m1: v.m1,
1327 m5: v.m5,
1328 m9: v.m9,
1329 m13: v.m13,
1330 m2: v.m2,
1331 m6: v.m6,
1332 m10: v.m10,
1333 m14: v.m14,
1334 m3: v.m3,
1335 m7: v.m7,
1336 m11: v.m11,
1337 m15: v.m15,
1338 }
1339 }
1340}
1341
1342impl Matrix {
1343 pub fn identity() -> Matrix {
1345 Matrix {
1346 m0: 1.0,
1347 m4: 0.0,
1348 m8: 0.0,
1349 m12: 0.0,
1350 m1: 0.0,
1351 m5: 1.0,
1352 m9: 0.0,
1353 m13: 0.0,
1354 m2: 0.0,
1355 m6: 0.0,
1356 m10: 1.0,
1357 m14: 0.0,
1358 m3: 0.0,
1359 m7: 0.0,
1360 m11: 0.0,
1361 m15: 1.0,
1362 }
1363 }
1364
1365 pub fn zero() -> Matrix {
1367 Matrix {
1368 m0: 0.0,
1369 m4: 0.0,
1370 m8: 0.0,
1371 m12: 0.0,
1372 m1: 0.0,
1373 m5: 0.0,
1374 m9: 0.0,
1375 m13: 0.0,
1376 m2: 0.0,
1377 m6: 0.0,
1378 m10: 0.0,
1379 m14: 0.0,
1380 m3: 0.0,
1381 m7: 0.0,
1382 m11: 0.0,
1383 m15: 0.0,
1384 }
1385 }
1386
1387 pub fn translate(x: f32, y: f32, z: f32) -> Matrix {
1389 Matrix {
1390 m0: 1.0,
1391 m4: 0.0,
1392 m8: 0.0,
1393 m12: x,
1394 m1: 0.0,
1395 m5: 1.0,
1396 m9: 0.0,
1397 m13: y,
1398 m2: 0.0,
1399 m6: 0.0,
1400 m10: 1.0,
1401 m14: z,
1402 m3: 0.0,
1403 m7: 0.0,
1404 m11: 0.0,
1405 m15: 1.0,
1406 }
1407 }
1408
1409 pub fn rotate(axis: Vector3, angle: f32) -> Matrix {
1411 let mut x = axis.x;
1412 let mut y = axis.y;
1413 let mut z = axis.z;
1414 let mut length = (x * x + y * y + z * z).sqrt();
1415
1416 if (length != 1.0) && (length != 0.0) {
1417 length = 1.0 / length;
1418 x *= length;
1419 y *= length;
1420 z *= length;
1421 }
1422
1423 let sinres = angle.sin();
1424 let cosres = angle.cos();
1425 let t = 1.0 - cosres;
1426
1427 Matrix {
1428 m0: (x * x * t) + cosres,
1429 m1: (y * x * t) + (z * sinres),
1430 m2: (z * x * t) - (y * sinres),
1431 m3: 0.0,
1432
1433 m4: (x * y * t) - (z * sinres),
1434 m5: (y * y * t) + cosres,
1435 m6: (z * y * t) + (x * sinres),
1436 m7: 0.0,
1437
1438 m8: (x * z * t) + (y * sinres),
1439 m9: (y * z * t) - (x * sinres),
1440 m10: (z * z * t) + cosres,
1441 m11: 0.0,
1442
1443 m12: 0.0,
1444 m13: 0.0,
1445 m14: 0.0,
1446 m15: 1.0,
1447 }
1448 }
1449
1450 pub fn rotate_x(angle: f32) -> Matrix {
1452 let mut result = Matrix::identity();
1453
1454 let cosres = angle.cos();
1455 let sinres = angle.sin();
1456
1457 result.m5 = cosres;
1458 result.m6 = sinres;
1459 result.m9 = -sinres;
1460 result.m10 = cosres;
1461 result
1462 }
1463
1464 pub fn rotate_y(angle: f32) -> Matrix {
1466 let mut result = Matrix::identity();
1467
1468 let cosres = angle.cos();
1469 let sinres = angle.sin();
1470
1471 result.m0 = cosres;
1472 result.m2 = -sinres;
1473 result.m8 = sinres;
1474 result.m10 = cosres;
1475 result
1476 }
1477
1478 pub fn rotate_z(angle: f32) -> Matrix {
1480 let mut result = Matrix::identity();
1481
1482 let cosres = angle.cos();
1483 let sinres = angle.sin();
1484
1485 result.m0 = cosres;
1486 result.m1 = sinres;
1487 result.m4 = -sinres;
1488 result.m5 = cosres;
1489 result
1490 }
1491
1492 pub fn rotate_xyz(ang: Vector3) -> Self {
1494 let mut result = Self::identity();
1495
1496 let cosz = -ang.z.cos();
1497 let sinz = -ang.z.sin();
1498 let cosy = -ang.y.cos();
1499 let siny = -ang.y.sin();
1500 let cosx = -ang.x.cos();
1501 let sinx = -ang.x.sin();
1502
1503 result.m0 = cosz * cosy;
1504 result.m4 = (cosz * siny * sinx) - (sinz * cosx);
1505 result.m8 = (cosz * siny * cosx) + (sinz * sinx);
1506
1507 result.m1 = sinz * cosy;
1508 result.m5 = (sinz * siny * sinx) + (cosz * cosx);
1509 result.m9 = (sinz * siny * cosx) - (cosz * sinx);
1510
1511 result.m2 = -siny;
1512 result.m6 = cosy * sinx;
1513 result.m10 = cosy * cosx;
1514
1515 result
1516 }
1517
1518 pub fn scale(x: f32, y: f32, z: f32) -> Matrix {
1520 Matrix {
1521 m0: x,
1522 m4: 0.0,
1523 m8: 0.0,
1524 m12: 0.0,
1525 m1: 0.0,
1526 m5: y,
1527 m9: 0.0,
1528 m13: 0.0,
1529 m2: 0.0,
1530 m6: 0.0,
1531 m10: z,
1532 m14: 0.0,
1533 m3: 0.0,
1534 m7: 0.0,
1535 m11: 0.0,
1536 m15: 1.0,
1537 }
1538 }
1539
1540 pub fn frustum(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32) -> Matrix {
1542 let rl = right - left;
1543 let tb = top - bottom;
1544 let fne = far - near;
1545
1546 Matrix {
1547 m0: (near * 2.0) / rl,
1548 m1: 0.0,
1549 m2: 0.0,
1550 m3: 0.0,
1551
1552 m4: 0.0,
1553 m5: (near * 2.0) / tb,
1554 m6: 0.0,
1555 m7: 0.0,
1556
1557 m8: (right + left) / rl,
1558 m9: (top + bottom) / tb,
1559 m10: -(far + near) / fne,
1560 m11: -1.0,
1561
1562 m12: 0.0,
1563 m13: 0.0,
1564 m14: -(far * near * 2.0) / fne,
1565 m15: 0.0,
1566 }
1567 }
1568
1569 pub fn perspective(fovy: f32, aspect: f32, near: f32, far: f32) -> Matrix {
1571 let top = near * (fovy * 0.5).tan();
1572 let right = top * aspect;
1573 Matrix::frustum(-right, right, -top, top, near, far)
1574 }
1575
1576 pub fn ortho(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32) -> Matrix {
1578 let rl = right - left;
1579 let tb = top - bottom;
1580 let fne = far - near;
1581
1582 Matrix {
1583 m0: 2.0 / rl,
1584 m1: 0.0,
1585 m2: 0.0,
1586 m3: 0.0,
1587 m4: 0.0,
1588 m5: 2.0 / tb,
1589 m6: 0.0,
1590 m7: 0.0,
1591 m8: 0.0,
1592 m9: 0.0,
1593 m10: -2.0 / fne,
1594 m11: 0.0,
1595 m12: -(left + right) / rl,
1596 m13: -(top + bottom) / tb,
1597 m14: -(far + near) / fne,
1598 m15: 1.0,
1599 }
1600 }
1601
1602 pub fn look_at(eye: Vector3, target: Vector3, up: Vector3) -> Matrix {
1604 let z = (eye - target).normalized();
1605 let x = up.cross(z).normalized();
1606 let y = z.cross(x).normalized();
1607
1608 Matrix {
1609 m0: x.x,
1610 m1: x.y,
1611 m2: x.z,
1612 m3: 0.0,
1613 m4: y.x,
1614 m5: y.y,
1615 m6: y.z,
1616 m7: 0.0,
1617 m8: z.x,
1618 m9: z.y,
1619 m10: z.z,
1620 m11: 0.0,
1621 m12: eye.x,
1622 m13: eye.y,
1623 m14: eye.z,
1624 m15: 1.0,
1625 }
1626 .inverted()
1627 }
1628
1629 pub fn determinant(&self) -> f32 {
1631 let a00 = self.m0;
1632 let a01 = self.m1;
1633 let a02 = self.m2;
1634 let a03 = self.m3;
1635 let a10 = self.m4;
1636 let a11 = self.m5;
1637 let a12 = self.m6;
1638 let a13 = self.m7;
1639 let a20 = self.m8;
1640 let a21 = self.m9;
1641 let a22 = self.m10;
1642 let a23 = self.m11;
1643 let a30 = self.m12;
1644 let a31 = self.m13;
1645 let a32 = self.m14;
1646 let a33 = self.m15;
1647
1648 a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03
1649 + a10 * a31 * a22 * a03
1650 + a20 * a11 * a32 * a03
1651 - a10 * a21 * a32 * a03
1652 - a30 * a21 * a02 * a13
1653 + a20 * a31 * a02 * a13
1654 + a30 * a01 * a22 * a13
1655 - a00 * a31 * a22 * a13
1656 - a20 * a01 * a32 * a13
1657 + a00 * a21 * a32 * a13
1658 + a30 * a11 * a02 * a23
1659 - a10 * a31 * a02 * a23
1660 - a30 * a01 * a12 * a23
1661 + a00 * a31 * a12 * a23
1662 + a10 * a01 * a32 * a23
1663 - a00 * a11 * a32 * a23
1664 - a20 * a11 * a02 * a33
1665 + a10 * a21 * a02 * a33
1666 + a20 * a01 * a12 * a33
1667 - a00 * a21 * a12 * a33
1668 - a10 * a01 * a22 * a33
1669 + a00 * a11 * a22 * a33
1670 }
1671
1672 pub fn trace(&self) -> f32 {
1674 self.m0 + self.m5 + self.m10 + self.m15
1675 }
1676
1677 pub fn transposed(&self) -> Matrix {
1679 Matrix {
1680 m0: self.m0,
1681 m1: self.m4,
1682 m2: self.m8,
1683 m3: self.m12,
1684 m4: self.m1,
1685 m5: self.m5,
1686 m6: self.m9,
1687 m7: self.m13,
1688 m8: self.m2,
1689 m9: self.m6,
1690 m10: self.m10,
1691 m11: self.m14,
1692 m12: self.m3,
1693 m13: self.m7,
1694 m14: self.m11,
1695 m15: self.m15,
1696 }
1697 }
1698
1699 pub fn inverted(&self) -> Matrix {
1701 let a00 = self.m0;
1702 let a01 = self.m1;
1703 let a02 = self.m2;
1704 let a03 = self.m3;
1705 let a10 = self.m4;
1706 let a11 = self.m5;
1707 let a12 = self.m6;
1708 let a13 = self.m7;
1709 let a20 = self.m8;
1710 let a21 = self.m9;
1711 let a22 = self.m10;
1712 let a23 = self.m11;
1713 let a30 = self.m12;
1714 let a31 = self.m13;
1715 let a32 = self.m14;
1716 let a33 = self.m15;
1717
1718 let b00 = (a00 * a11) - (a01 * a10);
1719 let b01 = (a00 * a12) - (a02 * a10);
1720 let b02 = (a00 * a13) - (a03 * a10);
1721 let b03 = (a01 * a12) - (a02 * a11);
1722 let b04 = (a01 * a13) - (a03 * a11);
1723 let b05 = (a02 * a13) - (a03 * a12);
1724 let b06 = (a20 * a31) - (a21 * a30);
1725 let b07 = (a20 * a32) - (a22 * a30);
1726 let b08 = (a20 * a33) - (a23 * a30);
1727 let b09 = (a21 * a32) - (a22 * a31);
1728 let b10 = (a21 * a33) - (a23 * a31);
1729 let b11 = (a22 * a33) - (a23 * a32);
1730
1731 let inv_det = 1.0
1732 / ((b00 * b11) - (b01 * b10) + (b02 * b09) + (b03 * b08) - (b04 * b07) + (b05 * b06));
1733
1734 Matrix {
1735 m0: ((a11 * b11) - (a12 * b10) + (a13 * b09)) * inv_det,
1736 m1: ((-a01 * b11) + (a02 * b10) - (a03 * b09)) * inv_det,
1737 m2: ((a31 * b05) - (a32 * b04) + (a33 * b03)) * inv_det,
1738 m3: ((-a21 * b05) + (a22 * b04) - (a23 * b03)) * inv_det,
1739 m4: ((-a10 * b11) + (a12 * b08) - (a13 * b07)) * inv_det,
1740 m5: ((a00 * b11) - (a02 * b08) + (a03 * b07)) * inv_det,
1741 m6: ((-a30 * b05) + (a32 * b02) - (a33 * b01)) * inv_det,
1742 m7: ((a20 * b05) - (a22 * b02) + (a23 * b01)) * inv_det,
1743 m8: ((a10 * b10) - (a11 * b08) + (a13 * b06)) * inv_det,
1744 m9: ((-a00 * b10) + (a01 * b08) - (a03 * b06)) * inv_det,
1745 m10: ((a30 * b04) - (a31 * b02) + (a33 * b00)) * inv_det,
1746 m11: ((-a20 * b04) + (a21 * b02) - (a23 * b00)) * inv_det,
1747 m12: ((-a10 * b09) + (a11 * b07) - (a12 * b06)) * inv_det,
1748 m13: ((a00 * b09) - (a01 * b07) + (a02 * b06)) * inv_det,
1749 m14: ((-a30 * b03) + (a31 * b01) - (a32 * b00)) * inv_det,
1750 m15: ((a20 * b03) - (a21 * b01) + (a22 * b00)) * inv_det,
1751 }
1752 }
1753
1754 pub fn normalized(&self) -> Matrix {
1756 let det = self.determinant();
1757 Matrix {
1758 m0: self.m0 / det,
1759 m1: self.m1 / det,
1760 m2: self.m2 / det,
1761 m3: self.m3 / det,
1762 m4: self.m4 / det,
1763 m5: self.m5 / det,
1764 m6: self.m6 / det,
1765 m7: self.m7 / det,
1766 m8: self.m8 / det,
1767 m9: self.m9 / det,
1768 m10: self.m10 / det,
1769 m11: self.m11 / det,
1770 m12: self.m12 / det,
1771 m13: self.m13 / det,
1772 m14: self.m14 / det,
1773 m15: self.m15 / det,
1774 }
1775 }
1776
1777 pub fn to_array(&self) -> [f32; 16] {
1779 [
1780 self.m0, self.m1, self.m2, self.m3, self.m4, self.m5, self.m6, self.m7, self.m8,
1781 self.m9, self.m10, self.m11, self.m12, self.m13, self.m14, self.m15,
1782 ]
1783 }
1784}
1785
1786impl Add for Matrix {
1787 type Output = Matrix;
1788 fn add(self, mat: Matrix) -> Matrix {
1789 Matrix {
1790 m0: self.m0 + mat.m0,
1791 m1: self.m1 + mat.m1,
1792 m2: self.m2 + mat.m2,
1793 m3: self.m3 + mat.m3,
1794 m4: self.m4 + mat.m4,
1795 m5: self.m5 + mat.m5,
1796 m6: self.m6 + mat.m6,
1797 m7: self.m7 + mat.m7,
1798 m8: self.m8 + mat.m8,
1799 m9: self.m9 + mat.m9,
1800 m10: self.m10 + mat.m10,
1801 m11: self.m11 + mat.m11,
1802 m12: self.m12 + mat.m12,
1803 m13: self.m13 + mat.m13,
1804 m14: self.m14 + mat.m14,
1805 m15: self.m15 + mat.m15,
1806 }
1807 }
1808}
1809
1810impl AddAssign for Matrix {
1811 fn add_assign(&mut self, mat: Matrix) {
1812 *self = *self + mat;
1813 }
1814}
1815
1816impl Sub for Matrix {
1817 type Output = Matrix;
1818 fn sub(self, mat: Matrix) -> Matrix {
1819 Matrix {
1820 m0: self.m0 - mat.m0,
1821 m1: self.m1 - mat.m1,
1822 m2: self.m2 - mat.m2,
1823 m3: self.m3 - mat.m3,
1824 m4: self.m4 - mat.m4,
1825 m5: self.m5 - mat.m5,
1826 m6: self.m6 - mat.m6,
1827 m7: self.m7 - mat.m7,
1828 m8: self.m8 - mat.m8,
1829 m9: self.m9 - mat.m9,
1830 m10: self.m10 - mat.m10,
1831 m11: self.m11 - mat.m11,
1832 m12: self.m12 - mat.m12,
1833 m13: self.m13 - mat.m13,
1834 m14: self.m14 - mat.m14,
1835 m15: self.m15 - mat.m15,
1836 }
1837 }
1838}
1839
1840impl SubAssign for Matrix {
1841 fn sub_assign(&mut self, mat: Matrix) {
1842 *self = *self - mat;
1843 }
1844}
1845
1846impl Mul for Matrix {
1847 type Output = Matrix;
1848 fn mul(self, mat: Matrix) -> Matrix {
1849 Matrix {
1850 m0: self.m0 * mat.m0 + self.m1 * mat.m4 + self.m2 * mat.m8 + self.m3 * mat.m12,
1851 m1: self.m0 * mat.m1 + self.m1 * mat.m5 + self.m2 * mat.m9 + self.m3 * mat.m13,
1852 m2: self.m0 * mat.m2 + self.m1 * mat.m6 + self.m2 * mat.m10 + self.m3 * mat.m14,
1853 m3: self.m0 * mat.m3 + self.m1 * mat.m7 + self.m2 * mat.m11 + self.m3 * mat.m15,
1854 m4: self.m4 * mat.m0 + self.m5 * mat.m4 + self.m6 * mat.m8 + self.m7 * mat.m12,
1855 m5: self.m4 * mat.m1 + self.m5 * mat.m5 + self.m6 * mat.m9 + self.m7 * mat.m13,
1856 m6: self.m4 * mat.m2 + self.m5 * mat.m6 + self.m6 * mat.m10 + self.m7 * mat.m14,
1857 m7: self.m4 * mat.m3 + self.m5 * mat.m7 + self.m6 * mat.m11 + self.m7 * mat.m15,
1858 m8: self.m8 * mat.m0 + self.m9 * mat.m4 + self.m10 * mat.m8 + self.m11 * mat.m12,
1859 m9: self.m8 * mat.m1 + self.m9 * mat.m5 + self.m10 * mat.m9 + self.m11 * mat.m13,
1860 m10: self.m8 * mat.m2 + self.m9 * mat.m6 + self.m10 * mat.m10 + self.m11 * mat.m14,
1861 m11: self.m8 * mat.m3 + self.m9 * mat.m7 + self.m10 * mat.m11 + self.m11 * mat.m15,
1862 m12: self.m12 * mat.m0 + self.m13 * mat.m4 + self.m14 * mat.m8 + self.m15 * mat.m12,
1863 m13: self.m12 * mat.m1 + self.m13 * mat.m5 + self.m14 * mat.m9 + self.m15 * mat.m13,
1864 m14: self.m12 * mat.m2 + self.m13 * mat.m6 + self.m14 * mat.m10 + self.m15 * mat.m14,
1865 m15: self.m12 * mat.m3 + self.m13 * mat.m7 + self.m14 * mat.m11 + self.m15 * mat.m15,
1866 }
1867 }
1868}
1869
1870impl MulAssign for Matrix {
1871 fn mul_assign(&mut self, mat: Matrix) {
1872 *self = *self * mat;
1873 }
1874}
1875
1876optional_serde_struct! {
1877 pub struct Ray {
1878 pub position: Vector3,
1879 pub direction: Vector3,
1880 }
1881}
1882
1883impl From<ffi::Ray> for Ray {
1884 fn from(r: ffi::Ray) -> Ray {
1885 unsafe { std::mem::transmute(r) }
1886 }
1887}
1888
1889impl From<Ray> for ffi::Ray {
1890 fn from(v: Ray) -> ffi::Ray {
1891 unsafe { std::mem::transmute(v) }
1892 }
1893}
1894
1895impl From<&Ray> for ffi::Ray {
1896 fn from(v: &Ray) -> ffi::Ray {
1897 ffi::Ray {
1898 position: v.position.into(),
1899 direction: v.direction.into(),
1900 }
1901 }
1902}
1903
1904impl Ray {
1905 pub const fn new(position: Vector3, direction: Vector3) -> Self {
1906 Self {
1907 position,
1908 direction,
1909 }
1910 }
1911}
1912
1913optional_serde_struct! {
1914 pub struct Rectangle {
1915 pub x: f32,
1916 pub y: f32,
1917 pub width: f32,
1918 pub height: f32,
1919 }
1920}
1921
1922impl From<ffi::Rectangle> for Rectangle {
1923 fn from(r: ffi::Rectangle) -> Rectangle {
1924 unsafe { std::mem::transmute(r) }
1925 }
1926}
1927
1928impl From<Rectangle> for ffi::Rectangle {
1929 fn from(v: Rectangle) -> ffi::Rectangle {
1930 unsafe { std::mem::transmute(v) }
1931 }
1932}
1933
1934impl From<&Rectangle> for ffi::Rectangle {
1935 fn from(v: &Rectangle) -> ffi::Rectangle {
1936 ffi::Rectangle {
1937 x: v.x,
1938 y: v.y,
1939 width: v.width,
1940 height: v.height,
1941 }
1942 }
1943}
1944
1945impl Rectangle {
1946 pub const EMPTY: Rectangle = Rectangle::new(0.0, 0.0, 0.0, 0.0);
1947 pub const fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
1948 Self {
1949 x,
1950 y,
1951 width,
1952 height,
1953 }
1954 }
1955}
1956
1957optional_serde_struct! {
1958 pub struct BoundingBox {
1959 pub min: Vector3,
1960 pub max: Vector3,
1961 }
1962}
1963
1964impl BoundingBox {
1965 pub fn new(min: Vector3, max: Vector3) -> BoundingBox {
1966 BoundingBox { min, max }
1967 }
1968}
1969
1970impl From<ffi::BoundingBox> for BoundingBox {
1971 fn from(r: ffi::BoundingBox) -> BoundingBox {
1972 unsafe { std::mem::transmute(r) }
1973 }
1974}
1975
1976impl From<BoundingBox> for ffi::BoundingBox {
1977 fn from(v: BoundingBox) -> ffi::BoundingBox {
1978 unsafe { std::mem::transmute(v) }
1979 }
1980}
1981
1982impl From<&BoundingBox> for ffi::BoundingBox {
1983 fn from(v: &BoundingBox) -> ffi::BoundingBox {
1984 ffi::BoundingBox {
1985 min: v.min.into(),
1986 max: v.max.into(),
1987 }
1988 }
1989}
1990
1991optional_serde_struct! {
1992 pub struct RayCollision {
1993 pub hit: bool,
1994 pub distance: f32,
1995 pub point: Vector3,
1996 pub normal: Vector3,
1997 }
1998}
1999
2000impl From<ffi::RayCollision> for RayCollision {
2001 fn from(r: ffi::RayCollision) -> RayCollision {
2002 unsafe { std::mem::transmute(r) }
2003 }
2004}
2005
2006impl From<RayCollision> for ffi::RayCollision {
2007 fn from(v: RayCollision) -> ffi::RayCollision {
2008 unsafe { std::mem::transmute(v) }
2009 }
2010}
2011
2012impl From<&RayCollision> for ffi::RayCollision {
2013 fn from(v: &RayCollision) -> ffi::RayCollision {
2014 ffi::RayCollision {
2015 hit: v.hit,
2016 distance: v.distance,
2017 point: v.point.into(),
2018 normal: v.normal.into(),
2019 }
2020 }
2021}
2022
2023optional_serde_struct! {
2024 pub struct Transform {
2025 pub translation: Vector3,
2026 pub rotation: Quaternion,
2027 pub scale: Vector3,
2028 }
2029}
2030
2031impl From<ffi::Transform> for Transform {
2032 fn from(r: ffi::Transform) -> Transform {
2033 unsafe { std::mem::transmute(r) }
2034 }
2035}
2036
2037impl From<Transform> for ffi::Transform {
2038 fn from(v: Transform) -> ffi::Transform {
2039 unsafe { std::mem::transmute(v) }
2040 }
2041}
2042
2043impl From<&Transform> for ffi::Transform {
2044 fn from(v: &Transform) -> ffi::Transform {
2045 ffi::Transform {
2046 translation: v.translation.into(),
2047 rotation: v.rotation.into(),
2048 scale: v.scale.into(),
2049 }
2050 }
2051}
2052
2053#[cfg(test)]
2054mod math_test {
2055 use super::{Ray, Vector2, Vector3, Vector4};
2056 use crate::ffi;
2057
2058 #[test]
2059 fn test_into() {
2060 let v2: ffi::Vector2 = (Vector2 { x: 1.0, y: 2.0 }).into();
2061 assert!(v2.x == 1.0 && v2.y == 2.0, "bad memory transmutation");
2062
2063 let v3: ffi::Vector3 = (Vector3 {
2064 x: 1.0,
2065 y: 2.0,
2066 z: 3.0,
2067 })
2068 .into();
2069 assert!(
2070 v3.x == 1.0 && v3.y == 2.0 && v3.z == 3.0,
2071 "bad memory transmutation"
2072 );
2073
2074 let v4: ffi::Vector4 = (Vector4 {
2075 x: 1.0,
2076 y: 2.0,
2077 z: 3.0,
2078 w: 4.0,
2079 })
2080 .into();
2081 assert!(
2082 v4.x == 1.0 && v4.y == 2.0 && v4.z == 3.0 && v4.w == 4.0,
2083 "bad memory transmutation"
2084 );
2085
2086 let r: ffi::Ray = (Ray {
2087 position: v3.into(),
2088 direction: Vector3 {
2089 x: 3.0,
2090 y: 2.0,
2091 z: 1.0,
2092 },
2093 })
2094 .into();
2095 assert!(
2096 r.position.x == 1.0
2097 && r.position.y == 2.0
2098 && r.position.z == 3.0
2099 && r.direction.x == 3.0
2100 && r.direction.y == 2.0
2101 && r.direction.z == 1.0,
2102 "bad memory transmutation"
2103 )
2104 }
2105}