mini_math/
operators.rs

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} });