diff --git a/src/matrix.rs b/src/matrix.rs index bc34d41..567ffd6 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -909,7 +909,7 @@ macro_rules! impl_binary_operator { #[inline] fn $binop(self, other: &'a $MatrixN) -> $MatrixN { - $MatrixN { $($field: self.$field.$binop(&other.$field)),+ } + $MatrixN { $($field: self.$field.$binop(other.$field)),+ } } } } @@ -922,35 +922,29 @@ impl_binary_operator!(Sub::sub, Matrix2 { x, y }); impl_binary_operator!(Sub::sub, Matrix3 { x, y, z }); impl_binary_operator!(Sub::sub, Matrix4 { x, y, z, w }); -impl<'a, 'b, S: BaseNum> Mul<&'a Vector2> for &'b Matrix2 { - type Output = Vector2; +macro_rules! impl_vector_mul_operators { + ($MatrixN:ident, $VectorN:ident { $($row_index:expr),+ }) => { + impl<'a, S: BaseNum> Mul<$VectorN> for &'a $MatrixN { + type Output = $VectorN; - fn mul(self, v: &'a Vector2) -> Vector2 { - Vector2::new(self.row(0).dot(v), - self.row(1).dot(v)) + fn mul(self, v: $VectorN) -> $VectorN { + $VectorN::new($(self.row($row_index).dot(&v)),+) + } + } + + impl<'a, 'b, S: BaseNum> Mul<&'a $VectorN> for &'b $MatrixN { + type Output = $VectorN; + + fn mul(self, v: &'a $VectorN) -> $VectorN { + $VectorN::new($(self.row($row_index).dot(v)),+) + } + } } } -impl<'a, 'b, S: BaseNum> Mul<&'a Vector3> for &'b Matrix3 { - type Output = Vector3; - - fn mul(self, v: &'a Vector3) -> Vector3 { - Vector3::new(self.row(0).dot(v), - self.row(1).dot(v), - self.row(2).dot(v)) - } -} - -impl<'a, 'b, S: BaseNum> Mul<&'a Vector4> for &'b Matrix4 { - type Output = Vector4; - - fn mul(self, v: &'a Vector4) -> Vector4 { - Vector4::new(self.row(0).dot(v), - self.row(1).dot(v), - self.row(2).dot(v), - self.row(3).dot(v)) - } -} +impl_vector_mul_operators!(Matrix2, Vector2 { 0, 1 }); +impl_vector_mul_operators!(Matrix3, Vector3 { 0, 1, 2 }); +impl_vector_mul_operators!(Matrix4, Vector4 { 0, 1, 2, 3 }); impl<'a, 'b, S: BaseNum> Mul<&'a Matrix2> for &'b Matrix2 { type Output = Matrix2; diff --git a/src/point.rs b/src/point.rs index c2d0568..dfa50e4 100644 --- a/src/point.rs +++ b/src/point.rs @@ -55,7 +55,7 @@ impl Point3 { impl Point3 { #[inline] pub fn from_homogeneous(v: &Vector4) -> Point3 { - let e = v.truncate().mul_s(S::one() / v.w); + let e = v.truncate() * (S::one() / v.w); Point3::new(e.x, e.y, e.z) //FIXME } @@ -299,6 +299,33 @@ impl ApproxEq for Point3 { macro_rules! impl_operators { ($PointN:ident { $($field:ident),+ }, $VectorN:ident) => { + impl Mul for $PointN { + type Output = $PointN; + + #[inline] + fn mul(self, scalar: S) -> $PointN { + $PointN::new($(self.$field * scalar),+) + } + } + + impl Div for $PointN { + type Output = $PointN; + + #[inline] + fn div(self, scalar: S) -> $PointN { + $PointN::new($(self.$field / scalar),+) + } + } + + impl Rem for $PointN { + type Output = $PointN; + + #[inline] + fn rem(self, scalar: S) -> $PointN { + $PointN::new($(self.$field % scalar),+) + } + } + impl<'a, S: BaseNum> Mul for &'a $PointN { type Output = $PointN; @@ -326,6 +353,60 @@ macro_rules! impl_operators { } } + impl Add<$VectorN> for $PointN { + type Output = $PointN; + + #[inline] + fn add(self, v: $VectorN) -> $PointN { + $PointN::new($(self.$field + v.$field),+) + } + } + + impl Sub<$PointN> for $PointN { + type Output = $VectorN; + + #[inline] + fn sub(self, p: $PointN) -> $VectorN { + $VectorN::new($(self.$field - p.$field),+) + } + } + + impl<'a, S: BaseNum> Add<&'a $VectorN> for $PointN { + type Output = $PointN; + + #[inline] + fn add(self, v: &'a $VectorN) -> $PointN { + $PointN::new($(self.$field + v.$field),+) + } + } + + impl<'a, S: BaseNum> Sub<&'a $PointN> for $PointN { + type Output = $VectorN; + + #[inline] + fn sub(self, p: &'a $PointN) -> $VectorN { + $VectorN::new($(self.$field - p.$field),+) + } + } + + impl<'a, S: BaseNum> Add<$VectorN> for &'a $PointN { + type Output = $PointN; + + #[inline] + fn add(self, v: $VectorN) -> $PointN { + $PointN::new($(self.$field + v.$field),+) + } + } + + impl<'a, S: BaseNum> Sub<$PointN> for &'a $PointN { + type Output = $VectorN; + + #[inline] + fn sub(self, p: $PointN) -> $VectorN { + $VectorN::new($(self.$field - p.$field),+) + } + } + impl<'a, 'b, S: BaseNum> Add<&'a $VectorN> for &'b $PointN { type Output = $PointN; diff --git a/src/quaternion.rs b/src/quaternion.rs index b40799f..ec10c4b 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -114,12 +114,30 @@ impl Quaternion { } } +impl Mul for Quaternion { + type Output = Quaternion; + + #[inline] + fn mul(self, value: S) -> Quaternion { + Quaternion::from_sv(self.s * value, self.v * value) + } +} + impl<'a, S: BaseFloat> Mul for &'a Quaternion { type Output = Quaternion; #[inline] fn mul(self, value: S) -> Quaternion { - Quaternion::from_sv(self.s * value, &self.v * value) + Quaternion::from_sv(self.s * value, self.v * value) + } +} + +impl Div for Quaternion { + type Output = Quaternion; + + #[inline] + fn div(self, value: S) -> Quaternion { + Quaternion::from_sv(self.s / value, self.v / value) } } @@ -128,7 +146,7 @@ impl<'a, S: BaseFloat> Div for &'a Quaternion { #[inline] fn div(self, value: S) -> Quaternion { - Quaternion::from_sv(self.s / value, &self.v / value) + Quaternion::from_sv(self.s / value, self.v / value) } } @@ -137,8 +155,9 @@ impl<'a, 'b, S: BaseFloat> Mul<&'b Vector3> for &'a Quaternion { #[inline] fn mul(self, vec: &'b Vector3) -> Vector3 { - let tmp = self.v.cross(vec).add_v(&vec.mul_s(self.s.clone())); - self.v.cross(&tmp).mul_s(cast(2i8).unwrap()).add_v(vec) + let two: S = cast(2i8).unwrap(); + let tmp = self.v.cross(vec) + (vec * self.s); + (self.v.cross(&tmp) * two) + vec } } @@ -147,7 +166,7 @@ impl<'a, 'b, S: BaseFloat> Add<&'b Quaternion> for &'a Quaternion { #[inline] fn add(self, other: &'b Quaternion) -> Quaternion { - Quaternion::from_sv(self.s + other.s, &self.v + &other.v) + Quaternion::from_sv(self.s + other.s, self.v + &other.v) } } @@ -156,7 +175,7 @@ impl<'a, 'b, S: BaseFloat> Sub<&'b Quaternion> for &'a Quaternion { #[inline] fn sub(self, other: &'b Quaternion) -> Quaternion { - Quaternion::from_sv(self.s - other.s, &self.v - &other.v) + Quaternion::from_sv(self.s - other.s, self.v - &other.v) } } diff --git a/src/transform.rs b/src/transform.rs index a1583ab..00bef7f 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -142,7 +142,7 @@ pub trait Transform3: Transform> + Into> {} impl> From, R>> for Matrix3 { fn from(dec: Decomposed, R>) -> Matrix3 { let m: Matrix2<_> = dec.rot.into(); - let mut m: Matrix3<_> = m.mul_s(dec.scale).into(); + let mut m: Matrix3<_> = (&m * dec.scale).into(); m.z = dec.disp.extend(S::one()); m } @@ -151,7 +151,7 @@ impl> From, R>> for Matrix3< impl> From, R>> for Matrix4 { fn from(dec: Decomposed, R>) -> Matrix4 { let m: Matrix3<_> = dec.rot.into(); - let mut m: Matrix4<_> = m.mul_s(dec.scale).into(); + let mut m: Matrix4<_> = (&m * dec.scale).into(); m.w = dec.disp.extend(S::one()); m } diff --git a/src/vector.rs b/src/vector.rs index 2b11b16..f1886af 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -316,12 +316,48 @@ macro_rules! vec { macro_rules! impl_binary_operator { ($Binop:ident :: $binop:ident, $VectorN:ident { $($field:ident),+ }) => { + impl $Binop for $VectorN { + type Output = $VectorN; + + #[inline] + fn $binop(self, scalar: S) -> $VectorN { + $VectorN::new($(self.$field.$binop(scalar)),+) + } + } + impl<'a, S: BaseNum> $Binop for &'a $VectorN { type Output = $VectorN; #[inline] - fn $binop(self, s: S) -> $VectorN { - $VectorN::new($(self.$field.$binop(s)),+) + fn $binop(self, scalar: S) -> $VectorN { + $VectorN::new($(self.$field.$binop(scalar)),+) + } + } + + impl $Binop<$VectorN> for $VectorN { + type Output = $VectorN; + + #[inline] + fn $binop(self, other: $VectorN) -> $VectorN { + $VectorN::new($(self.$field.$binop(other.$field)),+) + } + } + + impl<'a, S: BaseNum> $Binop<&'a $VectorN> for $VectorN { + type Output = $VectorN; + + #[inline] + fn $binop(self, other: &'a $VectorN) -> $VectorN { + $VectorN::new($(self.$field.$binop(other.$field)),+) + } + } + + impl<'a, S: BaseNum> $Binop<$VectorN> for &'a $VectorN { + type Output = $VectorN; + + #[inline] + fn $binop(self, other: $VectorN) -> $VectorN { + $VectorN::new($(self.$field.$binop(other.$field)),+) } }