diff --git a/src/matrix.rs b/src/matrix.rs index 3ea5a56..85bd3ac 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -1326,53 +1326,35 @@ impl ApproxEq for Matrix4 { // Conversion traits -/// Represents types which can be converted to a Matrix2 -pub trait ToMatrix2 { - /// Convert this value to a Matrix2 - fn to_matrix2(&self) -> Matrix2; -} - -/// Represents types which can be converted to a Matrix3 -pub trait ToMatrix3 { - /// Convert this value to a Matrix3 - fn to_matrix3(&self) -> Matrix3; -} - -/// Represents types which can be converted to a Matrix4 -pub trait ToMatrix4 { - /// Convert this value to a Matrix4 - fn to_matrix4(&self) -> Matrix4; -} - -impl ToMatrix3 for Matrix2 { +impl From> for Matrix3 { /// Clone the elements of a 2-dimensional matrix into the top-left corner /// of a 3-dimensional identity matrix. - fn to_matrix3(&self) -> Matrix3 { - Matrix3::new(self[0][0], self[0][1], zero(), - self[1][0], self[1][1], zero(), - zero(), zero(), one()) + fn from(m: Matrix2) -> Matrix3 { + Matrix3::new(m[0][0], m[0][1], zero(), + m[1][0], m[1][1], zero(), + zero(), zero(), one()) } } -impl ToMatrix4 for Matrix2 { +impl From> for Matrix4 { /// Clone the elements of a 2-dimensional matrix into the top-left corner /// of a 4-dimensional identity matrix. - fn to_matrix4(&self) -> Matrix4 { - Matrix4::new(self[0][0], self[0][1], zero(), zero(), - self[1][0], self[1][1], zero(), zero(), - zero(), zero(), one(), zero(), - zero(), zero(), zero(), one()) + fn from(m: Matrix2) -> Matrix4 { + Matrix4::new(m[0][0], m[0][1], zero(), zero(), + m[1][0], m[1][1], zero(), zero(), + zero(), zero(), one(), zero(), + zero(), zero(), zero(), one()) } } -impl ToMatrix4 for Matrix3 { +impl From> for Matrix4 { /// Clone the elements of a 3-dimensional matrix into the top-left corner /// of a 4-dimensional identity matrix. - fn to_matrix4(&self) -> Matrix4 { - Matrix4::new(self[0][0], self[0][1], self[0][2], zero(), - self[1][0], self[1][1], self[1][2], zero(), - self[2][0], self[2][1], self[2][2], zero(), - zero(), zero(), zero(), one()) + fn from(m: Matrix3) -> Matrix4 { + Matrix4::new(m[0][0], m[0][1], m[0][2], zero(), + m[1][0], m[1][1], m[1][2], zero(), + m[2][0], m[2][1], m[2][2], zero(), + zero(), zero(), zero(), one()) } } diff --git a/src/projection.rs b/src/projection.rs index 90a9f31..507db02 100644 --- a/src/projection.rs +++ b/src/projection.rs @@ -18,7 +18,7 @@ use rust_num::traits::cast; use angle::{Angle, Rad, tan, cot}; use frustum::Frustum; -use matrix::{Matrix4, ToMatrix4}; +use matrix::Matrix4; use num::BaseFloat; use plane::Plane; @@ -32,7 +32,7 @@ pub fn perspective>(fovy: A, aspect: S, near aspect: aspect, near: near, far: far, - }.to_matrix4() + }.into() } /// Create a perspective matrix from a view frustrum. @@ -47,7 +47,7 @@ pub fn frustum(left: S, right: S, bottom: S, top: S, nea top: top, near: near, far: far, - }.to_matrix4() + }.into() } /// Create an orthographic projection matrix. @@ -62,10 +62,10 @@ pub fn ortho(left: S, right: S, bottom: S, top: S, near: top: top, near: near, far: far, - }.to_matrix4() + }.into() } -pub trait Projection: ToMatrix4 { +pub trait Projection: Into> { fn to_frustum(&self) -> Frustum; } @@ -99,26 +99,26 @@ impl> PerspectiveFov { impl> Projection for PerspectiveFov { fn to_frustum(&self) -> Frustum { // TODO: Could this be faster? - Frustum::from_matrix4(self.to_matrix4()).unwrap() + Frustum::from_matrix4(self.clone().into()).unwrap() } } -impl> ToMatrix4 for PerspectiveFov { - fn to_matrix4(&self) -> Matrix4 { +impl> From> for Matrix4 { + fn from(persp: PerspectiveFov) -> Matrix4 { let half_turn: A = Angle::turn_div_2(); - assert!(self.fovy > zero(), "The vertical field of view cannot be below zero, found: {:?}", self.fovy); - assert!(self.fovy < half_turn, "The vertical field of view cannot be greater than a half turn, found: {:?}", self.fovy); - assert!(self.aspect > zero(), "The aspect ratio cannot be below zero, found: {:?}", self.aspect); - assert!(self.near > zero(), "The near plane distance cannot be below zero, found: {:?}", self.near); - assert!(self.far > zero(), "The far plane distance cannot be below zero, found: {:?}", self.far); - assert!(self.far > self.near, "The far plane cannot be closer than the near plane, found: far: {:?}, near: {:?}", self.far, self.near); + assert!(persp.fovy > zero(), "The vertical field of view cannot be below zero, found: {:?}", persp.fovy); + assert!(persp.fovy < half_turn, "The vertical field of view cannot be greater than a half turn, found: {:?}", persp.fovy); + assert!(persp.aspect > zero(), "The aspect ratio cannot be below zero, found: {:?}", persp.aspect); + assert!(persp.near > zero(), "The near plane distance cannot be below zero, found: {:?}", persp.near); + assert!(persp.far > zero(), "The far plane distance cannot be below zero, found: {:?}", persp.far); + assert!(persp.far > persp.near, "The far plane cannot be closer than the near plane, found: far: {:?}, near: {:?}", persp.far, persp.near); - let f: Rad<_> = self.fovy.div_s(cast(2i8).unwrap()).into(); + let f: Rad<_> = persp.fovy.div_s(cast(2i8).unwrap()).into(); let f = cot(f); let two: S = cast(2i8).unwrap(); - let c0r0 = f / self.aspect; + let c0r0 = f / persp.aspect; let c0r1 = zero(); let c0r2 = zero(); let c0r3 = zero(); @@ -130,12 +130,12 @@ impl> ToMatrix4 for PerspectiveFov { let c2r0 = zero(); let c2r1 = zero(); - let c2r2 = (self.far + self.near) / (self.near - self.far); + let c2r2 = (persp.far + persp.near) / (persp.near - persp.far); let c2r3 = -one::(); let c3r0 = zero(); let c3r1 = zero(); - let c3r2 = (two * self.far * self.near) / (self.near - self.far); + let c3r2 = (two * persp.far * persp.near) / (persp.near - persp.far); let c3r3 = zero(); Matrix4::new(c0r0, c0r1, c0r2, c0r3, @@ -159,36 +159,36 @@ pub struct Perspective { impl Projection for Perspective { fn to_frustum(&self) -> Frustum { // TODO: Could this be faster? - Frustum::from_matrix4(self.to_matrix4()).unwrap() + Frustum::from_matrix4(self.clone().into()).unwrap() } } -impl ToMatrix4 for Perspective { - fn to_matrix4(&self) -> Matrix4 { - assert!(self.left <= self.right, "`left` cannot be greater than `right`, found: left: {:?} right: {:?}", self.left, self.right); - assert!(self.bottom <= self.top, "`bottom` cannot be greater than `top`, found: bottom: {:?} top: {:?}", self.bottom, self.top); - assert!(self.near <= self.far, "`near` cannot be greater than `far`, found: near: {:?} far: {:?}", self.near, self.far); +impl From> for Matrix4 { + fn from(persp: Perspective) -> Matrix4 { + assert!(persp.left <= persp.right, "`left` cannot be greater than `right`, found: left: {:?} right: {:?}", persp.left, persp.right); + assert!(persp.bottom <= persp.top, "`bottom` cannot be greater than `top`, found: bottom: {:?} top: {:?}", persp.bottom, persp.top); + assert!(persp.near <= persp.far, "`near` cannot be greater than `far`, found: near: {:?} far: {:?}", persp.near, persp.far); let two: S = cast(2i8).unwrap(); - let c0r0 = (two * self.near) / (self.right - self.left); + let c0r0 = (two * persp.near) / (persp.right - persp.left); let c0r1 = zero(); let c0r2 = zero(); let c0r3 = zero(); let c1r0 = zero(); - let c1r1 = (two * self.near) / (self.top - self.bottom); + let c1r1 = (two * persp.near) / (persp.top - persp.bottom); let c1r2 = zero(); let c1r3 = zero(); - let c2r0 = (self.right + self.left) / (self.right - self.left); - let c2r1 = (self.top + self.bottom) / (self.top - self.bottom); - let c2r2 = -(self.far + self.near) / (self.far - self.near); + let c2r0 = (persp.right + persp.left) / (persp.right - persp.left); + let c2r1 = (persp.top + persp.bottom) / (persp.top - persp.bottom); + let c2r2 = -(persp.far + persp.near) / (persp.far - persp.near); let c2r3 = -one::(); let c3r0 = zero(); let c3r1 = zero(); - let c3r2 = -(two * self.far * self.near) / (self.far - self.near); + let c3r2 = -(two * persp.far * persp.near) / (persp.far - persp.near); let c3r3 = zero(); Matrix4::new(c0r0, c0r1, c0r2, c0r3, @@ -222,28 +222,28 @@ impl Projection for Ortho { } } -impl ToMatrix4 for Ortho { - fn to_matrix4(&self) -> Matrix4 { +impl From> for Matrix4 { + fn from(ortho: Ortho) -> Matrix4 { let two: S = cast(2i8).unwrap(); - let c0r0 = two / (self.right - self.left); + let c0r0 = two / (ortho.right - ortho.left); let c0r1 = zero(); let c0r2 = zero(); let c0r3 = zero(); let c1r0 = zero(); - let c1r1 = two / (self.top - self.bottom); + let c1r1 = two / (ortho.top - ortho.bottom); let c1r2 = zero(); let c1r3 = zero(); let c2r0 = zero(); let c2r1 = zero(); - let c2r2 = -two / (self.far - self.near); + let c2r2 = -two / (ortho.far - ortho.near); let c2r3 = zero(); - let c3r0 = -(self.right + self.left) / (self.right - self.left); - let c3r1 = -(self.top + self.bottom) / (self.top - self.bottom); - let c3r2 = -(self.far + self.near) / (self.far - self.near); + let c3r0 = -(ortho.right + ortho.left) / (ortho.right - ortho.left); + let c3r1 = -(ortho.top + ortho.bottom) / (ortho.top - ortho.bottom); + let c3r2 = -(ortho.far + ortho.near) / (ortho.far - ortho.near); let c3r3 = one::(); Matrix4::new(c0r0, c0r1, c0r2, c0r3, diff --git a/src/quaternion.rs b/src/quaternion.rs index f023efe..8ab4b17 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -25,7 +25,7 @@ use rust_num::traits::cast; use angle::{Angle, Rad, acos, sin, sin_cos, rad}; use approx::ApproxEq; use array::Array1; -use matrix::{Matrix3, ToMatrix3, ToMatrix4, Matrix4}; +use matrix::{Matrix3, Matrix4}; use num::BaseFloat; use point::Point3; use rotation::{Rotation, Rotation3, Basis3, ToBasis3}; @@ -310,24 +310,24 @@ impl Quaternion { } } -impl ToMatrix3 for Quaternion { +impl From> for Matrix3 { /// Convert the quaternion to a 3 x 3 rotation matrix - fn to_matrix3(&self) -> Matrix3 { - let x2 = self.v.x + self.v.x; - let y2 = self.v.y + self.v.y; - let z2 = self.v.z + self.v.z; + fn from(quat: Quaternion) -> Matrix3 { + let x2 = quat.v.x + quat.v.x; + let y2 = quat.v.y + quat.v.y; + let z2 = quat.v.z + quat.v.z; - let xx2 = x2 * self.v.x; - let xy2 = x2 * self.v.y; - let xz2 = x2 * self.v.z; + let xx2 = x2 * quat.v.x; + let xy2 = x2 * quat.v.y; + let xz2 = x2 * quat.v.z; - let yy2 = y2 * self.v.y; - let yz2 = y2 * self.v.z; - let zz2 = z2 * self.v.z; + let yy2 = y2 * quat.v.y; + let yz2 = y2 * quat.v.z; + let zz2 = z2 * quat.v.z; - let sy2 = y2 * self.s; - let sz2 = z2 * self.s; - let sx2 = x2 * self.s; + let sy2 = y2 * quat.s; + let sz2 = z2 * quat.s; + let sx2 = x2 * quat.s; Matrix3::new(one::() - yy2 - zz2, xy2 + sz2, xz2 - sy2, xy2 - sz2, one::() - xx2 - zz2, yz2 + sx2, @@ -335,24 +335,24 @@ impl ToMatrix3 for Quaternion { } } -impl ToMatrix4 for Quaternion { +impl From> for Matrix4 { /// Convert the quaternion to a 4 x 4 rotation matrix - fn to_matrix4(&self) -> Matrix4 { - let x2 = self.v.x + self.v.x; - let y2 = self.v.y + self.v.y; - let z2 = self.v.z + self.v.z; + fn from(quat: Quaternion) -> Matrix4 { + let x2 = quat.v.x + quat.v.x; + let y2 = quat.v.y + quat.v.y; + let z2 = quat.v.z + quat.v.z; - let xx2 = x2 * self.v.x; - let xy2 = x2 * self.v.y; - let xz2 = x2 * self.v.z; + let xx2 = x2 * quat.v.x; + let xy2 = x2 * quat.v.y; + let xz2 = x2 * quat.v.z; - let yy2 = y2 * self.v.y; - let yz2 = y2 * self.v.z; - let zz2 = z2 * self.v.z; + let yy2 = y2 * quat.v.y; + let yz2 = y2 * quat.v.z; + let zz2 = z2 * quat.v.z; - let sy2 = y2 * self.s; - let sz2 = z2 * self.s; - let sx2 = x2 * self.s; + let sy2 = y2 * quat.s; + let sz2 = z2 * quat.s; + let sx2 = x2 * quat.s; Matrix4::new(one::() - yy2 - zz2, xy2 + sz2, xz2 - sy2, zero::(), xy2 - sz2, one::() - xx2 - zz2, yz2 + sx2, zero::(), diff --git a/src/rotation.rs b/src/rotation.rs index cf3e689..39cf1a0 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -16,8 +16,8 @@ use angle::{Rad, acos}; use approx::ApproxEq; use matrix::Matrix; -use matrix::{Matrix2, ToMatrix2}; -use matrix::{Matrix3, ToMatrix3}; +use matrix::Matrix2; +use matrix::Matrix3; use num::{BaseNum, BaseFloat}; use point::{Point, Point2, Point3}; use quaternion::{Quaternion, ToQuaternion}; @@ -75,7 +75,7 @@ pub trait Rotation, P: Point>: PartialEq + Approx /// A two-dimensional rotation. pub trait Rotation2: Rotation, Point2> - + ToMatrix2 + + Into> + ToBasis2 { /// Create a rotation by a given angle. Thus is a redundant case of both /// from_axis_angle() and from_euler() for 2D space. @@ -84,7 +84,7 @@ pub trait Rotation2: Rotation, Point2> /// A three-dimensional rotation. pub trait Rotation3: Rotation, Point3> - + ToMatrix3 + + Into> + ToBasis3 + ToQuaternion{ /// Create a rotation using an angle around a given axis. @@ -135,7 +135,7 @@ pub trait Rotation3: Rotation, Point3> /// ```no_run /// use cgmath::rad; /// use cgmath::Vector2; -/// use cgmath::{Matrix, ToMatrix2}; +/// use cgmath::{Matrix, Matrix2}; /// use cgmath::{Rotation, Rotation2, Basis2}; /// use cgmath::ApproxEq; /// use std::f64; @@ -153,7 +153,8 @@ pub trait Rotation3: Rotation, Point3> /// assert!(unit_y.approx_eq(&Vector2::unit_y())); /// /// // This is exactly equivalent to using the raw matrix itself: -/// let unit_y2 = rot.to_matrix2().mul_v(&unit_x); +/// let unit_y2: Matrix2<_> = rot.into(); +/// let unit_y2 = unit_y2.mul_v(&unit_x); /// assert_eq!(unit_y2, unit_y); /// /// // Note that we can also concatenate rotations: @@ -183,9 +184,9 @@ impl ToBasis2 for Basis2 { fn to_rot2(&self) -> Basis2 { self.clone() } } -impl ToMatrix2 for Basis2 { +impl From> for Matrix2 { #[inline] - fn to_matrix2(&self) -> Matrix2 { self.mat.clone() } + fn from(b: Basis2) -> Matrix2 { b.mat } } impl Rotation, Point2> for Basis2 { @@ -248,7 +249,7 @@ impl Basis3 { /// Create a new rotation matrix from a quaternion. #[inline] pub fn from_quaternion(quaternion: &Quaternion) -> Basis3 { - Basis3 { mat: quaternion.to_matrix3() } + Basis3 { mat: quaternion.clone().into() } } /// Coerce to a `Matrix3` @@ -267,9 +268,9 @@ impl ToBasis3 for Basis3 { fn to_rot3(&self) -> Basis3 { self.clone() } } -impl ToMatrix3 for Basis3 { +impl From> for Matrix3 { #[inline] - fn to_matrix3(&self) -> Matrix3 { self.mat.clone() } + fn from(b: Basis3) -> Matrix3 { b.mat } } impl ToQuaternion for Basis3 { diff --git a/src/transform.rs b/src/transform.rs index 9e09f12..7485fd3 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -146,16 +146,17 @@ impl< } } -pub trait Transform2: Transform, Point2> + ToMatrix3 {} -pub trait Transform3: Transform, Point3> + ToMatrix4 {} +pub trait Transform2: Transform, Point2> + Into> {} +pub trait Transform3: Transform, Point3> + Into> {} impl< S: BaseFloat + 'static, R: Rotation2, -> ToMatrix3 for Decomposed, R> { - fn to_matrix3(&self) -> Matrix3 { - let mut m = self.rot.to_matrix2().mul_s(self.scale.clone()).to_matrix3(); - m.z = self.disp.extend(one()); +> 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(); + m.z = dec.disp.extend(one()); m } } @@ -163,10 +164,11 @@ impl< impl< S: BaseFloat + 'static, R: Rotation3, -> ToMatrix4 for Decomposed, R> { - fn to_matrix4(&self) -> Matrix4 { - let mut m = self.rot.to_matrix3().mul_s(self.scale.clone()).to_matrix4(); - m.w = self.disp.extend(one()); +> 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(); + m.w = dec.disp.extend(one()); m } } @@ -229,8 +231,8 @@ impl Transform, Point3> for AffineMatri } } -impl ToMatrix4 for AffineMatrix3 { - #[inline] fn to_matrix4(&self) -> Matrix4 { self.mat.clone() } +impl From> for Matrix4 { + #[inline] fn from(aff: AffineMatrix3) -> Matrix4 { aff.mat } } impl Transform3 for AffineMatrix3 {} diff --git a/tests/quaternion.rs b/tests/quaternion.rs index 3462365..5a91bcf 100644 --- a/tests/quaternion.rs +++ b/tests/quaternion.rs @@ -15,7 +15,7 @@ extern crate cgmath; -use cgmath::{ToMatrix4, ToMatrix3}; +use cgmath::{Matrix4, Matrix3}; use cgmath::Quaternion; use cgmath::{Rad, rad, ApproxEq}; @@ -28,8 +28,10 @@ fn to_matrix4() { let quaternion = Quaternion::new(2f32, 3f32, 4f32, 5f32); - let matrix_short = quaternion.to_matrix4(); - let matrix_long = quaternion.to_matrix3().to_matrix4(); + let matrix_short: Matrix4<_> = quaternion.into(); + + let matrix_long: Matrix3<_> = quaternion.into(); + let matrix_long: Matrix4<_> = matrix_long.into(); assert!(matrix_short == matrix_long); }