Add conversion traits

This commit is contained in:
Brendan Zabarauskas 2013-06-12 11:30:18 +10:00
parent b2e7f2e4b1
commit 5cb98d09cf
5 changed files with 43 additions and 16 deletions

View file

@ -13,9 +13,9 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
pub use self::mat2::Mat2; pub use self::mat2::{Mat2, ToMat2};
pub use self::mat3::Mat3; pub use self::mat3::{Mat3, ToMat3};
pub use self::mat4::Mat4; pub use self::mat4::{Mat4, ToMat4};
pub mod mat2; pub mod mat2;
pub mod mat3; pub mod mat3;

View file

@ -18,7 +18,8 @@ use std::cmp::ApproxEq;
use std::num::{Zero, One}; use std::num::{Zero, One};
use vec::*; use vec::*;
use super::{Mat3, Mat4}; use super::{Mat3, ToMat3};
use super::{Mat4, ToMat4};
#[deriving(Eq)] #[deriving(Eq)]
pub struct Mat2<T> { pub struct Mat2<T> {
@ -26,6 +27,10 @@ pub struct Mat2<T> {
y: Vec2<T>, y: Vec2<T>,
} }
pub trait ToMat2<T> {
pub fn to_mat2(&self) -> Mat2<T>;
}
impl<T> Mat2<T> { impl<T> Mat2<T> {
/// Construct a 2 x 2 matrix /// Construct a 2 x 2 matrix
/// ///
@ -265,7 +270,9 @@ impl<T:Copy + Num> Mat2<T> {
pub fn to_zero(&mut self) { pub fn to_zero(&mut self) {
*self = Mat2::zero(); *self = Mat2::zero();
} }
}
impl<T:Copy + Num> ToMat3<T> for Mat2<T> {
/// Returns the the matrix with an extra row and column added /// Returns the the matrix with an extra row and column added
/// ~~~ /// ~~~
/// c0 c1 c0 c1 c2 /// c0 c1 c0 c1 c2
@ -283,7 +290,9 @@ impl<T:Copy + Num> Mat2<T> {
*self.elem(1, 0), *self.elem(1, 1), Zero::zero(), *self.elem(1, 0), *self.elem(1, 1), Zero::zero(),
Zero::zero(), Zero::zero(), One::one()) Zero::zero(), Zero::zero(), One::one())
} }
}
impl<T:Copy + Num> ToMat4<T> for Mat2<T> {
/// Returns the the matrix with an extra two rows and columns added /// Returns the the matrix with an extra two rows and columns added
/// ~~~ /// ~~~
/// c0 c1 c0 c1 c2 c3 /// c0 c1 c0 c1 c2 c3

View file

@ -18,8 +18,8 @@ use std::cmp::ApproxEq;
use std::num::{Zero, One}; use std::num::{Zero, One};
use vec::*; use vec::*;
use quat::Quat; use quat::{Quat, ToQuat};
use super::Mat4; use super::{Mat4, ToMat4};
#[deriving(Eq)] #[deriving(Eq)]
pub struct Mat3<T> { pub struct Mat3<T> {
@ -28,6 +28,10 @@ pub struct Mat3<T> {
z: Vec3<T>, z: Vec3<T>,
} }
pub trait ToMat3<T> {
pub fn to_mat3(&self) -> Mat3<T>;
}
impl<T> Mat3<T> { impl<T> Mat3<T> {
/// Construct a 3 x 3 matrix /// Construct a 3 x 3 matrix
/// ///
@ -320,7 +324,9 @@ impl<T:Copy + Num> Mat3<T> {
pub fn to_zero(&mut self) { pub fn to_zero(&mut self) {
*self = Mat3::zero(); *self = Mat3::zero();
} }
}
impl<T:Copy + Num> ToMat4<T> for Mat3<T> {
/// Returns the the matrix with an extra row and column added /// Returns the the matrix with an extra row and column added
/// ~~~ /// ~~~
/// c0 c1 c2 c0 c1 c2 c3 /// c0 c1 c2 c0 c1 c2 c3
@ -432,7 +438,9 @@ impl<T:Copy + Real> Mat3<T> {
Mat3::from_axes(up_, side, dir_) Mat3::from_axes(up_, side, dir_)
} }
}
impl<T:Copy + Real> ToQuat<T> for Mat3<T> {
/// Convert the matrix to a quaternion /// Convert the matrix to a quaternion
pub fn to_quat(&self) -> Quat<T> { pub fn to_quat(&self) -> Quat<T> {
// Implemented using a mix of ideas from jMonkeyEngine and Ken Shoemake's // Implemented using a mix of ideas from jMonkeyEngine and Ken Shoemake's

View file

@ -29,6 +29,10 @@ pub struct Mat4<T> {
w: Vec4<T>, w: Vec4<T>,
} }
pub trait ToMat4<T> {
pub fn to_mat4(&self) -> Mat4<T>;
}
impl<T> Mat4<T> { impl<T> Mat4<T> {
/// Construct a 4 x 4 matrix /// Construct a 4 x 4 matrix
/// ///

View file

@ -17,7 +17,7 @@ use std::cast::transmute;
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::num::{Zero, One, cast}; use std::num::{Zero, One, cast};
use mat::Mat3; use mat::{Mat3, ToMat3};
use vec::Vec3; use vec::Vec3;
// GLSL-style type aliases // GLSL-style type aliases
@ -44,6 +44,10 @@ pub type Quatf64 = Quat<f64>;
#[deriving(Eq)] #[deriving(Eq)]
pub struct Quat<T> { s: T, v: Vec3<T> } pub struct Quat<T> { s: T, v: Vec3<T> }
pub trait ToQuat<T> {
pub fn to_quat(&self) -> Quat<T>;
}
impl<T> Quat<T> { impl<T> Quat<T> {
/// Construct the quaternion from one scalar component and three /// Construct the quaternion from one scalar component and three
/// imaginary components /// imaginary components
@ -267,6 +271,17 @@ impl<T:Copy + Real> Quat<T> {
self.mul_t(One::one::<T>() / self.magnitude()) self.mul_t(One::one::<T>() / self.magnitude())
} }
/// Normalised linear interpolation
///
/// # Return value
///
/// The intoperlated quaternion
pub fn nlerp(&self, other: &Quat<T>, amount: T) -> Quat<T> {
self.mul_t(One::one::<T>() - amount).add_q(&other.mul_t(amount)).normalize()
}
}
impl<T:Copy + Num> ToMat3<T> for Quat<T> {
/// Convert the quaternion to a 3 x 3 rotation matrix /// Convert the quaternion to a 3 x 3 rotation matrix
pub fn to_mat3(&self) -> Mat3<T> { pub fn to_mat3(&self) -> Mat3<T> {
let x2 = self.v.x + self.v.x; let x2 = self.v.x + self.v.x;
@ -291,15 +306,6 @@ impl<T:Copy + Real> Quat<T> {
xy2 - sz2, _1 - xx2 - zz2, yz2 + sx2, xy2 - sz2, _1 - xx2 - zz2, yz2 + sx2,
xz2 + sy2, yz2 - sx2, _1 - xx2 - yy2) xz2 + sy2, yz2 - sx2, _1 - xx2 - yy2)
} }
/// Normalised linear interpolation
///
/// # Return value
///
/// The intoperlated quaternion
pub fn nlerp(&self, other: &Quat<T>, amount: T) -> Quat<T> {
self.mul_t(One::one::<T>() - amount).add_q(&other.mul_t(amount)).normalize()
}
} }
impl<T:Copy + Float> Neg<Quat<T>> for Quat<T> { impl<T:Copy + Float> Neg<Quat<T>> for Quat<T> {