Convert vector arrays to separate fields in matrix types

This commit is contained in:
Brendan Zabarauskas 2012-11-02 00:06:12 +10:00
parent 25de081805
commit 12498701a1
2 changed files with 74 additions and 62 deletions

View file

@ -1,6 +1,9 @@
use std::cmp::FuzzyEq; use cast::transmute;
use cmp::Eq; use cmp::Eq;
use num::from_int; use num::from_int;
use ptr::to_unsafe_ptr;
use vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use math::*; use math::*;
use num_util::*; use num_util::*;
@ -15,8 +18,8 @@ pub trait Matrix<T, V> {
pure fn cols() -> uint; pure fn cols() -> uint;
pure fn is_col_major() -> bool; pure fn is_col_major() -> bool;
pure fn row(i: uint) -> V;
pure fn col(i: uint) -> V; pure fn col(i: uint) -> V;
pure fn row(i: uint) -> V;
pure fn mul_t(value: T) -> self; pure fn mul_t(value: T) -> self;
pure fn mul_v(other: &V) -> V; pure fn mul_v(other: &V) -> V;
@ -57,7 +60,7 @@ pub trait Matrix4<T> {
// //
// Mat2: A 2x2, column major matrix // Mat2: A 2x2, column major matrix
// //
pub struct Mat2<T> { data:[Vec2<T> * 2] } pub struct Mat2<T> { x: Vec2<T>, y: Vec2<T> }
pub mod Mat2 { pub mod Mat2 {
@ -70,19 +73,20 @@ pub mod Mat2 {
#[inline(always)] #[inline(always)]
pub pure fn from_cols<T:Copy>(col0: &Vec2<T>, col1: &Vec2<T>) -> Mat2<T> { pub pure fn from_cols<T:Copy>(col0: &Vec2<T>, col1: &Vec2<T>) -> Mat2<T> {
Mat2 { data: [ *col0, *col1 ] } Mat2 { x: *col0,
y: *col1 }
} }
#[inline(always)] #[inline(always)]
pub pure fn zero<T:Copy Num>() -> Mat2<T> { pub pure fn zero<T:Copy Num>() -> Mat2<T> {
Mat2 { data: [ Vec2::zero(), Mat2 { x: Vec2::zero(),
Vec2::zero() ] } y: Vec2::zero() }
} }
#[inline(always)] #[inline(always)]
pub pure fn identity<T:Copy Num>() -> Mat2<T> { pub pure fn identity<T:Copy Num>() -> Mat2<T> {
Mat2 { data: [ Vec2::unit_x(), Mat2 { x: Vec2::unit_x(),
Vec2::unit_y() ] } y: Vec2::unit_y() }
} }
} }
@ -96,17 +100,15 @@ pub impl<T:Copy Num Sqrt FuzzyEq> Mat2<T>: Matrix<T, Vec2<T>> {
#[inline(always)] #[inline(always)]
pure fn is_col_major() -> bool { true } pure fn is_col_major() -> bool { true }
#[inline(always)]
pure fn col(i: uint) -> Vec2<T> { self[i] }
#[inline(always)] #[inline(always)]
pure fn row(i: uint) -> Vec2<T> { pure fn row(i: uint) -> Vec2<T> {
Vec2::new(self[0][i], Vec2::new(self[0][i],
self[1][i]) self[1][i])
} }
#[inline(always)]
pure fn col(i: uint) -> Vec2<T> {
self.data[i]
}
#[inline(always)] #[inline(always)]
pure fn mul_t(value: T) -> Mat2<T> { pure fn mul_t(value: T) -> Mat2<T> {
Mat2::from_cols(&self[0].mul_t(value), Mat2::from_cols(&self[0].mul_t(value),
@ -176,7 +178,10 @@ pub impl<T:Copy Num Sqrt FuzzyEq> Mat2<T>: Matrix<T, Vec2<T>> {
pub impl<T:Copy> Mat2<T>: Index<uint, Vec2<T>> { pub impl<T:Copy> Mat2<T>: Index<uint, Vec2<T>> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> Vec2<T> { pure fn index(i: uint) -> Vec2<T> {
self.data[i] unsafe { do buf_as_slice(
transmute::<*Mat2<T>, *Vec2<T>>(
to_unsafe_ptr(&self)), 2) |slice| { slice[i] }
}
} }
} }
@ -224,7 +229,7 @@ pub impl<T:Copy FuzzyEq> Mat2<T>: FuzzyEq {
// //
// Mat3: A 3x3, column major matrix // Mat3: A 3x3, column major matrix
// //
pub struct Mat3<T> { data:[Vec3<T> * 3] } pub struct Mat3<T> { x: Vec3<T>, y: Vec3<T>, z: Vec3<T> }
pub mod Mat3 { pub mod Mat3 {
@ -239,21 +244,23 @@ pub mod Mat3 {
#[inline(always)] #[inline(always)]
pub pure fn from_cols<T:Copy>(col0: &Vec3<T>, col1: &Vec3<T>, col2: &Vec3<T>) -> Mat3<T> { pub pure fn from_cols<T:Copy>(col0: &Vec3<T>, col1: &Vec3<T>, col2: &Vec3<T>) -> Mat3<T> {
Mat3 { data: [ *col0, *col1, *col2 ] } Mat3 { x: *col0,
y: *col1,
z: *col2 }
} }
#[inline(always)] #[inline(always)]
pub pure fn zero<T:Num>() -> Mat3<T> { pub pure fn zero<T:Num>() -> Mat3<T> {
Mat3 { data: [ Vec3::zero(), Mat3 { x: Vec3::zero(),
Vec3::zero(), y: Vec3::zero(),
Vec3::zero() ] } z: Vec3::zero() }
} }
#[inline(always)] #[inline(always)]
pub pure fn identity<T:Num>() -> Mat3<T> { pub pure fn identity<T:Num>() -> Mat3<T> {
Mat3 { data: [ Vec3::unit_x(), Mat3 { x: Vec3::unit_x(),
Vec3::unit_y(), y: Vec3::unit_y(),
Vec3::unit_z() ] } z: Vec3::unit_z() }
} }
} }
@ -267,6 +274,9 @@ pub impl<T:Copy Num Sqrt FuzzyEq> Mat3<T>: Matrix<T, Vec3<T>> {
#[inline(always)] #[inline(always)]
pure fn is_col_major() -> bool { true } pure fn is_col_major() -> bool { true }
#[inline(always)]
pure fn col(i: uint) -> Vec3<T> { self[i] }
#[inline(always)] #[inline(always)]
pure fn row(i: uint) -> Vec3<T> { pure fn row(i: uint) -> Vec3<T> {
Vec3::new(self[0][i], Vec3::new(self[0][i],
@ -274,11 +284,6 @@ pub impl<T:Copy Num Sqrt FuzzyEq> Mat3<T>: Matrix<T, Vec3<T>> {
self[2][i]) self[2][i])
} }
#[inline(always)]
pure fn col(i: uint) -> Vec3<T> {
self.data[i]
}
#[inline(always)] #[inline(always)]
pure fn mul_t(value: T) -> Mat3<T> { pure fn mul_t(value: T) -> Mat3<T> {
Mat3::from_cols(&self[0].mul_t(value), Mat3::from_cols(&self[0].mul_t(value),
@ -431,7 +436,10 @@ pub impl<T:Copy Num NumCast Ord> Mat3<T>: ToQuat<T> {
pub impl<T:Copy> Mat3<T>: Index<uint, Vec3<T>> { pub impl<T:Copy> Mat3<T>: Index<uint, Vec3<T>> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> Vec3<T> { pure fn index(i: uint) -> Vec3<T> {
self.data[i] unsafe { do buf_as_slice(
transmute::<*Mat3<T>, *Vec3<T>>(
to_unsafe_ptr(&self)), 3) |slice| { slice[i] }
}
} }
} }
@ -488,7 +496,7 @@ pub impl<T:Copy> Mat3<T>: ToPtr<T> {
// //
// Mat4: A 4x4, column major matrix // Mat4: A 4x4, column major matrix
// //
pub struct Mat4<T> { data:[Vec4<T> * 4] } pub struct Mat4<T> { x: Vec4<T>, y: Vec4<T>, z: Vec4<T>, w: Vec4<T> }
pub mod Mat4 { pub mod Mat4 {
@ -505,23 +513,26 @@ pub mod Mat4 {
#[inline(always)] #[inline(always)]
pub pure fn from_cols<T:Copy>(col0: &Vec4<T>, col1: &Vec4<T>, col2: &Vec4<T>, col3: &Vec4<T>) -> Mat4<T> { pub pure fn from_cols<T:Copy>(col0: &Vec4<T>, col1: &Vec4<T>, col2: &Vec4<T>, col3: &Vec4<T>) -> Mat4<T> {
Mat4 { data: [ *col0, *col1, *col2, *col3 ] } Mat4 { x: *col0,
y: *col1,
z: *col2,
w: *col3 }
} }
#[inline(always)] #[inline(always)]
pub pure fn zero<T:Num>() -> Mat4<T> { pub pure fn zero<T:Num>() -> Mat4<T> {
Mat4 { data: [ Vec4::zero(), Mat4 { x: Vec4::zero(),
Vec4::zero(), y: Vec4::zero(),
Vec4::zero(), z: Vec4::zero(),
Vec4::zero() ] } w: Vec4::zero() }
} }
#[inline(always)] #[inline(always)]
pub pure fn identity<T:Num>() -> Mat4<T> { pub pure fn identity<T:Num>() -> Mat4<T> {
Mat4 { data: [ Vec4::unit_x(), Mat4 { x: Vec4::unit_x(),
Vec4::unit_y(), y: Vec4::unit_y(),
Vec4::unit_z(), z: Vec4::unit_z(),
Vec4::unit_w() ] } w: Vec4::unit_w() }
} }
} }
@ -535,6 +546,9 @@ pub impl<T:Copy Num Sqrt FuzzyEq> Mat4<T>: Matrix<T, Vec4<T>> {
#[inline(always)] #[inline(always)]
pure fn is_col_major() -> bool { true } pure fn is_col_major() -> bool { true }
#[inline(always)]
pure fn col(i: uint) -> Vec4<T> { self[i] }
#[inline(always)] #[inline(always)]
pure fn row(i: uint) -> Vec4<T> { pure fn row(i: uint) -> Vec4<T> {
Vec4::new(self[0][i], Vec4::new(self[0][i],
@ -543,11 +557,6 @@ pub impl<T:Copy Num Sqrt FuzzyEq> Mat4<T>: Matrix<T, Vec4<T>> {
self[3][i]) self[3][i])
} }
#[inline(always)]
pure fn col(i: uint) -> Vec4<T> {
self.data[i]
}
#[inline(always)] #[inline(always)]
pure fn mul_t(value: T) -> Mat4<T> { pure fn mul_t(value: T) -> Mat4<T> {
Mat4::from_cols(&self[0].mul_t(value), Mat4::from_cols(&self[0].mul_t(value),
@ -688,7 +697,10 @@ pub impl<T:Copy Num Sqrt FuzzyEq> Mat4<T>: Matrix4<T> {
pub impl<T:Copy> Mat4<T>: Index<uint, Vec4<T>> { pub impl<T:Copy> Mat4<T>: Index<uint, Vec4<T>> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> Vec4<T> { pure fn index(i: uint) -> Vec4<T> {
self.data[i] unsafe { do buf_as_slice(
transmute::<*Mat4<T>, *Vec4<T>>(
to_unsafe_ptr(&self)), 4) |slice| { slice[i] }
}
} }
} }

View file

@ -5,10 +5,10 @@ use vector::*;
#[test] #[test]
fn test_Mat2() { fn test_Mat2() {
let a = Mat2 { data: [ Vec2 { x: 1f, y: 3f }, let a = Mat2 { x: Vec2 { x: 1f, y: 3f },
Vec2 { x: 2f, y: 4f } ] }; y: Vec2 { x: 2f, y: 4f } };
let b = Mat2 { data: [ Vec2 { x: 2f, y: 4f }, let b = Mat2 { x: Vec2 { x: 2f, y: 4f },
Vec2 { x: 3f, y: 5f } ] }; y: Vec2 { x: 3f, y: 5f } };
let v1 = Vec2::new(1f, 2f); let v1 = Vec2::new(1f, 2f);
let f1 = 0.5f; let f1 = 0.5f;
@ -69,12 +69,12 @@ fn test_Mat2() {
#[test] #[test]
fn test_Mat3() { fn test_Mat3() {
let a = Mat3 { data: [ Vec3 { x: 1f, y: 4f, z: 7f }, let a = Mat3 { x: Vec3 { x: 1f, y: 4f, z: 7f },
Vec3 { x: 2f, y: 5f, z: 8f }, y: Vec3 { x: 2f, y: 5f, z: 8f },
Vec3 { x: 3f, y: 6f, z: 9f } ] }; z: Vec3 { x: 3f, y: 6f, z: 9f } };
let b = Mat3 { data: [ Vec3 { x: 2f, y: 5f, z: 8f }, let b = Mat3 { x: Vec3 { x: 2f, y: 5f, z: 8f },
Vec3 { x: 3f, y: 6f, z: 9f }, y: Vec3 { x: 3f, y: 6f, z: 9f },
Vec3 { x: 4f, y: 7f, z: 10f } ] }; z: Vec3 { x: 4f, y: 7f, z: 10f } };
let v1 = Vec3::new(1f, 2f, 3f); let v1 = Vec3::new(1f, 2f, 3f);
let f1 = 0.5f; let f1 = 0.5f;
@ -154,14 +154,14 @@ fn test_Mat3() {
#[test] #[test]
fn test_Mat4() { fn test_Mat4() {
let a = Mat4 { data: [ Vec4 { x: 1f, y: 5f, z: 9f, w: 13f }, let a = Mat4 { x: Vec4 { x: 1f, y: 5f, z: 9f, w: 13f },
Vec4 { x: 2f, y: 6f, z: 10f, w: 14f }, y: Vec4 { x: 2f, y: 6f, z: 10f, w: 14f },
Vec4 { x: 3f, y: 7f, z: 11f, w: 15f }, z: Vec4 { x: 3f, y: 7f, z: 11f, w: 15f },
Vec4 { x: 4f, y: 8f, z: 12f, w: 16f } ] }; w: Vec4 { x: 4f, y: 8f, z: 12f, w: 16f } };
let b = Mat4 { data: [ Vec4 { x: 2f, y: 6f, z: 10f, w: 14f }, let b = Mat4 { x: Vec4 { x: 2f, y: 6f, z: 10f, w: 14f },
Vec4 { x: 3f, y: 7f, z: 11f, w: 15f }, y: Vec4 { x: 3f, y: 7f, z: 11f, w: 15f },
Vec4 { x: 4f, y: 8f, z: 12f, w: 16f }, z: Vec4 { x: 4f, y: 8f, z: 12f, w: 16f },
Vec4 { x: 5f, y: 9f, z: 13f, w: 17f } ] }; w: Vec4 { x: 5f, y: 9f, z: 13f, w: 17f } };
let v1 = Vec4::new(1f, 2f, 3f, 4f); let v1 = Vec4::new(1f, 2f, 3f, 4f);
let f1 = 0.5f; let f1 = 0.5f;