2012-09-24 02:54:24 +00:00
|
|
|
use std::cmp::FuzzyEq;
|
2012-09-29 10:25:49 +00:00
|
|
|
use cmp::Eq;
|
2012-09-29 10:37:46 +00:00
|
|
|
use ops::{Neg, Index};
|
2012-09-24 02:54:24 +00:00
|
|
|
// use to_str::ToStr;
|
|
|
|
use math::Sqrt;
|
|
|
|
use quat::Quat;
|
|
|
|
use vec::*;
|
2012-09-07 10:48:47 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// NxN Matrix
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
pub trait Matrix<T, V> {
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn rows() -> uint;
|
|
|
|
pure fn cols() -> uint;
|
|
|
|
pure fn is_col_major() -> bool;
|
|
|
|
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn row(i: uint) -> V;
|
|
|
|
pure fn col(i: uint) -> V;
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn mul_f(value: T) -> self;
|
|
|
|
pure fn mul_v(other: &V) -> V;
|
|
|
|
pure fn add_m(other: &self) -> self;
|
|
|
|
pure fn sub_m(other: &self) -> self;
|
|
|
|
pure fn mul_m(other: &self) -> self;
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-10-01 06:23:49 +00:00
|
|
|
// pure fn invert(other: &self) -> self;
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn transpose() -> self;
|
|
|
|
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn exact_eq(other: &self) -> bool;
|
2012-09-07 10:48:47 +00:00
|
|
|
|
|
|
|
pure fn is_identity() -> bool;
|
|
|
|
pure fn is_symmetric() -> bool;
|
|
|
|
pure fn is_diagonal() -> bool;
|
|
|
|
pure fn is_rotated() -> bool;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// 3x3 Matrix
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
pub trait Matrix3<V3> {
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn scale(vec: &V3) -> self;
|
2012-09-24 02:54:24 +00:00
|
|
|
pure fn to_Mat4() -> Mat4;
|
|
|
|
pure fn to_Quat() -> Quat;
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// 4x4 Matrix
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
pub trait Matrix4<V3, V4> {
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn scale(vec: &V3) -> self; // I don't like the use of `Vec3` here
|
|
|
|
pure fn translate(vec: &V3) -> self;
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Mat2: A 2x2, column major matrix
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
pub struct Mat2 { data:[Vec2 * 2] }
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-29 08:41:48 +00:00
|
|
|
pub const mat2_zero :Mat2 = Mat2 { data: [ vec2_zero,
|
|
|
|
vec2_zero ] };
|
|
|
|
pub const mat2_identity :Mat2 = Mat2 { data: [ vec2_unit_x,
|
|
|
|
vec2_unit_y ] };
|
2012-09-08 06:08:36 +00:00
|
|
|
|
2012-09-07 10:48:47 +00:00
|
|
|
//
|
|
|
|
// Mat2 Constructor
|
|
|
|
//
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-29 08:41:48 +00:00
|
|
|
pub pure fn Mat2(m00:float, m01:float,
|
|
|
|
m10:float, m11:float) -> Mat2 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Mat2 { data: [ Vec2(m00, m01),
|
|
|
|
Vec2(m10, m11) ] }
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
// Conpub struct Mat2 from column vectors
|
2012-09-07 10:48:47 +00:00
|
|
|
//
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pub pure fn Mat2_v(col0: &Vec2, col1: &Vec2) -> Mat2 {
|
|
|
|
Mat2 { data: [ *col0, *col1 ] }
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Matrix2x2 Implementation
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
pub impl Mat2: Matrix<float, Vec2> {
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn rows() -> uint { 2 }
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn cols() -> uint { 2 }
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_col_major() -> bool { true }
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn row(i: uint) -> Vec2 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Vec2(self[0][i],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[1][i])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn col(i: uint) -> Vec2 {
|
2012-09-07 10:48:47 +00:00
|
|
|
self.data[i]
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn mul_f(value: float) -> Mat2 {
|
|
|
|
Mat2_v(&self[0].mul_f(value),
|
|
|
|
&self[1].mul_f(value))
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn mul_v(other: &Vec2) -> Vec2 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Vec2(self[0][0]*other[0] + self[1][0]*other[1],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[0][1]*other[0] + self[1][1]*other[1])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn add_m(other: &Mat2) -> Mat2 {
|
|
|
|
Mat2_v(&self[0].add_v(&other[0]),
|
|
|
|
&self[1].add_v(&other[1]))
|
2012-09-08 01:54:32 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn sub_m(other: &Mat2) -> Mat2 {
|
|
|
|
Mat2_v(&self[0].sub_v(&other[0]),
|
|
|
|
&self[1].sub_v(&other[1]))
|
2012-09-08 01:54:32 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn mul_m(other: &Mat2) -> Mat2 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Mat2(self[0][0]*other[0][0] + self[1][0]*other[0][1],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[0][1]*other[0][0] + self[1][1]*other[0][1],
|
|
|
|
|
|
|
|
self[0][0]*other[1][0] + self[1][0]*other[1][1],
|
|
|
|
self[0][1]*other[1][0] + self[1][1]*other[1][1])
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO - inversion is harrrd D:
|
2012-09-24 02:54:24 +00:00
|
|
|
// #[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
// pure fn invert(other: &Mat2) -> Mat2 {}
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
|
|
|
pure fn transpose() -> Mat2 {
|
|
|
|
Mat2(self[0][0], self[1][0],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[0][1], self[1][1])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn exact_eq(other: &Mat2) -> bool {
|
|
|
|
self[0].exact_eq(&other[0]) &&
|
|
|
|
self[1].exact_eq(&other[1])
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_identity() -> bool {
|
2012-09-29 10:25:49 +00:00
|
|
|
self.fuzzy_eq(&mat2_identity)
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_symmetric() -> bool {
|
|
|
|
self[0][1].fuzzy_eq(&self[1][0]) &&
|
|
|
|
self[1][0].fuzzy_eq(&self[0][1])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_diagonal() -> bool {
|
2012-09-07 14:17:26 +00:00
|
|
|
self[0][1].fuzzy_eq(&0f) &&
|
|
|
|
self[1][0].fuzzy_eq(&0f)
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_rotated() -> bool {
|
2012-09-29 10:25:49 +00:00
|
|
|
!self.fuzzy_eq(&mat2_identity)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-29 10:37:46 +00:00
|
|
|
pub impl Mat2: Index<uint, Vec2> {
|
|
|
|
#[inline]
|
|
|
|
pure fn index(+i: uint) -> Vec2 {
|
|
|
|
self.data[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-29 10:25:49 +00:00
|
|
|
pub impl Mat2: Neg<Mat2> {
|
|
|
|
#[inline]
|
|
|
|
pure fn neg() -> Mat2 {
|
2012-10-01 06:23:49 +00:00
|
|
|
Mat2_v(&-self[0], &-self[1])
|
2012-09-29 10:25:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub impl Mat2: Eq {
|
|
|
|
#[inline]
|
|
|
|
pure fn eq(other: &Mat2) -> bool {
|
|
|
|
self.fuzzy_eq(other)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pure fn ne(other: &Mat2) -> bool {
|
|
|
|
!(self == *other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub impl Mat2: FuzzyEq {
|
|
|
|
#[inline]
|
|
|
|
pure fn fuzzy_eq(other: &Mat2) -> bool {
|
|
|
|
self[0].fuzzy_eq(&other[0]) &&
|
|
|
|
self[1].fuzzy_eq(&other[1])
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Mat3: A 3x3, column major matrix
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
pub struct Mat3 { data:[Vec3 * 3] }
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-29 08:41:48 +00:00
|
|
|
pub const mat3_zero :Mat3 = Mat3 { data: [ vec3_zero,
|
|
|
|
vec3_zero,
|
|
|
|
vec3_zero ] };
|
|
|
|
pub const mat3_identity :Mat3 = Mat3 { data: [ vec3_unit_x,
|
|
|
|
vec3_unit_y,
|
|
|
|
vec3_unit_z ] };
|
2012-09-08 06:08:36 +00:00
|
|
|
|
2012-09-07 10:48:47 +00:00
|
|
|
//
|
|
|
|
// Mat3 Constructor
|
|
|
|
//
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-29 08:41:48 +00:00
|
|
|
pub pure fn Mat3(m00:float, m01:float, m02:float,
|
|
|
|
m10:float, m11:float, m12:float,
|
|
|
|
m20:float, m21:float, m22:float) -> Mat3 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Mat3 { data: [ Vec3(m00, m01, m02),
|
|
|
|
Vec3(m10, m11, m12),
|
|
|
|
Vec3(m20, m21, m22) ] }
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
// Conpub struct Mat3 from column vectors
|
2012-09-07 10:48:47 +00:00
|
|
|
//
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pub pure fn Mat3_v(col0: &Vec3, col1: &Vec3, col2: &Vec3) -> Mat3 {
|
|
|
|
Mat3 { data: [ *col0, *col1, *col2 ] }
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Matrix3x3 Implementation
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
pub impl Mat3: Matrix<float, Vec3> {
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn rows() -> uint { 3 }
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn cols() -> uint { 3 }
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_col_major() -> bool { true }
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn row(i: uint) -> Vec3 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Vec3(self[0][i],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[1][i],
|
|
|
|
self[2][i])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn col(i: uint) -> Vec3 {
|
2012-09-07 10:48:47 +00:00
|
|
|
self.data[i]
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn mul_f(value: float) -> Mat3 {
|
|
|
|
Mat3_v(&self[0].mul_f(value),
|
|
|
|
&self[1].mul_f(value),
|
|
|
|
&self[2].mul_f(value))
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn mul_v(other: &Vec3) -> Vec3 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Vec3(self[0][0]*other[0] + self[1][0]*other[1] + self[2][0]*other[2],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[0][1]*other[0] + self[1][1]*other[1] + self[2][1]*other[2],
|
|
|
|
self[0][2]*other[0] + self[1][2]*other[1] + self[2][2]*other[2])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn add_m(other: &Mat3) -> Mat3 {
|
|
|
|
Mat3_v(&self[0].add_v(&other[0]),
|
|
|
|
&self[1].add_v(&other[1]),
|
|
|
|
&self[2].add_v(&other[2]))
|
2012-09-08 01:54:32 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn sub_m(other: &Mat3) -> Mat3 {
|
|
|
|
Mat3_v(&self[0].sub_v(&other[0]),
|
|
|
|
&self[1].sub_v(&other[1]),
|
|
|
|
&self[2].sub_v(&other[2]))
|
2012-09-08 01:54:32 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn mul_m(other: &Mat3) -> Mat3 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Mat3(self[0][0]*other[0][0] + self[1][0]*other[0][1] + self[2][0]*other[0][2],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[0][1]*other[0][0] + self[1][1]*other[0][1] + self[2][1]*other[0][2],
|
|
|
|
self[0][2]*other[0][0] + self[1][2]*other[0][1] + self[2][2]*other[0][2],
|
|
|
|
|
|
|
|
self[0][0]*other[1][0] + self[1][0]*other[1][1] + self[2][0]*other[1][2],
|
|
|
|
self[0][1]*other[1][0] + self[1][1]*other[1][1] + self[2][1]*other[1][2],
|
|
|
|
self[0][2]*other[1][0] + self[1][2]*other[1][1] + self[2][2]*other[1][2],
|
|
|
|
|
|
|
|
self[0][0]*other[2][0] + self[1][0]*other[2][1] + self[2][0]*other[2][2],
|
|
|
|
self[0][1]*other[2][0] + self[1][1]*other[2][1] + self[2][1]*other[2][2],
|
|
|
|
self[0][2]*other[2][0] + self[1][2]*other[2][1] + self[2][2]*other[2][2])
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO - inversion is harrrd D:
|
2012-09-24 02:54:24 +00:00
|
|
|
// #[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
// pure fn invert(other: &Mat3) -> Mat3 {}
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
|
|
|
pure fn transpose() -> Mat3 {
|
|
|
|
Mat3(self[0][0], self[1][0], self[2][0],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[0][1], self[1][1], self[2][1],
|
|
|
|
self[0][2], self[1][2], self[2][2])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn exact_eq(other: &Mat3) -> bool {
|
|
|
|
self[0].exact_eq(&other[0]) &&
|
|
|
|
self[1].exact_eq(&other[1]) &&
|
|
|
|
self[2].exact_eq(&other[2])
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_identity() -> bool {
|
2012-09-29 10:25:49 +00:00
|
|
|
self.fuzzy_eq(&mat3_identity)
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_symmetric() -> bool {
|
|
|
|
self[0][1].fuzzy_eq(&self[1][0]) &&
|
|
|
|
self[0][2].fuzzy_eq(&self[2][0]) &&
|
|
|
|
|
|
|
|
self[1][0].fuzzy_eq(&self[0][1]) &&
|
|
|
|
self[1][2].fuzzy_eq(&self[2][1]) &&
|
|
|
|
|
|
|
|
self[2][0].fuzzy_eq(&self[0][2]) &&
|
|
|
|
self[2][1].fuzzy_eq(&self[1][2])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_diagonal() -> bool {
|
2012-09-07 14:17:26 +00:00
|
|
|
self[0][1].fuzzy_eq(&0f) &&
|
|
|
|
self[0][2].fuzzy_eq(&0f) &&
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-07 14:17:26 +00:00
|
|
|
self[1][0].fuzzy_eq(&0f) &&
|
|
|
|
self[1][2].fuzzy_eq(&0f) &&
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-07 14:17:26 +00:00
|
|
|
self[2][0].fuzzy_eq(&0f) &&
|
|
|
|
self[2][1].fuzzy_eq(&0f)
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_rotated() -> bool {
|
2012-09-29 10:25:49 +00:00
|
|
|
!self.fuzzy_eq(&mat3_identity)
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-29 08:41:48 +00:00
|
|
|
pub impl Mat3: Matrix3<Vec3> {
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn scale(vec: &Vec3) -> Mat3 {
|
|
|
|
self.mul_m(&Mat3(vec.x(), 0f, 0f,
|
|
|
|
0f, vec.y(), 0f,
|
|
|
|
0f, 0f, vec.z()))
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
|
|
|
pure fn to_Mat4() -> Mat4 {
|
|
|
|
Mat4(self[0][0], self[0][1], self[0][2], 0f,
|
2012-09-07 14:17:26 +00:00
|
|
|
self[1][0], self[1][1], self[1][2], 0f,
|
|
|
|
self[2][0], self[2][1], self[2][2], 0f,
|
|
|
|
0f, 0f, 0f, 1f)
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
pure fn to_Quat() -> Quat {
|
2012-09-07 10:48:47 +00:00
|
|
|
// Implemented using a mix of ideas from jMonkeyEngine and Ken Shoemake's
|
2012-09-24 02:54:24 +00:00
|
|
|
// paper on Quaternions: http://www.cs.ucr.edu/~vbz/resources/Quatut.pdf
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-07 14:17:26 +00:00
|
|
|
let mut s:float;
|
|
|
|
let w:float, x:float, y:float, z:float;
|
2012-09-07 10:48:47 +00:00
|
|
|
let trace:float = self[0][0] + self[1][1] + self[2][2];
|
|
|
|
|
2012-09-07 14:17:26 +00:00
|
|
|
if trace >= 0f {
|
2012-09-10 02:55:15 +00:00
|
|
|
s = (trace + 1f).sqrt();
|
2012-09-07 10:48:47 +00:00
|
|
|
w = 0.5 * s;
|
|
|
|
s = 0.5 / s;
|
|
|
|
x = self[1][2] - self[2][1] * s;
|
|
|
|
y = self[2][0] - self[0][2] * s;
|
|
|
|
z = self[0][1] - self[1][0] * s;
|
|
|
|
} else if (self[0][0] > self[1][1]) && (self[0][0] > self[2][2]) {
|
2012-09-10 02:55:15 +00:00
|
|
|
s = (1f + self[0][0] - self[1][1] - self[2][2]).sqrt();
|
2012-09-07 10:48:47 +00:00
|
|
|
w = 0.5 * s;
|
|
|
|
s = 0.5 / s;
|
|
|
|
x = self[0][1] - self[1][0] * s;
|
|
|
|
y = self[2][0] - self[0][2] * s;
|
|
|
|
z = self[1][2] - self[2][1] * s;
|
|
|
|
} else if self[1][1] > self[2][2] {
|
2012-09-10 02:55:15 +00:00
|
|
|
s = (1f + self[1][1] - self[0][0] - self[2][2]).sqrt();
|
2012-09-07 10:48:47 +00:00
|
|
|
w = 0.5 * s;
|
|
|
|
s = 0.5 / s;
|
|
|
|
x = self[0][1] - self[1][0] * s;
|
|
|
|
y = self[1][2] - self[2][1] * s;
|
|
|
|
z = self[2][0] - self[0][2] * s;
|
|
|
|
} else {
|
2012-09-10 02:55:15 +00:00
|
|
|
s = (1f + self[2][2] - self[0][0] - self[1][1]).sqrt();
|
2012-09-07 10:48:47 +00:00
|
|
|
w = 0.5 * s;
|
|
|
|
s = 0.5 / s;
|
|
|
|
x = self[2][0] - self[0][2] * s;
|
|
|
|
y = self[1][2] - self[2][1] * s;
|
|
|
|
z = self[0][1] - self[1][0] * s;
|
|
|
|
}
|
2012-09-24 02:54:24 +00:00
|
|
|
return Quat(w, x, y, z);
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-29 10:37:46 +00:00
|
|
|
pub impl Mat3: Index<uint, Vec3> {
|
|
|
|
#[inline]
|
|
|
|
pure fn index(+i: uint) -> Vec3 {
|
|
|
|
self.data[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-29 10:25:49 +00:00
|
|
|
pub impl Mat3: Neg<Mat3> {
|
|
|
|
#[inline]
|
|
|
|
pure fn neg() -> Mat3 {
|
2012-10-01 06:23:49 +00:00
|
|
|
Mat3_v(&-self[0], &-self[1], &-self[2])
|
2012-09-29 10:25:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub impl Mat3: Eq {
|
|
|
|
#[inline]
|
|
|
|
pure fn eq(other: &Mat3) -> bool {
|
|
|
|
self.fuzzy_eq(other)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pure fn ne(other: &Mat3) -> bool {
|
|
|
|
!(self == *other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub impl Mat3: FuzzyEq {
|
|
|
|
#[inline]
|
|
|
|
pure fn fuzzy_eq(other: &Mat3) -> bool {
|
|
|
|
self[0].fuzzy_eq(&other[0]) &&
|
|
|
|
self[1].fuzzy_eq(&other[1]) &&
|
|
|
|
self[2].fuzzy_eq(&other[2])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-07 10:48:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Mat4: A 4x4, column major matrix
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
pub struct Mat4 { data:[Vec4 * 4] }
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-29 08:41:48 +00:00
|
|
|
pub const mat4_zero :Mat4 = Mat4 { data: [ vec4_zero,
|
2012-09-08 06:08:36 +00:00
|
|
|
vec4_zero,
|
|
|
|
vec4_zero,
|
|
|
|
vec4_zero ] };
|
2012-09-29 08:41:48 +00:00
|
|
|
pub const mat4_identity :Mat4 = Mat4 { data: [ vec4_unit_x,
|
2012-09-08 06:08:36 +00:00
|
|
|
vec4_unit_y,
|
|
|
|
vec4_unit_z,
|
|
|
|
vec4_unit_w ] };
|
|
|
|
|
2012-09-07 10:48:47 +00:00
|
|
|
//
|
|
|
|
// Mat4 Constructor
|
|
|
|
//
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-29 08:41:48 +00:00
|
|
|
pub pure fn Mat4(m00:float, m01:float, m02:float, m03:float,
|
2012-09-07 10:48:47 +00:00
|
|
|
m10:float, m11:float, m12:float, m13:float,
|
|
|
|
m20:float, m21:float, m22:float, m23:float,
|
2012-09-24 02:54:24 +00:00
|
|
|
m30:float, m31:float, m32:float, m33:float) -> Mat4 {
|
|
|
|
Mat4 { data: [ Vec4(m00, m01, m02, m03),
|
|
|
|
Vec4(m10, m11, m12, m13),
|
|
|
|
Vec4(m20, m21, m22, m23),
|
|
|
|
Vec4(m30, m31, m32, m33) ] }
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
// Conpub struct Mat4 from column vectors
|
2012-09-07 10:48:47 +00:00
|
|
|
//
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pub pure fn Mat4_v(col0: &Vec4, col1: &Vec4, col2: &Vec4, col3: &Vec4) -> Mat4 {
|
|
|
|
Mat4 { data: [ *col0, *col1, *col2, *col3 ] }
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Matrix4x4 Implementation
|
|
|
|
//
|
2012-09-29 08:41:48 +00:00
|
|
|
pub impl Mat4: Matrix<float, Vec4> {
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn rows() -> uint { 4 }
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn cols() -> uint { 4 }
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_col_major() -> bool { true }
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn row(i: uint) -> Vec4 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Vec4(self[0][i],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[1][i],
|
|
|
|
self[2][i],
|
|
|
|
self[3][i])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn col(i: uint) -> Vec4 {
|
2012-09-07 10:48:47 +00:00
|
|
|
self.data[i]
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn mul_f(value: float) -> Mat4 {
|
|
|
|
Mat4_v(&self[0].mul_f(value),
|
|
|
|
&self[1].mul_f(value),
|
|
|
|
&self[2].mul_f(value),
|
|
|
|
&self[3].mul_f(value))
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn mul_v(other: &Vec4) -> Vec4 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Vec4(self[0][0]*other[0] + self[1][0]*other[1] + self[2][0]*other[2] + self[3][0]*other[3],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[0][1]*other[0] + self[1][1]*other[1] + self[2][1]*other[2] + self[3][1]*other[3],
|
|
|
|
self[0][2]*other[0] + self[1][2]*other[1] + self[2][2]*other[2] + self[3][2]*other[3],
|
|
|
|
self[0][3]*other[0] + self[1][3]*other[1] + self[2][3]*other[2] + self[3][3]*other[3])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn add_m(other: &Mat4) -> Mat4 {
|
|
|
|
Mat4_v(&self[0].add_v(&other[0]),
|
|
|
|
&self[1].add_v(&other[1]),
|
|
|
|
&self[2].add_v(&other[2]),
|
|
|
|
&self[3].add_v(&other[3]))
|
2012-09-08 01:54:32 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn sub_m(other: &Mat4) -> Mat4 {
|
|
|
|
Mat4_v(&self[0].sub_v(&other[0]),
|
|
|
|
&self[1].sub_v(&other[1]),
|
|
|
|
&self[2].sub_v(&other[2]),
|
|
|
|
&self[3].sub_v(&other[3]))
|
2012-09-08 01:54:32 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn mul_m(other: &Mat4) -> Mat4 {
|
2012-09-24 02:54:24 +00:00
|
|
|
Mat4(self[0][0]*other[0][0] + self[1][0]*other[0][1] + self[2][0]*other[0][2] + self[3][0]*other[0][3],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[0][1]*other[0][0] + self[1][1]*other[0][1] + self[2][1]*other[0][2] + self[3][1]*other[0][3],
|
|
|
|
self[0][2]*other[0][0] + self[1][2]*other[0][1] + self[2][2]*other[0][2] + self[3][2]*other[0][3],
|
|
|
|
self[0][3]*other[0][0] + self[1][3]*other[0][1] + self[2][3]*other[0][2] + self[3][3]*other[0][3],
|
|
|
|
|
|
|
|
self[0][0]*other[1][0] + self[1][0]*other[1][1] + self[2][0]*other[1][2] + self[3][0]*other[1][3],
|
|
|
|
self[0][1]*other[1][0] + self[1][1]*other[1][1] + self[2][1]*other[1][2] + self[3][1]*other[1][3],
|
|
|
|
self[0][2]*other[1][0] + self[1][2]*other[1][1] + self[2][2]*other[1][2] + self[3][2]*other[1][3],
|
|
|
|
self[0][3]*other[1][0] + self[1][3]*other[1][1] + self[2][3]*other[1][2] + self[3][3]*other[1][3],
|
|
|
|
|
|
|
|
self[0][0]*other[2][0] + self[1][0]*other[2][1] + self[2][0]*other[2][2] + self[3][0]*other[2][3],
|
|
|
|
self[0][1]*other[2][0] + self[1][1]*other[2][1] + self[2][1]*other[2][2] + self[3][1]*other[2][3],
|
|
|
|
self[0][2]*other[2][0] + self[1][2]*other[2][1] + self[2][2]*other[2][2] + self[3][2]*other[2][3],
|
|
|
|
self[0][3]*other[2][0] + self[1][3]*other[2][1] + self[2][3]*other[2][2] + self[3][3]*other[2][3],
|
|
|
|
|
|
|
|
self[0][0]*other[3][0] + self[1][0]*other[3][1] + self[2][0]*other[3][2] + self[3][0]*other[3][3],
|
|
|
|
self[0][1]*other[3][0] + self[1][1]*other[3][1] + self[2][1]*other[3][2] + self[3][1]*other[3][3],
|
|
|
|
self[0][2]*other[3][0] + self[1][2]*other[3][1] + self[2][2]*other[3][2] + self[3][2]*other[3][3],
|
|
|
|
self[0][3]*other[3][0] + self[1][3]*other[3][1] + self[2][3]*other[3][2] + self[3][3]*other[3][3])
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO - inversion is harrrd D:
|
2012-09-24 02:54:24 +00:00
|
|
|
// #[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
// pure fn invert(other: &Mat4) -> Mat4 {}
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
|
|
|
pure fn transpose() -> Mat4 {
|
|
|
|
Mat4(self[0][0], self[1][0], self[2][0], self[3][0],
|
2012-09-07 10:48:47 +00:00
|
|
|
self[0][1], self[1][1], self[2][1], self[3][1],
|
|
|
|
self[0][2], self[1][2], self[2][2], self[3][2],
|
|
|
|
self[0][3], self[1][3], self[2][3], self[3][3])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn exact_eq(other: &Mat4) -> bool {
|
|
|
|
self[0].exact_eq(&other[0]) &&
|
|
|
|
self[1].exact_eq(&other[1]) &&
|
|
|
|
self[2].exact_eq(&other[2]) &&
|
|
|
|
self[3].exact_eq(&other[3])
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_identity() -> bool {
|
2012-09-29 10:25:49 +00:00
|
|
|
self.fuzzy_eq(&mat4_identity)
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_symmetric() -> bool {
|
|
|
|
self[0][1].fuzzy_eq(&self[1][0]) &&
|
|
|
|
self[0][2].fuzzy_eq(&self[2][0]) &&
|
|
|
|
self[0][3].fuzzy_eq(&self[3][0]) &&
|
|
|
|
|
|
|
|
self[1][0].fuzzy_eq(&self[0][1]) &&
|
|
|
|
self[1][2].fuzzy_eq(&self[2][1]) &&
|
|
|
|
self[1][3].fuzzy_eq(&self[3][1]) &&
|
|
|
|
|
|
|
|
self[2][0].fuzzy_eq(&self[0][2]) &&
|
|
|
|
self[2][1].fuzzy_eq(&self[1][2]) &&
|
|
|
|
self[2][3].fuzzy_eq(&self[3][2]) &&
|
|
|
|
|
|
|
|
self[3][0].fuzzy_eq(&self[0][3]) &&
|
|
|
|
self[3][1].fuzzy_eq(&self[1][3]) &&
|
|
|
|
self[3][2].fuzzy_eq(&self[2][3])
|
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_diagonal() -> bool {
|
2012-09-07 14:17:26 +00:00
|
|
|
self[0][1].fuzzy_eq(&0f) &&
|
|
|
|
self[0][2].fuzzy_eq(&0f) &&
|
|
|
|
self[0][3].fuzzy_eq(&0f) &&
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-07 14:17:26 +00:00
|
|
|
self[1][0].fuzzy_eq(&0f) &&
|
|
|
|
self[1][2].fuzzy_eq(&0f) &&
|
|
|
|
self[1][3].fuzzy_eq(&0f) &&
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-07 14:17:26 +00:00
|
|
|
self[2][0].fuzzy_eq(&0f) &&
|
|
|
|
self[2][1].fuzzy_eq(&0f) &&
|
|
|
|
self[2][3].fuzzy_eq(&0f) &&
|
2012-09-07 10:48:47 +00:00
|
|
|
|
2012-09-07 14:17:26 +00:00
|
|
|
self[3][0].fuzzy_eq(&0f) &&
|
|
|
|
self[3][1].fuzzy_eq(&0f) &&
|
|
|
|
self[3][2].fuzzy_eq(&0f)
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-09-07 10:48:47 +00:00
|
|
|
pure fn is_rotated() -> bool {
|
2012-09-29 10:25:49 +00:00
|
|
|
!self.fuzzy_eq(&mat4_identity)
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-29 08:41:48 +00:00
|
|
|
pub impl Mat4: Matrix4<Vec3, Vec4> {
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn scale(vec: &Vec3) -> Mat4 {
|
|
|
|
self.mul_m(&Mat4(vec.x(), 0f, 0f, 0f,
|
|
|
|
0f, vec.y(), 0f, 0f,
|
|
|
|
0f, 0f, vec.z(), 0f,
|
|
|
|
0f, 0f, 0f, 1f))
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 02:54:24 +00:00
|
|
|
#[inline]
|
2012-10-01 06:23:49 +00:00
|
|
|
pure fn translate(vec: &Vec3) -> Mat4 {
|
|
|
|
Mat4_v(&self[0],
|
|
|
|
&self[1],
|
|
|
|
&self[2],
|
|
|
|
&Vec4(self[3][0] + vec.x(),
|
|
|
|
self[3][1] + vec.y(),
|
|
|
|
self[3][2] + vec.z(),
|
|
|
|
self[3][3]))
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|
2012-09-29 10:25:49 +00:00
|
|
|
}
|
|
|
|
|
2012-09-29 10:37:46 +00:00
|
|
|
pub impl Mat4: Index<uint, Vec4> {
|
|
|
|
#[inline]
|
|
|
|
pure fn index(+i: uint) -> Vec4 {
|
|
|
|
self.data[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-29 10:25:49 +00:00
|
|
|
pub impl Mat4: Neg<Mat4> {
|
|
|
|
#[inline]
|
|
|
|
pure fn neg() -> Mat4 {
|
2012-10-01 06:23:49 +00:00
|
|
|
Mat4_v(&-self[0], &-self[1], &-self[2], &-self[3])
|
2012-09-29 10:25:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub impl Mat4: Eq {
|
|
|
|
#[inline]
|
|
|
|
pure fn eq(other: &Mat4) -> bool {
|
|
|
|
self.fuzzy_eq(other)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pure fn ne(other: &Mat4) -> bool {
|
|
|
|
!(self == *other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub impl Mat4: FuzzyEq {
|
|
|
|
#[inline]
|
|
|
|
pure fn fuzzy_eq(other: &Mat4) -> bool {
|
|
|
|
self[0].fuzzy_eq(&other[0]) &&
|
|
|
|
self[1].fuzzy_eq(&other[1]) &&
|
|
|
|
self[2].fuzzy_eq(&other[2]) &&
|
|
|
|
self[3].fuzzy_eq(&other[3])
|
|
|
|
}
|
2012-09-07 10:48:47 +00:00
|
|
|
}
|