diff --git a/src/angle.rs b/src/angle.rs index e3a84b8..dbb0a5e 100644 --- a/src/angle.rs +++ b/src/angle.rs @@ -40,39 +40,19 @@ pub struct Deg { pub s: S } /// Create a new angle, in degrees #[inline] pub fn deg(s: S) -> Deg { Deg { s: s } } -/// Represents types that can be converted to radians. -pub trait ToRad { - /// Convert this value to radians. - fn to_rad(&self) -> Rad; -} - -/// Represents types that can be converted to degrees. -pub trait ToDeg { - /// Convert this value to degrees. - fn to_deg(&self) -> Deg; -} - -impl ToRad for Rad { +impl From> for Deg where S: BaseFloat { #[inline] - fn to_rad(&self) -> Rad { self.clone() } -} -impl ToRad for Deg { - #[inline] - fn to_rad(&self) -> Rad { - rad(self.s * cast(f64::consts::PI / 180.0).unwrap()) + fn from(r: Rad) -> Deg { + deg(r.s * cast(180.0 / f64::consts::PI).unwrap()) } } -impl ToDeg for Rad { +impl From> for Rad where S: BaseFloat { #[inline] - fn to_deg(&self) -> Deg { - deg(self.s * cast(180.0 / f64::consts::PI).unwrap()) + fn from(d: Deg) -> Rad { + rad(d.s * cast(f64::consts::PI / 180.0).unwrap()) } } -impl ToDeg for Deg { - #[inline] - fn to_deg(&self) -> Deg { self.clone() } -} /// Private utility functions for converting to/from scalars trait ScalarConv { @@ -102,8 +82,8 @@ pub trait Angle + PartialEq + PartialOrd + ApproxEq + Neg -+ ToRad -+ ToDeg ++ Into> ++ Into> + ScalarConv + fmt::Debug { @@ -279,13 +259,13 @@ impl One for Deg { const PI_2: f64 = f64::consts::PI * 2f64; impl Angle for Rad { - #[inline] fn from>(theta: A) -> Rad { theta.to_rad() } + #[inline] fn from>(theta: A) -> Rad { theta.into() } #[inline] fn full_turn() -> Rad { rad(cast(PI_2).unwrap()) } } impl Angle for Deg { - #[inline] fn from>(theta: A) -> Deg { theta.to_deg() } + #[inline] fn from>(theta: A) -> Deg { theta.into() } #[inline] fn full_turn() -> Deg { deg(cast(360i32).unwrap()) } } diff --git a/src/matrix.rs b/src/matrix.rs index 3ea5a56..d683b73 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -29,7 +29,7 @@ use approx::ApproxEq; use array::{Array1, Array2, FixedArray}; use num::{BaseFloat, BaseNum}; use point::{Point, Point3}; -use quaternion::{Quaternion, ToQuaternion}; +use quaternion::Quaternion; use vector::{Vector, EuclideanVector}; use vector::{Vector2, Vector3, Vector4}; @@ -1326,94 +1326,76 @@ 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()) } } -impl ToQuaternion for Matrix3 { +impl From> for Quaternion { /// Convert the matrix to a quaternion - fn to_quaternion(&self) -> Quaternion { + fn from(mat: Matrix3) -> Quaternion { // http://www.cs.ucr.edu/~vbz/resources/quatut.pdf - let trace = self.trace(); + let trace = mat.trace(); let half: S = cast(0.5f64).unwrap(); if trace >= zero::() { let s = (one::() + trace).sqrt(); let w = half * s; let s = half / s; - let x = (self[1][2] - self[2][1]) * s; - let y = (self[2][0] - self[0][2]) * s; - let z = (self[0][1] - self[1][0]) * s; + let x = (mat[1][2] - mat[2][1]) * s; + let y = (mat[2][0] - mat[0][2]) * s; + let z = (mat[0][1] - mat[1][0]) * s; Quaternion::new(w, x, y, z) - } else if (self[0][0] > self[1][1]) && (self[0][0] > self[2][2]) { - let s = (half + (self[0][0] - self[1][1] - self[2][2])).sqrt(); + } else if (mat[0][0] > mat[1][1]) && (mat[0][0] > mat[2][2]) { + let s = (half + (mat[0][0] - mat[1][1] - mat[2][2])).sqrt(); let w = half * s; let s = half / s; - let x = (self[0][1] - self[1][0]) * s; - let y = (self[2][0] - self[0][2]) * s; - let z = (self[1][2] - self[2][1]) * s; + let x = (mat[0][1] - mat[1][0]) * s; + let y = (mat[2][0] - mat[0][2]) * s; + let z = (mat[1][2] - mat[2][1]) * s; Quaternion::new(w, x, y, z) - } else if self[1][1] > self[2][2] { - let s = (half + (self[1][1] - self[0][0] - self[2][2])).sqrt(); + } else if mat[1][1] > mat[2][2] { + let s = (half + (mat[1][1] - mat[0][0] - mat[2][2])).sqrt(); let w = half * s; let s = half / s; - let x = (self[0][1] - self[1][0]) * s; - let y = (self[1][2] - self[2][1]) * s; - let z = (self[2][0] - self[0][2]) * s; + let x = (mat[0][1] - mat[1][0]) * s; + let y = (mat[1][2] - mat[2][1]) * s; + let z = (mat[2][0] - mat[0][2]) * s; Quaternion::new(w, x, y, z) } else { - let s = (half + (self[2][2] - self[0][0] - self[1][1])).sqrt(); + let s = (half + (mat[2][2] - mat[0][0] - mat[1][1])).sqrt(); let w = half * s; let s = half / s; - let x = (self[2][0] - self[0][2]) * s; - let y = (self[1][2] - self[2][1]) * s; - let z = (self[0][1] - self[1][0]) * s; + let x = (mat[2][0] - mat[0][2]) * s; + let y = (mat[1][2] - mat[2][1]) * s; + let z = (mat[0][1] - mat[1][0]) * s; Quaternion::new(w, x, y, z) } } diff --git a/src/projection.rs b/src/projection.rs index 6835ddf..507db02 100644 --- a/src/projection.rs +++ b/src/projection.rs @@ -16,9 +16,9 @@ use rust_num::{zero, one}; use rust_num::traits::cast; -use angle::{Angle, tan, cot}; +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; } @@ -81,7 +81,8 @@ pub struct PerspectiveFov { impl> PerspectiveFov { pub fn to_perspective(&self) -> Perspective { let angle = self.fovy.div_s(cast(2i8).unwrap()); - let ymax = self.near * tan(angle.to_rad()); + let angle: Rad<_> = angle.into(); + let ymax = self.near * tan(angle); let xmax = ymax * self.aspect; Perspective { @@ -98,25 +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 = cot(self.fovy.div_s(cast(2i8).unwrap()).to_rad()); + 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(); @@ -128,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, @@ -157,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, @@ -220,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..03b3e1a 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -25,10 +25,10 @@ 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}; +use rotation::{Rotation, Rotation3, Basis3}; use vector::{Vector3, Vector, EuclideanVector}; @@ -37,12 +37,6 @@ use vector::{Vector3, Vector, EuclideanVector}; #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)] pub struct Quaternion { pub s: S, pub v: Vector3 } -/// Represents types which can be expressed as a quaternion. -pub trait ToQuaternion { - /// Convert this value to a quaternion. - fn to_quaternion(&self) -> Quaternion; -} - impl Array1 for Quaternion { #[inline] fn map(&mut self, mut op: F) -> Quaternion where F: FnMut(S) -> S { @@ -310,24 +304,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 +329,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::(), @@ -382,14 +376,9 @@ impl fmt::Debug for Quaternion { // Quaternion Rotation impls -impl ToBasis3 for Quaternion { +impl From> for Basis3 { #[inline] - fn to_rot3(&self) -> Basis3 { Basis3::from_quaternion(self) } -} - -impl ToQuaternion for Quaternion { - #[inline] - fn to_quaternion(&self) -> Quaternion { self.clone() } + fn from(quat: Quaternion) -> Basis3 { Basis3::from_quaternion(&quat) } } impl Rotation, Point3> for Quaternion { @@ -398,7 +387,7 @@ impl Rotation, Point3> for Quaternion, up: &Vector3) -> Quaternion { - Matrix3::look_at(dir, up).to_quaternion() + Matrix3::look_at(dir, up).into() } #[inline] diff --git a/src/rotation.rs b/src/rotation.rs index cf3e689..6c5419a 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -16,11 +16,11 @@ 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}; +use quaternion::Quaternion; use ray::Ray; use vector::{Vector, Vector2, Vector3}; @@ -75,8 +75,8 @@ pub trait Rotation, P: Point>: PartialEq + Approx /// A two-dimensional rotation. pub trait Rotation2: Rotation, Point2> - + ToMatrix2 - + ToBasis2 { + + Into> + + Into> { /// Create a rotation by a given angle. Thus is a redundant case of both /// from_axis_angle() and from_euler() for 2D space. fn from_angle(theta: Rad) -> Self; @@ -84,9 +84,9 @@ pub trait Rotation2: Rotation, Point2> /// A three-dimensional rotation. pub trait Rotation3: Rotation, Point3> - + ToMatrix3 - + ToBasis3 - + ToQuaternion{ + + Into> + + Into> + + Into> { /// Create a rotation using an angle around a given axis. fn from_axis_angle(axis: &Vector3, angle: Rad) -> Self; @@ -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: @@ -166,26 +167,16 @@ pub struct Basis2 { mat: Matrix2 } -impl Basis2 { - /// Coerce to a `Matrix2` +impl AsRef> for Basis2 { #[inline] - pub fn as_matrix2<'a>(&'a self) -> &'a Matrix2 { &self.mat } + fn as_ref(&self) -> &Matrix2 { + &self.mat + } } -/// Represents types which can be converted to a rotation matrix. -pub trait ToBasis2 { - /// Convert this type to a rotation matrix. - fn to_rot2(&self) -> Basis2; -} - -impl ToBasis2 for Basis2 { +impl From> for Matrix2 { #[inline] - fn to_rot2(&self) -> Basis2 { self.clone() } -} - -impl ToMatrix2 for Basis2 { - #[inline] - fn to_matrix2(&self) -> Matrix2 { self.mat.clone() } + fn from(b: Basis2) -> Matrix2 { b.mat } } impl Rotation, Point2> for Basis2 { @@ -248,33 +239,25 @@ 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` - #[inline] - pub fn as_matrix3<'a>(&'a self) -> &'a Matrix3 { &self.mat } } -/// Represents types which can be converted to a rotation matrix. -pub trait ToBasis3 { - /// Convert this type to a rotation matrix. - fn to_rot3(&self) -> Basis3; +impl AsRef> for Basis3 { + #[inline] + fn as_ref(&self) -> &Matrix3 { + &self.mat + } } -impl ToBasis3 for Basis3 { +impl From> for Matrix3 { #[inline] - fn to_rot3(&self) -> Basis3 { self.clone() } + fn from(b: Basis3) -> Matrix3 { b.mat } } -impl ToMatrix3 for Basis3 { +impl From> for Quaternion { #[inline] - fn to_matrix3(&self) -> Matrix3 { self.mat.clone() } -} - -impl ToQuaternion for Basis3 { - #[inline] - fn to_quaternion(&self) -> Quaternion { self.mat.to_quaternion() } + fn from(b: Basis3) -> Quaternion { b.mat.into() } } impl Rotation, Point3> for Basis3 { @@ -289,7 +272,7 @@ impl Rotation, Point3> for Basis3 { #[inline] fn between_vectors(a: &Vector3, b: &Vector3) -> Basis3 { let q: Quaternion = Rotation::between_vectors(a, b); - q.to_rot3() + q.into() } #[inline] 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/angle.rs b/tests/angle.rs index e8a1224..02bf6f0 100644 --- a/tests/angle.rs +++ b/tests/angle.rs @@ -16,16 +16,25 @@ extern crate cgmath; use cgmath::{Angle, Rad, Deg, rad, deg}; -use cgmath::{ToRad, ToDeg}; use cgmath::ApproxEq; #[test] fn conv() { - assert!(deg(-5.0f64).to_rad().to_deg().approx_eq(°(-5.0f64))); - assert!(deg(30.0f64).to_rad().to_deg().approx_eq(°(30.0f64))); + let angle: Rad<_> = deg(-5.0f64).into(); + let angle: Deg<_> = angle.into(); + assert!(angle.approx_eq(°(-5.0f64))); - assert!(rad(-5.0f64).to_deg().to_rad().approx_eq(&rad(-5.0f64))); - assert!(rad(30.0f64).to_deg().to_rad().approx_eq(&rad(30.0f64))); + let angle: Rad<_> = deg(30.0f64).into(); + let angle: Deg<_> = angle.into(); + assert!(angle.approx_eq(°(30.0f64))); + + let angle: Deg<_> = rad(-5.0f64).into(); + let angle: Rad<_> = angle.into(); + assert!(angle.approx_eq(&rad(-5.0f64))); + + let angle: Deg<_> = rad(30.0f64).into(); + let angle: Rad<_> = angle.into(); + assert!(angle.approx_eq(&rad(30.0f64))); } #[test] 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); } diff --git a/tests/rotation.rs b/tests/rotation.rs index c44df49..4ee31de 100644 --- a/tests/rotation.rs +++ b/tests/rotation.rs @@ -21,23 +21,27 @@ mod rotation { use super::cgmath::*; pub fn a2>() -> R { - Rotation2::from_angle(deg(30.0).to_rad()) + Rotation2::from_angle(deg(30.0).into()) } pub fn a3>() -> R { let axis = Vector3::new(1.0, 1.0, 0.0).normalize(); - Rotation3::from_axis_angle(&axis, deg(30.0).to_rad()) + Rotation3::from_axis_angle(&axis, deg(30.0).into()) } } #[test] fn test_invert_basis2() { let a: Basis2<_> = rotation::a2(); - assert!(a.concat(&a.invert()).as_matrix2().is_identity()); + let a = a.concat(&a.invert()); + let a: &Matrix2<_> = a.as_ref(); + assert!(a.is_identity()); } #[test] fn test_invert_basis3() { let a: Basis3<_> = rotation::a3(); - assert!(a.concat(&a.invert()).as_matrix3().is_identity()); + let a = a.concat(&a.invert()); + let a: &Matrix3<_> = a.as_ref(); + assert!(a.is_identity()); }