cgmath/src/mat.rs

708 lines
19 KiB
Rust
Raw Normal View History

use std::cmp::FuzzyEq;
2012-09-29 10:25:49 +00:00
use cmp::Eq;
use ops::Neg;
// 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;
pure fn index(&&index:uint) -> V;
pure fn row(&&i:uint) -> V;
pure fn col(&&i:uint) -> V;
pure fn mul_f(&&value:T) -> self;
pure fn mul_v(&&other:V) -> V;
2012-09-08 01:54:32 +00:00
pure fn add_m(&&other:self) -> self;
pure fn sub_m(&&other:self) -> self;
2012-09-07 10:48:47 +00:00
pure fn mul_m(&&other:self) -> self;
// pure fn invert(&&other:self) -> self;
pure fn transpose() -> self;
pure fn exact_eq(&&other:self) -> bool;
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-09-10 02:55:15 +00:00
pure fn scale(&&vec:V3) -> self;
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> {
pure fn scale(&&vec:V3) -> self; // I don't like the use of `Vec3` here
2012-09-10 02:55:15 +00:00
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
//
#[inline]
2012-09-29 08:41:48 +00:00
pub pure fn Mat2(m00:float, m01:float,
m10:float, m11:float) -> Mat2 {
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
//
#[inline]
2012-09-29 08:41:48 +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> {
#[inline]
2012-09-07 10:48:47 +00:00
pure fn rows() -> uint { 2 }
#[inline]
2012-09-07 10:48:47 +00:00
pure fn cols() -> uint { 2 }
#[inline]
2012-09-07 10:48:47 +00:00
pure fn is_col_major() -> bool { true }
#[inline]
pure fn index(&&i: uint) -> Vec2 {
2012-09-07 10:48:47 +00:00
self.data[i]
}
#[inline]
pure fn row(&&i:uint) -> Vec2 {
Vec2(self[0][i],
2012-09-07 10:48:47 +00:00
self[1][i])
}
#[inline]
pure fn col(&&i:uint) -> Vec2 {
2012-09-07 10:48:47 +00:00
self.data[i]
}
#[inline]
pure fn mul_f(&&value:float) -> Mat2 {
2012-09-29 08:41:48 +00:00
Mat2_v(self[0].mul_f(value),
2012-09-07 10:48:47 +00:00
self[1].mul_f(value))
}
#[inline]
pure fn mul_v(&&other:Vec2) -> Vec2 {
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])
}
#[inline]
pure fn add_m(&&other:Mat2) -> Mat2 {
2012-09-29 08:41:48 +00:00
Mat2_v(self[0].add_v(other[0]),
2012-09-08 01:54:32 +00:00
self[1].add_v(other[1]))
}
#[inline]
pure fn sub_m(&&other:Mat2) -> Mat2 {
2012-09-29 08:41:48 +00:00
Mat2_v(self[0].sub_v(other[0]),
2012-09-08 01:54:32 +00:00
self[1].sub_v(other[1]))
}
#[inline]
pure fn mul_m(&&other:Mat2) -> Mat2 {
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:
// #[inline]
// pure fn invert(&&other:Mat2) -> Mat2 {}
2012-09-07 10:48:47 +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])
}
#[inline]
pure fn exact_eq(&&other:Mat2) -> bool {
2012-09-07 10:48:47 +00:00
self[0].exact_eq(other[0]) &&
self[1].exact_eq(other[1])
}
#[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
}
#[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])
}
#[inline]
2012-09-07 10:48:47 +00:00
pure fn is_diagonal() -> bool {
self[0][1].fuzzy_eq(&0f) &&
self[1][0].fuzzy_eq(&0f)
2012-09-07 10:48:47 +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)
}
}
pub impl Mat2: Neg<Mat2> {
#[inline]
pure fn neg() -> Mat2 {
Mat2_v(-self[0], -self[1])
}
}
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
//
#[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 {
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
//
#[inline]
2012-09-29 08:41:48 +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> {
#[inline]
2012-09-07 10:48:47 +00:00
pure fn rows() -> uint { 3 }
#[inline]
2012-09-07 10:48:47 +00:00
pure fn cols() -> uint { 3 }
#[inline]
2012-09-07 10:48:47 +00:00
pure fn is_col_major() -> bool { true }
#[inline]
pure fn index(&&i: uint) -> Vec3 {
2012-09-07 10:48:47 +00:00
self.data[i]
}
#[inline]
pure fn row(&&i:uint) -> Vec3 {
Vec3(self[0][i],
2012-09-07 10:48:47 +00:00
self[1][i],
self[2][i])
}
#[inline]
pure fn col(&&i:uint) -> Vec3 {
2012-09-07 10:48:47 +00:00
self.data[i]
}
#[inline]
pure fn mul_f(&&value:float) -> Mat3 {
2012-09-29 08:41:48 +00:00
Mat3_v(self[0].mul_f(value),
2012-09-07 10:48:47 +00:00
self[1].mul_f(value),
self[2].mul_f(value))
}
#[inline]
pure fn mul_v(&&other:Vec3) -> Vec3 {
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])
}
#[inline]
pure fn add_m(&&other:Mat3) -> Mat3 {
2012-09-29 08:41:48 +00:00
Mat3_v(self[0].add_v(other[0]),
2012-09-08 01:54:32 +00:00
self[1].add_v(other[1]),
self[2].add_v(other[2]))
}
#[inline]
pure fn sub_m(&&other:Mat3) -> Mat3 {
2012-09-29 08:41:48 +00:00
Mat3_v(self[0].sub_v(other[0]),
2012-09-08 01:54:32 +00:00
self[1].sub_v(other[1]),
self[2].sub_v(other[2]))
}
#[inline]
pure fn mul_m(&&other:Mat3) -> Mat3 {
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:
// #[inline]
// pure fn invert(&&other:Mat3) -> Mat3 {}
2012-09-07 10:48:47 +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])
}
#[inline]
pure fn exact_eq(&&other:Mat3) -> bool {
2012-09-07 10:48:47 +00:00
self[0].exact_eq(other[0]) &&
self[1].exact_eq(other[1]) &&
self[2].exact_eq(other[2])
}
#[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
}
#[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])
}
#[inline]
2012-09-07 10:48:47 +00:00
pure fn is_diagonal() -> bool {
self[0][1].fuzzy_eq(&0f) &&
self[0][2].fuzzy_eq(&0f) &&
2012-09-07 10:48:47 +00:00
self[1][0].fuzzy_eq(&0f) &&
self[1][2].fuzzy_eq(&0f) &&
2012-09-07 10:48:47 +00:00
self[2][0].fuzzy_eq(&0f) &&
self[2][1].fuzzy_eq(&0f)
2012-09-07 10:48:47 +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> {
#[inline]
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
}
#[inline]
pure fn to_Mat4() -> Mat4 {
Mat4(self[0][0], self[0][1], self[0][2], 0f,
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
}
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
// paper on Quaternions: http://www.cs.ucr.edu/~vbz/resources/Quatut.pdf
2012-09-07 10:48:47 +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];
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;
}
return Quat(w, x, y, z);
2012-09-07 10:48:47 +00:00
}
}
2012-09-29 10:25:49 +00:00
pub impl Mat3: Neg<Mat3> {
#[inline]
pure fn neg() -> Mat3 {
Mat3_v(-self[0], -self[1], -self[2])
}
}
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
//
#[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,
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
//
#[inline]
2012-09-29 08:41:48 +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> {
#[inline]
2012-09-07 10:48:47 +00:00
pure fn rows() -> uint { 4 }
#[inline]
2012-09-07 10:48:47 +00:00
pure fn cols() -> uint { 4 }
#[inline]
2012-09-07 10:48:47 +00:00
pure fn is_col_major() -> bool { true }
#[inline]
pure fn index(&&i: uint) -> Vec4 {
2012-09-07 10:48:47 +00:00
self.data[i]
}
#[inline]
pure fn row(&&i:uint) -> Vec4 {
Vec4(self[0][i],
2012-09-07 10:48:47 +00:00
self[1][i],
self[2][i],
self[3][i])
}
#[inline]
pure fn col(&&i:uint) -> Vec4 {
2012-09-07 10:48:47 +00:00
self.data[i]
}
#[inline]
pure fn mul_f(&&value:float) -> Mat4 {
2012-09-29 08:41:48 +00:00
Mat4_v(self[0].mul_f(value),
2012-09-07 10:48:47 +00:00
self[1].mul_f(value),
self[2].mul_f(value),
self[3].mul_f(value))
}
#[inline]
pure fn mul_v(&&other:Vec4) -> Vec4 {
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])
}
#[inline]
pure fn add_m(&&other:Mat4) -> Mat4 {
2012-09-29 08:41:48 +00:00
Mat4_v(self[0].add_v(other[0]),
2012-09-08 01:54:32 +00:00
self[1].add_v(other[1]),
self[2].add_v(other[2]),
self[3].add_v(other[3]))
}
#[inline]
pure fn sub_m(&&other:Mat4) -> Mat4 {
2012-09-29 08:41:48 +00:00
Mat4_v(self[0].sub_v(other[0]),
2012-09-08 01:54:32 +00:00
self[1].sub_v(other[1]),
self[2].sub_v(other[2]),
self[3].sub_v(other[3]))
}
#[inline]
pure fn mul_m(&&other:Mat4) -> Mat4 {
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:
// #[inline]
// pure fn invert(&&other:Mat4) -> Mat4 {}
2012-09-07 10:48:47 +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])
}
#[inline]
pure fn exact_eq(&&other:Mat4) -> bool {
2012-09-07 10:48:47 +00:00
self[0].exact_eq(other[0]) &&
self[1].exact_eq(other[1]) &&
self[2].exact_eq(other[2]) &&
self[3].exact_eq(other[3])
}
#[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
}
#[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])
}
#[inline]
2012-09-07 10:48:47 +00:00
pure fn is_diagonal() -> bool {
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
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
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
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
}
#[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> {
#[inline]
pure fn scale(&&vec:Vec3) -> Mat4 {
self.mul_m(Mat4(vec.x(), 0f, 0f, 0f,
2012-09-08 02:41:04 +00:00
0f, vec.y(), 0f, 0f,
0f, 0f, vec.z(), 0f,
0f, 0f, 0f, 1f))
2012-09-07 10:48:47 +00:00
}
#[inline]
pure fn translate(&&vec:Vec3) -> Mat4 {
2012-09-29 08:41:48 +00:00
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
}
pub impl Mat4: Neg<Mat4> {
#[inline]
pure fn neg() -> Mat4 {
Mat4_v(-self[0], -self[1], -self[2], -self[3])
}
}
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
}