1use crate::{Matrix4, Point, Vector2, Vector3, Vector4};
2
3impl std::ops::Mul<&Matrix4> for Matrix4 {
4 type Output = Self;
5
6 fn mul(self, rhs: &Matrix4) -> Self {
7 self * *rhs
8 }
9}
10
11impl std::ops::Mul for Matrix4 {
12 type Output = Self;
13
14 fn mul(self, rhs: Self) -> Self {
15 let mut result = Self::zero();
16
17 for i in 0..4 {
18 for j in 0..4 {
19 result.0[i][j] = rhs.0[i][0] * self.0[0][j]
20 + rhs.0[i][1] * self.0[1][j]
21 + rhs.0[i][2] * self.0[2][j]
22 + rhs.0[i][3] * self.0[3][j];
23 }
24 }
25
26 result
27 }
28}
29
30impl std::ops::Mul<Point> for Matrix4 {
31 type Output = Point;
32
33 fn mul(self, rhs: Point) -> Point {
34 Point::new(
35 self.0[0][0] * rhs.x + self.0[1][0] * rhs.y + self.0[2][0] * rhs.z + self.0[3][0],
36 self.0[0][1] * rhs.x + self.0[1][1] * rhs.y + self.0[2][1] * rhs.z + self.0[3][1],
37 self.0[0][2] * rhs.x + self.0[1][2] * rhs.y + self.0[2][2] * rhs.z + self.0[3][2],
38 )
39 }
40}
41
42impl std::ops::Mul<Vector3> for Matrix4 {
43 type Output = Vector3;
44
45 fn mul(self, rhs: Vector3) -> Vector3 {
46 Vector3::new(
47 self.0[0][0] * rhs.x + self.0[1][0] * rhs.y + self.0[2][0] * rhs.z,
48 self.0[0][1] * rhs.x + self.0[1][1] * rhs.y + self.0[2][1] * rhs.z,
49 self.0[0][2] * rhs.x + self.0[1][2] * rhs.y + self.0[2][2] * rhs.z,
50 )
51 }
52}
53
54impl std::ops::Mul<Vector4> for Matrix4 {
55 type Output = Vector4;
56
57 fn mul(self, rhs: Vector4) -> Vector4 {
58 Vector4::new(
59 self.row(0).dot(rhs),
60 self.row(1).dot(rhs),
61 self.row(2).dot(rhs),
62 self.row(3).dot(rhs),
63 )
64 }
65}
66
67impl std::ops::Mul<Matrix4> for Point {
68 type Output = Point;
69
70 fn mul(self, rhs: Matrix4) -> Point {
71 Point::new(
72 Vector3::from_scalar(self.x).dot(Vector3::from(rhs.column(0))),
73 Vector3::from_scalar(self.y).dot(Vector3::from(rhs.column(1))),
74 Vector3::from_scalar(self.z).dot(Vector3::from(rhs.column(2))),
75 )
76 }
77}
78
79impl std::ops::Mul<Matrix4> for Vector3 {
80 type Output = Vector3;
81
82 fn mul(self, rhs: Matrix4) -> Vector3 {
83 Vector3::new(
84 Vector3::from_scalar(self.x).dot(Vector3::from(rhs.column(0))),
85 Vector3::from_scalar(self.y).dot(Vector3::from(rhs.column(1))),
86 Vector3::from_scalar(self.z).dot(Vector3::from(rhs.column(2))),
87 )
88 }
89}
90
91impl std::ops::Mul<Matrix4> for Vector4 {
92 type Output = Vector4;
93
94 fn mul(self, rhs: Matrix4) -> Vector4 {
95 Vector4::new(
96 Vector4::from_scalar(self.x).dot(rhs.column(0)),
97 Vector4::from_scalar(self.y).dot(rhs.column(1)),
98 Vector4::from_scalar(self.z).dot(rhs.column(2)),
99 Vector4::from_scalar(self.w).dot(rhs.column(3)),
100 )
101 }
102}
103
104macro_rules! vector_op {
105 (impl $trait:ident<$other_type: ty> for $type:ty {
106 fn $op_fn:ident -> $result_type:ty, $op:tt { $($field:ident),+ }
107 }) => {
108 impl std::ops::$trait<$other_type> for $type {
109 type Output = $result_type;
110
111 fn $op_fn(self, rhs: $other_type) -> $result_type {
112 <$result_type>::new($(self.$field $op rhs.$field),+)
113 }
114 }
115 };
116}
117
118macro_rules! vector_assign_op {
119 (impl $trait:ident<$other_type: ty> for $type:ty {
120 fn $op_fn:ident, $op:tt { $($field:ident),+ }
121 }) => {
122 impl std::ops::$trait<$other_type> for $type {
123 fn $op_fn(&mut self, rhs: $other_type) {
124 $(self.$field $op rhs.$field);+
125 }
126 }
127 };
128}
129
130vector_op!(impl Add<Vector2> for Vector2 { fn add -> Vector2, + {x, y} });
131vector_op!(impl Sub<Vector2> for Vector2 { fn sub -> Vector2, - {x, y} });
132vector_op!(impl Mul<Vector2> for Vector2 { fn mul -> Vector2, * {x, y} });
133vector_op!(impl Div<Vector2> for Vector2 { fn div -> Vector2, / {x, y} });
134vector_assign_op!(impl AddAssign<Vector2> for Vector2 { fn add_assign, += {x, y} });
135vector_assign_op!(impl SubAssign<Vector2> for Vector2 { fn sub_assign, -= {x, y} });
136vector_assign_op!(impl MulAssign<Vector2> for Vector2 { fn mul_assign, *= {x, y} });
137vector_assign_op!(impl DivAssign<Vector2> for Vector2 { fn div_assign, /= {x, y} });
138
139vector_op!(impl Add<Vector3> for Vector3 { fn add -> Vector3, + {x, y, z} });
140vector_op!(impl Sub<Vector3> for Vector3 { fn sub -> Vector3, - {x, y, z} });
141vector_op!(impl Mul<Vector3> for Vector3 { fn mul -> Vector3, * {x, y, z} });
142vector_op!(impl Div<Vector3> for Vector3 { fn div -> Vector3, / {x, y, z} });
143vector_assign_op!(impl AddAssign<Vector3> for Vector3 { fn add_assign, += {x, y, z} });
144vector_assign_op!(impl SubAssign<Vector3> for Vector3 { fn sub_assign, -= {x, y, z} });
145vector_assign_op!(impl MulAssign<Vector3> for Vector3 { fn mul_assign, *= {x, y, z} });
146vector_assign_op!(impl DivAssign<Vector3> for Vector3 { fn div_assign, /= {x, y, z} });
147
148vector_op!(impl Add<Vector4> for Vector4 { fn add -> Vector4, + {x, y, z, w} });
149vector_op!(impl Sub<Vector4> for Vector4 { fn sub -> Vector4, - {x, y, z, w} });
150vector_op!(impl Mul<Vector4> for Vector4 { fn mul -> Vector4, * {x, y, z, w} });
151vector_op!(impl Div<Vector4> for Vector4 { fn div -> Vector4, / {x, y, z, w} });
152vector_assign_op!(impl AddAssign<Vector4> for Vector4 { fn add_assign, += {x, y, z, w} });
153vector_assign_op!(impl SubAssign<Vector4> for Vector4 { fn sub_assign, -= {x, y, z, w} });
154vector_assign_op!(impl MulAssign<Vector4> for Vector4 { fn mul_assign, *= {x, y, z, w} });
155vector_assign_op!(impl DivAssign<Vector4> for Vector4 { fn div_assign, /= {x, y, z, w} });
156
157vector_op!(impl Add<Vector3> for Point { fn add -> Point, + {x, y, z} });
158vector_op!(impl Sub<Vector3> for Point { fn sub -> Point, - {x, y, z} });
159vector_op!(impl Sub<Point> for Point { fn sub -> Vector3, - {x, y, z} });
160vector_assign_op!(impl AddAssign<Vector3> for Point { fn add_assign, += {x, y, z} });
161vector_assign_op!(impl SubAssign<Vector3> for Point { fn sub_assign, -= {x, y, z} });