1use crate::numtraits::{One, Zero};
4use crate::Real;
5use std::mem::transmute;
6use std::ops::*;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[repr(C)]
11pub struct Vector2<T>(pub T, pub T);
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14#[repr(C)]
15pub struct Vector3<T>(pub T, pub T, pub T);
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
18#[repr(C)]
19pub struct Vector4<T>(pub T, pub T, pub T, pub T);
20#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
22#[repr(C)]
23pub struct Quaternion<T>(pub T, pub T, pub T, pub T);
24
25pub type Vector2F32 = Vector2<f32>;
27pub type Vector3F32 = Vector3<f32>;
29pub type Vector4F32 = Vector4<f32>;
31pub type QuaternionF32 = Quaternion<f32>;
33
34#[derive(Debug, Clone, PartialEq, Eq, Hash)]
36#[repr(C)]
37pub struct Matrix2<T>(pub [T; 2], pub [T; 2]);
38#[derive(Debug, Clone, PartialEq, Eq, Hash)]
40#[repr(C)]
41pub struct Matrix3<T>(pub [T; 3], pub [T; 3], pub [T; 3]);
42#[derive(Debug, Clone, PartialEq, Eq, Hash)]
44#[repr(C)]
45pub struct Matrix4<T>(pub [T; 4], pub [T; 4], pub [T; 4], pub [T; 4]);
46#[derive(Debug, Clone, PartialEq, Eq, Hash)]
48#[repr(C)]
49pub struct Matrix2x3<T>(pub [T; 3], pub [T; 3]);
50#[derive(Debug, Clone, PartialEq, Eq, Hash)]
52#[repr(C)]
53pub struct Matrix3x4<T>(pub [T; 4], pub [T; 4], pub [T; 4]);
54
55pub type Matrix2F32 = Matrix2<f32>;
57pub type Matrix3F32 = Matrix3<f32>;
59pub type Matrix4F32 = Matrix4<f32>;
61pub type Matrix2x3F32 = Matrix2x3<f32>;
63pub type Matrix3x4F32 = Matrix3x4<f32>;
65
66impl<T> Vector2<T> {
67 pub const fn x(&self) -> &T {
68 &self.0
69 }
70
71 pub const fn y(&self) -> &T {
72 &self.1
73 }
74}
75impl<T> Vector3<T> {
76 pub const fn x(&self) -> &T {
77 &self.0
78 }
79
80 pub const fn y(&self) -> &T {
81 &self.1
82 }
83
84 pub const fn z(&self) -> &T {
85 &self.2
86 }
87}
88impl<T> Vector4<T> {
89 pub const fn x(&self) -> &T {
90 &self.0
91 }
92
93 pub const fn y(&self) -> &T {
94 &self.1
95 }
96
97 pub const fn z(&self) -> &T {
98 &self.2
99 }
100
101 pub const fn w(&self) -> &T {
102 &self.3
103 }
104}
105
106impl<T: Zero> Zero for Vector2<T> {
108 const ZERO: Self = Vector2(T::ZERO, T::ZERO);
109}
110impl<T: One> One for Vector2<T> {
111 const ONE: Self = Vector2(T::ONE, T::ONE);
112}
113impl<T: Zero> Zero for Vector3<T> {
114 const ZERO: Self = Vector3(T::ZERO, T::ZERO, T::ZERO);
115}
116impl<T: One> One for Vector3<T> {
117 const ONE: Self = Vector3(T::ONE, T::ONE, T::ONE);
118}
119impl<T: Zero> Zero for Vector4<T> {
120 const ZERO: Self = Vector4(T::ZERO, T::ZERO, T::ZERO, T::ZERO);
121}
122impl<T: One> One for Vector4<T> {
123 const ONE: Self = Vector4(T::ONE, T::ONE, T::ONE, T::ONE);
124}
125
126impl<T: Zero + One> Vector2<T> {
128 pub fn left() -> Self
129 where
130 Self: Neg<Output = Self>,
131 {
132 -Self::right()
133 }
134
135 pub fn down() -> Self
136 where
137 Self: Neg<Output = Self>,
138 {
139 -Self::up()
140 }
141
142 pub const fn right() -> Self {
143 Self(T::ONE, T::ZERO)
144 }
145
146 pub const fn up() -> Self {
147 Self(T::ZERO, T::ONE)
148 }
149}
150
151impl<T: Zero + One> Vector3<T> {
152 pub fn left() -> Self
153 where
154 Self: Neg<Output = Self>,
155 {
156 -Self::right()
157 }
158
159 pub const fn right() -> Self {
160 Self(T::ONE, T::ZERO, T::ZERO)
161 }
162
163 pub fn down() -> Self
164 where
165 Self: Neg<Output = Self>,
166 {
167 -Self::up()
168 }
169
170 pub const fn up() -> Self {
171 Self(T::ZERO, T::ONE, T::ZERO)
172 }
173
174 pub fn back() -> Self
175 where
176 Self: Neg<Output = Self>,
177 {
178 -Self::forward()
179 }
180
181 pub const fn forward() -> Self {
182 Self(T::ZERO, T::ZERO, T::ONE)
183 }
184}
185
186impl<T: Div<T> + Copy> From<Vector4<T>> for Vector3<<T as Div>::Output> {
190 fn from(Vector4(x, y, z, w): Vector4<T>) -> Self {
191 Vector3(x / w, y / w, z / w)
192 }
193}
194
195impl<T> Vector2<T> {
196 pub fn with_z(self, z: T) -> Vector3<T> {
197 Vector3(self.0, self.1, z)
198 }
199}
200impl<T> Vector3<T> {
201 pub fn with_w(self, w: T) -> Vector4<T> {
202 Vector4(self.0, self.1, self.2, w)
203 }
204}
205
206impl<T> AsRef<[T; 2]> for Vector2<T> {
208 fn as_ref(&self) -> &[T; 2] {
209 unsafe { transmute(self) }
210 }
211}
212impl<T> AsRef<[T; 3]> for Vector3<T> {
213 fn as_ref(&self) -> &[T; 3] {
214 unsafe { transmute(self) }
215 }
216}
217impl<T> AsRef<[T; 4]> for Vector4<T> {
218 fn as_ref(&self) -> &[T; 4] {
219 unsafe { transmute(self) }
220 }
221}
222impl<T> AsRef<[T; 4]> for Quaternion<T> {
223 fn as_ref(&self) -> &[T; 4] {
224 unsafe { transmute(self) }
225 }
226}
227
228impl<T: Zero + One> One for Matrix2<T> {
230 const ONE: Self = Matrix2([T::ONE, T::ZERO], [T::ZERO, T::ONE]);
231}
232impl<T: Zero + One> One for Matrix3<T> {
233 const ONE: Self = Matrix3(
234 [T::ONE, T::ZERO, T::ZERO],
235 [T::ZERO, T::ONE, T::ZERO],
236 [T::ZERO, T::ZERO, T::ONE],
237 );
238}
239impl<T: Zero + One> One for Matrix4<T> {
240 const ONE: Self = Matrix4(
241 [T::ONE, T::ZERO, T::ZERO, T::ZERO],
242 [T::ZERO, T::ONE, T::ZERO, T::ZERO],
243 [T::ZERO, T::ZERO, T::ONE, T::ZERO],
244 [T::ZERO, T::ZERO, T::ZERO, T::ONE],
245 );
246}
247impl<T: Zero + One> One for Matrix2x3<T> {
248 const ONE: Self = Matrix2x3([T::ONE, T::ZERO, T::ZERO], [T::ZERO, T::ONE, T::ZERO]);
249}
250impl<T: Zero + One> One for Matrix3x4<T> {
251 const ONE: Self = Matrix3x4(
252 [T::ONE, T::ZERO, T::ZERO, T::ZERO],
253 [T::ZERO, T::ONE, T::ZERO, T::ZERO],
254 [T::ZERO, T::ZERO, T::ONE, T::ZERO],
255 );
256}
257
258impl<T: Zero + One> From<Matrix2<T>> for Matrix3<T> {
260 fn from(Matrix2([a, b], [c, d]): Matrix2<T>) -> Self {
261 Matrix3([a, b, T::ZERO], [c, d, T::ZERO], [T::ZERO, T::ZERO, T::ONE])
262 }
263}
264impl<T: Zero + One> From<Matrix3<T>> for Matrix4<T> {
265 fn from(Matrix3([a, b, c], [d, e, f], [g, h, i]): Matrix3<T>) -> Self {
266 Matrix4(
267 [a, b, c, T::ZERO],
268 [d, e, f, T::ZERO],
269 [g, h, i, T::ZERO],
270 [T::ZERO, T::ZERO, T::ZERO, T::ONE],
271 )
272 }
273}
274
275impl<T: Copy> Mul for Matrix2<T>
277where
278 T: Mul<T>,
279 <T as Mul>::Output: Add,
280{
281 type Output = Matrix2<<<T as Mul>::Output as Add>::Output>;
282 fn mul(self, other: Matrix2<T>) -> Self::Output {
283 let dp =
284 |src: &[T; 2], colindex: usize| src[0] * other.0[colindex] + src[1] * other.1[colindex];
285
286 Matrix2(
287 [dp(&self.0, 0), dp(&self.0, 1)],
288 [dp(&self.1, 0), dp(&self.1, 1)],
289 )
290 }
291}
292impl<T: Copy> Mul for Matrix3<T>
293where
294 T: Mul<T>,
295 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
296{
297 type Output = Matrix3<<T as Mul>::Output>;
298
299 fn mul(self, other: Matrix3<T>) -> Self::Output {
300 let dp = |src: &[T; 3], colindex: usize| {
301 src[0] * other.0[colindex] + src[1] * other.1[colindex] + src[2] * other.2[colindex]
302 };
303
304 Matrix3(
305 [dp(&self.0, 0), dp(&self.0, 1), dp(&self.0, 2)],
306 [dp(&self.1, 0), dp(&self.1, 1), dp(&self.1, 2)],
307 [dp(&self.2, 0), dp(&self.2, 1), dp(&self.2, 2)],
308 )
309 }
310}
311impl<T: Copy> Mul for Matrix4<T>
312where
313 T: Mul<T>,
314 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
315{
316 type Output = Matrix4<<T as Mul>::Output>;
317
318 fn mul(self, other: Matrix4<T>) -> Self::Output {
319 let dp = |src: &[T; 4], colindex: usize| {
320 src[0] * other.0[colindex]
321 + src[1] * other.1[colindex]
322 + src[2] * other.2[colindex]
323 + src[3] * other.3[colindex]
324 };
325
326 Matrix4(
327 [
328 dp(&self.0, 0),
329 dp(&self.0, 1),
330 dp(&self.0, 2),
331 dp(&self.0, 3),
332 ],
333 [
334 dp(&self.1, 0),
335 dp(&self.1, 1),
336 dp(&self.1, 2),
337 dp(&self.1, 3),
338 ],
339 [
340 dp(&self.2, 0),
341 dp(&self.2, 1),
342 dp(&self.2, 2),
343 dp(&self.2, 3),
344 ],
345 [
346 dp(&self.3, 0),
347 dp(&self.3, 1),
348 dp(&self.3, 2),
349 dp(&self.3, 3),
350 ],
351 )
352 }
353}
354
355impl<T> Matrix2<T> {
357 pub fn scale(Vector2(x, y): Vector2<T>) -> Self
358 where
359 T: Zero,
360 {
361 Matrix2([x, T::ZERO], [T::ZERO, y])
362 }
363
364 pub fn rotate(rad: T) -> Self
365 where
366 T: Real + Copy + Neg<Output = T>,
367 {
368 let (s, c) = rad.sin_cos();
369 Matrix2([c, -s], [s, c])
370 }
371}
372
373impl<T> Matrix3<T> {
375 #[inline(always)]
376 pub fn scale(Vector3(x, y, z): Vector3<T>) -> Self
377 where
378 T: Zero,
379 {
380 Matrix3(
381 [x, T::ZERO, T::ZERO],
382 [T::ZERO, y, T::ZERO],
383 [T::ZERO, T::ZERO, z],
384 )
385 }
386
387 #[inline(always)]
388 pub fn translation(Vector2(x, y): Vector2<T>) -> Self
389 where
390 T: One + Zero,
391 {
392 Matrix3(
393 [T::ONE, T::ZERO, x],
394 [T::ZERO, T::ONE, y],
395 [T::ZERO, T::ZERO, T::ONE],
396 )
397 }
398}
399impl<T> Matrix4<T> {
400 #[inline(always)]
401 pub fn scale(Vector4(x, y, z, w): Vector4<T>) -> Self
402 where
403 T: Zero,
404 {
405 Matrix4(
406 [x, T::ZERO, T::ZERO, T::ZERO],
407 [T::ZERO, y, T::ZERO, T::ZERO],
408 [T::ZERO, T::ZERO, z, T::ZERO],
409 [T::ZERO, T::ZERO, T::ZERO, w],
410 )
411 }
412
413 #[inline(always)]
414 pub fn translation(Vector3(x, y, z): Vector3<T>) -> Self
415 where
416 T: One + Zero,
417 {
418 Matrix4(
419 [T::ONE, T::ZERO, T::ZERO, x],
420 [T::ZERO, T::ONE, T::ZERO, y],
421 [T::ZERO, T::ZERO, T::ONE, z],
422 [T::ZERO, T::ZERO, T::ZERO, T::ONE],
423 )
424 }
425}
426
427impl<T> Matrix4<T> {
429 pub fn trs(translate: Vector3<T>, rotate: Quaternion<T>, scale: Vector3<T>) -> Self
430 where
431 T: One + Zero + Mul<T, Output = T> + Sub<T, Output = T> + Add<T, Output = T> + Copy,
432 {
433 Matrix4::translation(translate)
434 * Matrix4::from(rotate)
435 * Matrix4::scale(scale.with_w(T::ONE))
436 }
437}
438
439fn dotproduct2<T: Mul + Copy>(a: &[T; 2], b: &[T; 2]) -> <T as Mul>::Output
440where
441 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
442{
443 a[0] * b[0] + a[1] * b[1]
444}
445fn dotproduct3<T: Mul + Copy>(a: &[T; 3], b: &[T; 3]) -> <T as Mul>::Output
446where
447 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
448{
449 a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
450}
451fn dotproduct4<T: Mul + Copy>(a: &[T; 4], b: &[T; 4]) -> <T as Mul>::Output
452where
453 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
454{
455 a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
456}
457
458impl<T: Mul + Copy> Mul<Vector2<T>> for Matrix2<T>
460where
461 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
462{
463 type Output = Vector2<<T as Mul>::Output>;
464 fn mul(self, v: Vector2<T>) -> Self::Output {
465 Vector2(
466 dotproduct2(v.as_ref(), &self.0),
467 dotproduct2(v.as_ref(), &self.1),
468 )
469 }
470}
471impl<T: Mul + Copy> Mul<Vector3<T>> for Matrix3<T>
472where
473 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
474{
475 type Output = Vector3<<T as Mul>::Output>;
476 fn mul(self, v: Vector3<T>) -> Self::Output {
477 Vector3(
478 dotproduct3(v.as_ref(), &self.0),
479 dotproduct3(v.as_ref(), &self.1),
480 dotproduct3(v.as_ref(), &self.2),
481 )
482 }
483}
484impl<T: Mul + Copy> Mul<Vector4<T>> for Matrix4<T>
485where
486 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
487{
488 type Output = Vector4<<T as Mul>::Output>;
489 fn mul(self, v: Vector4<T>) -> Self::Output {
490 Vector4(
491 dotproduct4(v.as_ref(), &self.0),
492 dotproduct4(v.as_ref(), &self.1),
493 dotproduct4(v.as_ref(), &self.2),
494 dotproduct4(v.as_ref(), &self.3),
495 )
496 }
497}
498impl<T: Mul + One + Copy> Mul<Vector2<T>> for Matrix2x3<T>
499where
500 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
501{
502 type Output = Vector2<<T as Mul>::Output>;
503 fn mul(self, v: Vector2<T>) -> Self::Output {
504 let v3 = v.with_z(T::ONE);
505 Vector2(
506 dotproduct3(v3.as_ref(), &self.0),
507 dotproduct3(v3.as_ref(), &self.1),
508 )
509 }
510}
511impl<T: Mul + One + Copy> Mul<Vector3<T>> for Matrix3x4<T>
512where
513 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
514{
515 type Output = Vector3<<T as Mul>::Output>;
516 fn mul(self, v: Vector3<T>) -> Self::Output {
517 let v4 = v.with_w(T::ONE);
518 Vector3(
519 dotproduct4(v4.as_ref(), &self.0),
520 dotproduct4(v4.as_ref(), &self.1),
521 dotproduct4(v4.as_ref(), &self.2),
522 )
523 }
524}
525impl<T: Mul + One + Copy> Mul<Vector2<T>> for Matrix3<T>
527where
528 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
529{
530 type Output = <Matrix3<T> as Mul<Vector3<T>>>::Output;
531 fn mul(self, v: Vector2<T>) -> Self::Output {
532 self * v.with_z(T::ONE)
533 }
534}
535impl<T: Mul + One + Copy> Mul<Vector2<T>> for Matrix4<T>
536where
537 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
538{
539 type Output = <Matrix4<T> as Mul<Vector4<T>>>::Output;
540 fn mul(self, v: Vector2<T>) -> Self::Output {
541 self * v.with_z(T::ONE)
542 }
543}
544impl<T: Mul + One + Copy> Mul<Vector3<T>> for Matrix4<T>
545where
546 <T as Mul>::Output: Add<Output = <T as Mul>::Output>,
547{
548 type Output = <Matrix4<T> as Mul<Vector4<T>>>::Output;
549 fn mul(self, v: Vector3<T>) -> Self::Output {
550 self * v.with_w(T::ONE)
551 }
552}
553
554impl<T> Vector2<T>
556where
557 T: Real + Copy + Mul<T, Output = T> + Add<T, Output = T>,
558{
559 #[inline]
560 pub fn len(&self) -> T {
561 self.len2().sqrt()
562 }
563
564 #[inline]
565 pub fn normalize(&self) -> Self
566 where
567 T: Div<T, Output = T>,
568 {
569 let l0 = self.len();
570 Vector2(self.0 / l0, self.1 / l0)
571 }
572}
573impl<T> Vector3<T>
574where
575 T: Real + Copy + Mul<T, Output = T> + Add<T, Output = T>,
576{
577 #[inline]
578 pub fn len(&self) -> T {
579 self.len2().sqrt()
580 }
581
582 #[inline]
583 pub fn normalize(&self) -> Self
584 where
585 T: Div<T, Output = T>,
586 {
587 let l0 = self.len();
588 Vector3(self.0 / l0, self.1 / l0, self.2 / l0)
589 }
590}
591impl<T> Vector4<T>
592where
593 T: Real + Copy + Mul<T, Output = T> + Add<T, Output = T>,
594{
595 #[inline]
596 pub fn len(&self) -> T {
597 self.len2().sqrt()
598 }
599
600 #[inline]
601 pub fn normalize(&self) -> Self
602 where
603 T: Div<T, Output = T>,
604 {
605 let l0 = self.len();
606 Vector4(self.0 / l0, self.1 / l0, self.2 / l0, self.3 / l0)
607 }
608}
609
610impl<T> Vector2<T>
612where
613 T: Copy + Div<T, Output = T> + PartialEq + Zero,
614{
615 #[inline(always)]
616 pub fn aspect_wh(&self) -> T {
617 if self.1 == T::ZERO {
618 T::ZERO
619 } else {
620 self.0 / self.1
621 }
622 }
623
624 #[inline(always)]
625 pub fn aspect_hw(&self) -> T {
626 if self.0 == T::ZERO {
627 T::ZERO
628 } else {
629 self.1 / self.0
630 }
631 }
632}
633
634impl<T: One + Zero> One for Quaternion<T> {
636 const ONE: Self = Quaternion(T::ZERO, T::ZERO, T::ZERO, T::ONE);
637}
638
639impl<T> Quaternion<T> {
640 pub fn new(rad: T, axis: Vector3<T>) -> Self
642 where
643 T: Div<T, Output = T> + Real + One + Copy + Add<T, Output = T> + Mul<T, Output = T>,
644 {
645 let (s, c) = (rad / (T::ONE + T::ONE)).sin_cos();
646 let axis = axis.normalize();
647
648 Self(axis.0 * s, axis.1 * s, axis.2 * s, c)
649 }
650
651 pub fn lerp(&self, other: &Self, t: T) -> Self
653 where
654 T: Real
655 + Copy
656 + Mul<T, Output = T>
657 + Add<T, Output = T>
658 + Div<T, Output = T>
659 + Sub<T, Output = T>
660 + One,
661 {
662 let omg = self.angle(other);
663 let (fa, fb) = (
664 (omg * (T::ONE - t)).sin() / omg.sin(),
665 (omg * t).sin() / omg.sin(),
666 );
667
668 Self(
669 fa * self.0 + fb * other.0,
670 fa * self.1 + fb * other.1,
671 fa * self.2 + fb * other.2,
672 fa * self.3 + fb * other.3,
673 )
674 }
675
676 #[inline(always)]
678 pub fn angle(&self, other: &Self) -> T
679 where
680 T: Real + Copy + Mul<T, Output = T> + Add<T, Output = T>,
681 {
682 dotproduct4(self.as_ref(), other.as_ref()).acos()
683 }
684
685 #[inline(always)]
687 pub fn normalize(self) -> Self
688 where
689 T: Copy + Div<T, Output = T> + Mul<T, Output = T> + Add<T, Output = T> + Real,
690 {
691 let d = (self.0 * self.0 + self.1 * self.1 + self.2 * self.2 + self.3 * self.3).sqrt();
692
693 Self(self.0 / d, self.1 / d, self.2 / d, self.3 / d)
694 }
695}
696
697impl<T> Mul for Quaternion<T>
698where
699 T: Mul<T, Output = T> + Add<T, Output = T> + Sub<T, Output = T> + Copy,
700{
701 type Output = Quaternion<T>;
702
703 fn mul(self, Quaternion(x2, y2, z2, w2): Quaternion<T>) -> Self::Output {
704 let Quaternion(x1, y1, z1, w1) = self;
705
706 let x0 = w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2;
707 let y0 = w1 * y2 - x1 * z2 + y1 * w2 + z1 * x2;
708 let z0 = w1 * z2 + x1 * y2 - y1 * x2 + z1 * w2;
709 let w0 = w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2;
710
711 Quaternion(x0, y0, z0, w0)
712 }
713}
714
715impl<T: Neg<Output = T>> Neg for Quaternion<T> {
717 type Output = Quaternion<T>;
718 fn neg(self) -> Self {
719 Quaternion(-self.0, -self.1, -self.2, self.3)
720 }
721}
722
723impl<T> From<Quaternion<T>> for Matrix3<T>
724where
725 T: One + Mul<T, Output = T> + Sub<T, Output = T> + Add<T, Output = T> + Copy,
726{
727 fn from(Quaternion(x, y, z, w): Quaternion<T>) -> Self {
728 let two = T::ONE + T::ONE;
729 let m11 = T::ONE - two * y * y - two * z * z;
730 let m22 = T::ONE - two * x * x - two * z * z;
731 let m33 = T::ONE - two * x * x - two * y * y;
732 let m12 = two * (x * y + w * z);
733 let m13 = two * (x * z - w * y);
734 let m21 = two * (x * y - w * z);
735 let m23 = two * (y * z + w * x);
736 let m31 = two * (x * z + w * y);
737 let m32 = two * (y * z - w * x);
738
739 Matrix3([m11, m12, m13], [m21, m22, m23], [m31, m32, m33])
740 }
741}
742impl<T> From<Quaternion<T>> for Matrix4<T>
743where
744 T: One + Zero + Mul<T, Output = T> + Sub<T, Output = T> + Add<T, Output = T> + Copy,
745{
746 fn from(Quaternion(x, y, z, w): Quaternion<T>) -> Self {
747 let two = T::ONE + T::ONE;
748 let m11 = T::ONE - two * y * y - two * z * z;
749 let m22 = T::ONE - two * x * x - two * z * z;
750 let m33 = T::ONE - two * x * x - two * y * y;
751 let m12 = two * (x * y + w * z);
752 let m13 = two * (x * z - w * y);
753 let m21 = two * (x * y - w * z);
754 let m23 = two * (y * z + w * x);
755 let m31 = two * (x * z + w * y);
756 let m32 = two * (y * z - w * x);
757
758 Matrix4(
759 [m11, m12, m13, T::ZERO],
760 [m21, m22, m23, T::ZERO],
761 [m31, m32, m33, T::ZERO],
762 [T::ZERO, T::ZERO, T::ZERO, T::ONE],
763 )
764 }
765}
766
767macro_rules! VariadicElementOps
769{
770 (for $e: ident ($($n: tt),*)) =>
771 {
772 impl<T: Add> Add for $e<T>
773 {
774 type Output = $e<<T as Add>::Output>;
775 fn add(self, other: Self) -> Self::Output { $e($(self.$n + other.$n),*) }
776 }
777 impl<T: AddAssign> AddAssign for $e<T>
778 {
779 fn add_assign(&mut self, other: Self) { $(self.$n += other.$n);* }
780 }
781
782 impl<T: Sub> Sub for $e<T>
783 {
784 type Output = $e<<T as Sub>::Output>;
785 fn sub(self, other: Self) -> Self::Output { $e($(self.$n - other.$n),*) }
786 }
787 impl<T: SubAssign> SubAssign for $e<T>
788 {
789 fn sub_assign(&mut self, other: Self) { $(self.$n -= other.$n);* }
790 }
791
792 impl<T: Mul + Copy> Mul<T> for $e<T>
793 {
794 type Output = $e<<T as Mul>::Output>;
795 fn mul(self, other: T) -> Self::Output { $e($(self.$n * other),*) }
796 }
797 impl<T: MulAssign + Copy> MulAssign<T> for $e<T>
798 {
799 fn mul_assign(&mut self, other: T) { $(self.$n *= other);* }
800 }
801
802 impl<T: Neg> Neg for $e<T>
803 {
804 type Output = $e<<T as Neg>::Output>;
805 fn neg(self) -> Self::Output { $e($(-self.$n),*) }
806 }
807
808 impl<T: Mul<Output = T> + Add<Output = T> + Copy> $e<T>
809 {
810 pub fn dot(self, other: Self) -> T
812 {
813 CTSummation!($(self.$n * other.$n),*)
814 }
815 }
816 impl<T: Mul<Output = T> + Add<Output = T> + Copy> $e<T>
817 {
818 pub fn len2(self) -> T
820 {
821 CTSummation!($(self.$n * self.$n),*)
822 }
823 }
824
825 impl<T> $e<T> {
826 pub fn min(self, other: Self) -> Self where T: crate::numtraits::Min<Output = T> {
828 $e($(self.$n.min(other.$n)),*)
829 }
830 pub fn max(self, other: Self) -> Self where T: crate::numtraits::Max<Output = T> {
832 $e($(self.$n.max(other.$n)),*)
833 }
834 }
835 }
836}
837macro_rules! CTSummation
838{
839 ($e: expr, $($e2: expr),+) => { $e $(.add($e2))* }
840}
841VariadicElementOps!(for Vector2 (0, 1));
842VariadicElementOps!(for Vector3 (0, 1, 2));
843VariadicElementOps!(for Vector4 (0, 1, 2, 3));
844
845impl<T> Vector2<T>
846where
847 T: Mul<Output = T> + Sub<Output = T> + Copy,
848{
849 pub fn cross(&self, other: &Self) -> T {
851 self.0 * other.1 - self.1 * other.0
852 }
853}
854impl<T> Vector3<T>
855where
856 T: Mul<T, Output = T> + Sub<T, Output = T> + Copy,
857{
858 pub fn cross(&self, other: &Self) -> Self {
860 let x = self.1 * other.2 - self.2 * other.1;
861 let y = self.2 * other.0 - self.0 * other.2;
862 let z = self.0 * other.1 - self.1 * other.0;
863
864 Vector3(x, y, z)
865 }
866}
867
868#[cfg(feature = "bedrock-interop")]
870mod bedrock_interop;
871#[cfg(feature = "euclid-interop")]
872mod euclid_interop;
873
874#[cfg(test)]
875mod tests {
876 use super::*;
877
878 #[test]
879 fn vector_dimension_transform() {
880 assert_eq!(Vector2(2, 3).with_z(1), Vector3(2, 3, 1));
881 assert_eq!(
882 Vector3(2.5, 3.0, 4.1).with_w(1.0),
883 Vector4(2.5, 3.0, 4.1, 1.0)
884 );
885 assert_eq!(Vector3::from(Vector4(4, 6, 8, 2)), Vector3(2, 3, 4));
886 }
887 #[test]
888 fn matrix_multiplication_identity() {
889 assert_eq!(Matrix3::ONE * Vector3(1, 2, 3), Vector3(1, 2, 3));
890 assert_eq!(
891 Matrix2::ONE * Matrix2::scale(Vector2(2, 3)),
892 Matrix2::scale(Vector2(2, 3))
893 );
894 assert_eq!(
895 Matrix3::ONE * Matrix3::scale(Vector3(2, 3, 4)),
896 Matrix3::scale(Vector3(2, 3, 4))
897 );
898 assert_eq!(
899 Matrix4::ONE * Matrix4::scale(Vector4(2, 3, 4, 5)),
900 Matrix4::scale(Vector4(2, 3, 4, 5))
901 );
902 }
903 #[test]
904 fn matrix_transforming() {
905 assert_eq!(
906 Matrix3([1, 0, 2], [0, 1, 3], [0, 0, 1]) * Vector2(0, 0),
907 Vector3(2, 3, 1)
908 );
909 assert_eq!(
910 Matrix4([1, 0, 0, 2], [0, 1, 0, 3], [0, 0, 1, 4], [0, 0, 0, 1]) * Vector3(1, 2, 3),
911 Vector4(3, 5, 7, 1)
912 );
913 assert_eq!(Matrix2::scale(Vector2(2, 3)) * Vector2(1, 1), Vector2(2, 3));
914 }
915 #[test]
916 fn matrix_extension() {
917 assert_eq!(
918 Matrix3::from(Matrix2([0, 1], [1, 0])),
919 Matrix3([0, 1, 0], [1, 0, 0], [0, 0, 1])
920 );
921 assert_eq!(
922 Matrix4::from(Matrix3::from(Matrix2([0, 1], [2, 3]))),
923 Matrix4([0, 1, 0, 0], [2, 3, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
924 );
925 }
926 #[test]
927 #[allow(clippy::no_effect)]
928 fn vector_ops() {
929 assert_eq!(Vector3(0, 1, 2) + Vector3(3, 4, 5), Vector3(3, 5, 7));
930 assert_eq!(Vector3(6, 7, 8) - Vector3(3, 4, 5), Vector3(3, 3, 3));
931 assert_eq!(Vector3(0, 2, 4) * 3, Vector3(0, 6, 12));
932 assert_eq!(-Vector3(1, 2, -1), Vector3(-1, -2, 1));
933 assert_eq!(
934 Vector3(2, 3, 4).dot(Vector3(5, 6, 7)),
935 2 * 5 + 3 * 6 + 4 * 7
936 );
937 assert_eq!(Vector2(0, 1).dot(Vector2(1, 0)), 0);
938 #[allow(clippy::identity_op)]
939 {
940 assert_eq!(Vector3(1, 2, 3).len2(), 1 * 1 + 2 * 2 + 3 * 3);
941 }
942 assert_eq!(Vector2(10, 3).cross(&Vector2(4, 30)), 10 * 30 - 3 * 4);
943 assert_eq!(
944 Vector3(2, 3, 4).cross(&Vector3(6, 7, 8)),
945 Vector3(3 * 8 - 4 * 7, 4 * 6 - 2 * 8, 2 * 7 - 6 * 3)
946 );
947 }
948 #[test]
949 fn inv_quaternion() {
950 let q = Quaternion(0.0f32, 1.0, 0.0, 3.0).normalize();
951 let Quaternion(a, b, c, d) = q * -q;
952 assert!(a.abs() <= f32::EPSILON);
954 assert!(b.abs() <= f32::EPSILON);
955 assert!(c.abs() <= f32::EPSILON);
956 assert!((1.0 - d).abs() <= f32::EPSILON);
957 }
958 #[test]
959 fn vector_ops_assign() {
960 let mut v1 = Vector3(0, 1, 2);
961 v1 += Vector3(1, -3, 2);
962 assert_eq!(v1, Vector3(0, 1, 2) + Vector3(1, -3, 2));
963 v1 -= Vector3(1, -3, 2);
964 assert_eq!(v1, Vector3(0, 1, 2) + Vector3(1, -3, 2) - Vector3(1, -3, 2));
965 v1 *= 4;
966 assert_eq!(
967 v1,
968 (Vector3(0, 1, 2) + Vector3(1, -3, 2) - Vector3(1, -3, 2)) * 4
969 );
970 }
971}