Merge pull request #114 from bjz/array-stuff

Array stuff
This commit is contained in:
Corey Richardson 2014-08-11 08:16:51 -04:00
commit 4a45bf3b53
5 changed files with 407 additions and 168 deletions

View file

@ -28,30 +28,30 @@ pub trait Array1<Element: Copy>: Index<uint, Element> + IndexMut<uint, Element>
&mut (*self)[0] &mut (*self)[0]
} }
/// Get a shared reference to the `i`th value. #[deprecated = "Use `Array1::swap_elems` instead"]
#[deprecated = "Use index operator instead"]
#[inline]
fn i<'a>(&'a self, i: uint) -> &'a Element {
&(*self)[i]
}
/// Get a mutable reference to the `i`th value.
#[deprecated = "Use index operator instead"]
#[inline]
fn mut_i<'a>(&'a mut self, i: uint) -> &'a mut Element {
&mut (*self)[i]
}
#[inline] #[inline]
/// Swap the elements at indices `i` and `j` in-place. /// Swap the elements at indices `i` and `j` in-place.
fn swap_i(&mut self, i: uint, j: uint) { fn swap_i(&mut self, i: uint, j: uint) {
self.swap_i(i, j)
}
/// Swap the elements at indices `i` and `j` in-place.
#[inline]
fn swap_elems(&mut self, i: uint, j: uint) {
// Yeah, ok borrow checker I know what I'm doing here // Yeah, ok borrow checker I know what I'm doing here
unsafe { ptr::swap(&mut (*self)[i], &mut (*self)[j]) }; unsafe { ptr::swap(&mut (*self)[i], &mut (*self)[j]) };
} }
/// Replace an element in the array. /// Replace an element in the array.
#[deprecated = "Use `Array1::replace_elem` instead"]
#[inline] #[inline]
fn replace_i(&mut self, i: uint, src: Element) -> Element { fn replace_i(&mut self, i: uint, src: Element) -> Element {
self.replace_i(i, src)
}
/// Replace an element in the array.
#[inline]
fn replace_elem(&mut self, i: uint, src: Element) -> Element {
mem::replace(&mut (*self)[i], src) mem::replace(&mut (*self)[i], src)
} }
@ -72,55 +72,61 @@ pub trait Array2<Column: Array1<Element>, Row: Array1<Element>, Element: Copy>:
&mut (*self)[0][0] &mut (*self)[0][0]
} }
/// Get a shared reference to a column of this array. /// Swap two columns of this array.
#[deprecated = "Use index operator instead"] #[deprecated = "Use `Array2::swap_cols` instead"]
#[inline] #[inline]
fn c<'a>(&'a self, c: uint) -> &'a Column { fn swap_c(&mut self, a: uint, b: uint) {
&(*self)[c] self.swap_cols(a, b)
}
/// Get a mutable reference to a column of this array.
#[deprecated = "Use index operator instead"]
#[inline]
fn mut_c<'a>(&'a mut self, c: uint) -> &'a mut Column {
&mut (*self)[c]
} }
/// Swap two columns of this array. /// Swap two columns of this array.
#[inline] #[inline]
fn swap_c(&mut self, a: uint, b: uint) { fn swap_cols(&mut self, a: uint, b: uint) {
unsafe { ptr::swap(&mut (*self)[a], &mut (*self)[b]) }; unsafe { ptr::swap(&mut (*self)[a], &mut (*self)[b]) };
} }
/// Replace a column in the array. /// Replace a column in the array.
#[deprecated = "Use `Array2::replace_col` instead"]
#[inline] #[inline]
fn replace_c(&mut self, c: uint, src: Column) -> Column { fn replace_c(&mut self, c: uint, src: Column) -> Column {
self.replace_col(c, src)
}
/// Replace a column in the array.
#[inline]
fn replace_col(&mut self, c: uint, src: Column) -> Column {
mem::replace(&mut (*self)[c], src) mem::replace(&mut (*self)[c], src)
} }
/// Get a row from this array by-value. /// Get a row from this array by-value.
fn r(&self, r: uint) -> Row; #[deprecated = "Use `Array2::row` instead"]
/// Swap two rows of this array.
fn swap_r(&mut self, a: uint, b: uint);
/// Return a shared reference to the element at column `c` and row `r`.
#[deprecated = "Use index operators instead"]
#[inline] #[inline]
fn cr<'a>(&'a self, c: uint, r: uint) -> &'a Element { fn r(&self, r: uint) -> Row {
&(*self)[c][r] self.row(r)
} }
/// Return a mutable reference to the element at column `c` and row `r`. /// Get a row from this array by-value.
#[deprecated = "Use index operators instead"] fn row(&self, r: uint) -> Row;
#[deprecated = "Use `Array2::swap_rows` instead"]
#[inline] #[inline]
fn mut_cr<'a>(&'a mut self, c: uint, r: uint) -> &'a mut Element { fn swap_r(&mut self, a: uint, b: uint) {
&mut (*self)[c][r] self.swap_rows(a, b)
}
/// Swap two rows of this array.
fn swap_rows(&mut self, a: uint, b: uint);
/// Swap the values at index `a` and `b`
#[deprecated = "Use `Array2::swap_elems` instead"]
#[inline]
fn swap_cr(&mut self, a: (uint, uint), b: (uint, uint)) {
self.swap_elems(a, b)
} }
/// Swap the values at index `a` and `b` /// Swap the values at index `a` and `b`
#[inline] #[inline]
fn swap_cr(&mut self, a: (uint, uint), b: (uint, uint)) { fn swap_elems(&mut self, a: (uint, uint), b: (uint, uint)) {
let (ac, ar) = a; let (ac, ar) = a;
let (bc, br) = b; let (bc, br) = b;
unsafe { ptr::swap(&mut (*self)[ac][ar], &mut (*self)[bc][br]) }; unsafe { ptr::swap(&mut (*self)[ac][ar], &mut (*self)[bc][br]) };
@ -129,3 +135,14 @@ pub trait Array2<Column: Array1<Element>, Row: Array1<Element>, Element: Copy>:
/// Apply a function to each column. /// Apply a function to each column.
fn map(&mut self, op: |&Column| -> Column) -> Self; fn map(&mut self, op: |&Column| -> Column) -> Self;
} }
/// Homogeneous arrays of elements that can be converted to and from `[T, ..N]`
/// arrays.
pub trait FixedArray<V> {
fn into_fixed(self) -> V;
fn as_fixed<'a>(&'a self) -> &'a V;
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut V;
fn from_fixed(v: V) -> Self;
fn from_fixed_ref<'a>(v: &'a V) -> &'a Self;
fn from_fixed_mut<'a>(v: &'a mut V) -> &'a mut Self;
}

View file

@ -50,12 +50,12 @@ Frustum<S> {
/// Extracts frustum planes from a projection matrix /// Extracts frustum planes from a projection matrix
pub fn from_matrix4(mat: Matrix4<S>) -> Frustum<S> { pub fn from_matrix4(mat: Matrix4<S>) -> Frustum<S> {
Frustum::new(Plane::from_vector4(mat.r(3).add_v(&mat.r(0)).normalize()), Frustum::new(Plane::from_vector4(mat.row(3).add_v(&mat.row(0)).normalize()),
Plane::from_vector4(mat.r(3).sub_v(&mat.r(0)).normalize()), Plane::from_vector4(mat.row(3).sub_v(&mat.row(0)).normalize()),
Plane::from_vector4(mat.r(3).add_v(&mat.r(1)).normalize()), Plane::from_vector4(mat.row(3).add_v(&mat.row(1)).normalize()),
Plane::from_vector4(mat.r(3).sub_v(&mat.r(1)).normalize()), Plane::from_vector4(mat.row(3).sub_v(&mat.row(1)).normalize()),
Plane::from_vector4(mat.r(3).add_v(&mat.r(2)).normalize()), Plane::from_vector4(mat.row(3).add_v(&mat.row(2)).normalize()),
Plane::from_vector4(mat.r(3).sub_v(&mat.r(2)).normalize())) Plane::from_vector4(mat.row(3).sub_v(&mat.row(2)).normalize()))
} }
} }

View file

@ -21,7 +21,7 @@ use std::num::{Zero, zero, One, one, cast};
use angle::{Rad, sin, cos, sin_cos}; use angle::{Rad, sin, cos, sin_cos};
use approx::ApproxEq; use approx::ApproxEq;
use array::{Array1, Array2}; use array::{Array1, Array2, FixedArray};
use num::{BaseFloat, BaseNum}; use num::{BaseFloat, BaseNum};
use point::{Point, Point3}; use point::{Point, Point3};
use quaternion::{Quaternion, ToQuaternion}; use quaternion::{Quaternion, ToQuaternion};
@ -209,7 +209,7 @@ Matrix3<S> {
_1subc * axis.z * axis.z + c) _1subc * axis.z * axis.z + c)
} }
/// Create a matrix from a non-uniform scale /// Create a matrix from a non-uniform scale
pub fn from_diagonal(value: &Vector3<S>) -> Matrix3<S> { pub fn from_diagonal(value: &Vector3<S>) -> Matrix3<S> {
Matrix3::new(value.x, zero(), zero(), Matrix3::new(value.x, zero(), zero(),
zero(), value.y, zero(), zero(), value.y, zero(),
@ -377,9 +377,9 @@ impl<S: BaseFloat> Sub<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn sub
impl<S: BaseFloat> Sub<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn sub(&self, other: &Matrix3<S>) -> Matrix3<S> { self.sub_m(other) } } impl<S: BaseFloat> Sub<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn sub(&self, other: &Matrix3<S>) -> Matrix3<S> { self.sub_m(other) } }
impl<S: BaseFloat> Sub<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn sub(&self, other: &Matrix4<S>) -> Matrix4<S> { self.sub_m(other) } } impl<S: BaseFloat> Sub<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn sub(&self, other: &Matrix4<S>) -> Matrix4<S> { self.sub_m(other) } }
impl<S: BaseFloat> Neg<Matrix2<S>> for Matrix2<S> { #[inline] fn neg(&self) -> Matrix2<S> { Matrix2::from_cols(self.c(0).neg(), self.c(1).neg()) } } impl<S: BaseFloat> Neg<Matrix2<S>> for Matrix2<S> { #[inline] fn neg(&self) -> Matrix2<S> { Matrix2::from_cols(self[0].neg(), self[1].neg()) } }
impl<S: BaseFloat> Neg<Matrix3<S>> for Matrix3<S> { #[inline] fn neg(&self) -> Matrix3<S> { Matrix3::from_cols(self.c(0).neg(), self.c(1).neg(), self.c(2).neg()) } } impl<S: BaseFloat> Neg<Matrix3<S>> for Matrix3<S> { #[inline] fn neg(&self) -> Matrix3<S> { Matrix3::from_cols(self[0].neg(), self[1].neg(), self[2].neg()) } }
impl<S: BaseFloat> Neg<Matrix4<S>> for Matrix4<S> { #[inline] fn neg(&self) -> Matrix4<S> { Matrix4::from_cols(self.c(0).neg(), self.c(1).neg(), self.c(2).neg(), self.c(3).neg()) } } impl<S: BaseFloat> Neg<Matrix4<S>> for Matrix4<S> { #[inline] fn neg(&self) -> Matrix4<S> { Matrix4::from_cols(self[0].neg(), self[1].neg(), self[2].neg(), self[3].neg()) } }
impl<S: BaseFloat> Zero for Matrix2<S> { #[inline] fn zero() -> Matrix2<S> { Matrix2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } impl<S: BaseFloat> Zero for Matrix2<S> { #[inline] fn zero() -> Matrix2<S> { Matrix2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: BaseFloat> Zero for Matrix3<S> { #[inline] fn zero() -> Matrix3<S> { Matrix3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } impl<S: BaseFloat> Zero for Matrix3<S> { #[inline] fn zero() -> Matrix3<S> { Matrix3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
@ -393,17 +393,74 @@ impl<S: BaseFloat> One for Matrix2<S> { #[inline] fn one() -> Matrix2<S> { Matri
impl<S: BaseFloat> One for Matrix3<S> { #[inline] fn one() -> Matrix3<S> { Matrix3::identity() } } impl<S: BaseFloat> One for Matrix3<S> { #[inline] fn one() -> Matrix3<S> { Matrix3::identity() } }
impl<S: BaseFloat> One for Matrix4<S> { #[inline] fn one() -> Matrix4<S> { Matrix4::identity() } } impl<S: BaseFloat> One for Matrix4<S> { #[inline] fn one() -> Matrix4<S> { Matrix4::identity() } }
impl<S> FixedArray<[[S, ..2], ..2]> for Matrix2<S> {
#[inline]
fn into_fixed(self) -> [[S, ..2], ..2] {
match self {
Matrix2 { x, y } => [
x.into_fixed(),
y.into_fixed(),
],
}
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [[S, ..2], ..2] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [[S, ..2], ..2] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [[S, ..2], ..2]) -> Matrix2<S> {
// match v {
// [x, y] => Matrix2 {
// x: FixedArray::from_fixed(x),
// y: FixedArray::from_fixed(y),
// },
// }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [[S, ..2], ..2]) -> &'a Matrix2<S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [[S, ..2], ..2]) -> &'a mut Matrix2<S> {
unsafe { mem::transmute(v) }
}
}
impl<S> Index<uint, Vector2<S>> for Matrix2<S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a Vector2<S> {
FixedArray::from_fixed_ref(&self.as_fixed()[*i])
}
}
impl<S> IndexMut<uint, Vector2<S>> for Matrix2<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut Vector2<S> {
FixedArray::from_fixed_mut(&mut self.as_mut_fixed()[*i])
}
}
impl<S: Copy> Array2<Vector2<S>, Vector2<S>, S> for Matrix2<S> { impl<S: Copy> Array2<Vector2<S>, Vector2<S>, S> for Matrix2<S> {
#[inline] #[inline]
fn r(&self, r: uint) -> Vector2<S> { fn row(&self, r: uint) -> Vector2<S> {
Vector2::new(self[0][r], Vector2::new(self[0][r],
self[1][r]) self[1][r])
} }
#[inline] #[inline]
fn swap_r(&mut self, a: uint, b: uint) { fn swap_rows(&mut self, a: uint, b: uint) {
(&mut self[0]).swap_i(a, b); (&mut self[0]).swap_elems(a, b);
(&mut self[1]).swap_i(a, b); (&mut self[1]).swap_elems(a, b);
} }
#[inline] #[inline]
@ -414,35 +471,78 @@ impl<S: Copy> Array2<Vector2<S>, Vector2<S>, S> for Matrix2<S> {
} }
} }
impl<S: Copy> Index<uint, Vector2<S>> for Matrix2<S> { impl<S> FixedArray<[[S, ..3], ..3]> for Matrix3<S> {
#[inline] #[inline]
fn index<'a>(&'a self, c: &uint) -> &'a Vector2<S> { fn into_fixed(self) -> [[S, ..3], ..3] {
let slice: &'a [Vector2<S>, ..2] = unsafe { mem::transmute(self) }; match self {
&slice[*c] Matrix3 { x, y, z } => [
x.into_fixed(),
y.into_fixed(),
z.into_fixed(),
],
}
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [[S, ..3], ..3] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [[S, ..3], ..3] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [[S, ..3], ..3]) -> Matrix3<S> {
// match v {
// [x, y, z] => Matrix3 {
// x: FixedArray::from_fixed(x),
// y: FixedArray::from_fixed(y),
// z: FixedArray::from_fixed(z),
// },
// }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [[S, ..3], ..3]) -> &'a Matrix3<S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [[S, ..3], ..3]) -> &'a mut Matrix3<S> {
unsafe { mem::transmute(v) }
} }
} }
impl<S: Copy> IndexMut<uint, Vector2<S>> for Matrix2<S> { impl<S> Index<uint, Vector3<S>> for Matrix3<S> {
#[inline] #[inline]
fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector2<S> { fn index<'a>(&'a self, i: &uint) -> &'a Vector3<S> {
let slice: &'a mut [Vector2<S>, ..2] = unsafe { mem::transmute(self) }; FixedArray::from_fixed_ref(&self.as_fixed()[*i])
&mut slice[*c] }
}
impl<S> IndexMut<uint, Vector3<S>> for Matrix3<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut Vector3<S> {
FixedArray::from_fixed_mut(&mut self.as_mut_fixed()[*i])
} }
} }
impl<S: Copy> Array2<Vector3<S>, Vector3<S>, S> for Matrix3<S> { impl<S: Copy> Array2<Vector3<S>, Vector3<S>, S> for Matrix3<S> {
#[inline] #[inline]
fn r(&self, r: uint) -> Vector3<S> { fn row(&self, r: uint) -> Vector3<S> {
Vector3::new(self[0][r], Vector3::new(self[0][r],
self[1][r], self[1][r],
self[2][r]) self[2][r])
} }
#[inline] #[inline]
fn swap_r(&mut self, a: uint, b: uint) { fn swap_rows(&mut self, a: uint, b: uint) {
(&mut self[0]).swap_i(a, b); (&mut self[0]).swap_elems(a, b);
(&mut self[1]).swap_i(a, b); (&mut self[1]).swap_elems(a, b);
(&mut self[2]).swap_i(a, b); (&mut self[2]).swap_elems(a, b);
} }
#[inline] #[inline]
@ -454,25 +554,70 @@ impl<S: Copy> Array2<Vector3<S>, Vector3<S>, S> for Matrix3<S> {
} }
} }
impl<S: Copy> Index<uint, Vector3<S>> for Matrix3<S> { impl<S> FixedArray<[[S, ..4], ..4]> for Matrix4<S> {
#[inline] #[inline]
fn index<'a>(&'a self, c: &uint) -> &'a Vector3<S> { fn into_fixed(self) -> [[S, ..4], ..4] {
let slice: &'a [Vector3<S>, ..3] = unsafe { mem::transmute(self) }; match self {
&slice[*c] Matrix4 { x, y, z, w } => [
x.into_fixed(),
y.into_fixed(),
z.into_fixed(),
w.into_fixed(),
],
}
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [[S, ..4], ..4] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [[S, ..4], ..4] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [[S, ..4], ..4]) -> Matrix4<S> {
// match v {
// [x, y, z, w] => Matrix4 {
// x: FixedArray::from_fixed(x),
// y: FixedArray::from_fixed(y),
// z: FixedArray::from_fixed(z),
// w: FixedArray::from_fixed(w),
// },
// }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [[S, ..4], ..4]) -> &'a Matrix4<S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [[S, ..4], ..4]) -> &'a mut Matrix4<S> {
unsafe { mem::transmute(v) }
} }
} }
impl<S: Copy> IndexMut<uint, Vector3<S>> for Matrix3<S> { impl<S> Index<uint, Vector4<S>> for Matrix4<S> {
#[inline] #[inline]
fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector3<S> { fn index<'a>(&'a self, i: &uint) -> &'a Vector4<S> {
let slice: &'a mut [Vector3<S>, ..3] = unsafe { mem::transmute(self) }; FixedArray::from_fixed_ref(&self.as_fixed()[*i])
&mut slice[*c] }
}
impl<S> IndexMut<uint, Vector4<S>> for Matrix4<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut Vector4<S> {
FixedArray::from_fixed_mut(&mut self.as_mut_fixed()[*i])
} }
} }
impl<S: Copy> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> { impl<S: Copy> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
#[inline] #[inline]
fn r(&self, r: uint) -> Vector4<S> { fn row(&self, r: uint) -> Vector4<S> {
Vector4::new(self[0][r], Vector4::new(self[0][r],
self[1][r], self[1][r],
self[2][r], self[2][r],
@ -480,11 +625,11 @@ impl<S: Copy> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
} }
#[inline] #[inline]
fn swap_r(&mut self, a: uint, b: uint) { fn swap_rows(&mut self, a: uint, b: uint) {
(&mut self[0]).swap_i(a, b); (&mut self[0]).swap_elems(a, b);
(&mut self[1]).swap_i(a, b); (&mut self[1]).swap_elems(a, b);
(&mut self[2]).swap_i(a, b); (&mut self[2]).swap_elems(a, b);
(&mut self[3]).swap_i(a, b); (&mut self[3]).swap_elems(a, b);
} }
#[inline] #[inline]
@ -497,22 +642,6 @@ impl<S: Copy> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
} }
} }
impl<S: Copy> Index<uint, Vector4<S>> for Matrix4<S> {
#[inline]
fn index<'a>(&'a self, c: &uint) -> &'a Vector4<S> {
let slice: &'a [Vector4<S>, ..4] = unsafe { mem::transmute(self) };
&slice[*c]
}
}
impl<S: Copy> IndexMut<uint, Vector4<S>> for Matrix4<S> {
#[inline]
fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector4<S> {
let slice: &'a mut [Vector4<S>, ..4] = unsafe { mem::transmute(self) };
&mut slice[*c]
}
}
impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> { impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
#[inline] #[inline]
fn mul_s(&self, s: S) -> Matrix2<S> { fn mul_s(&self, s: S) -> Matrix2<S> {
@ -546,13 +675,13 @@ impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
#[inline] #[inline]
fn mul_v(&self, v: &Vector2<S>) -> Vector2<S> { fn mul_v(&self, v: &Vector2<S>) -> Vector2<S> {
Vector2::new(self.r(0).dot(v), Vector2::new(self.row(0).dot(v),
self.r(1).dot(v)) self.row(1).dot(v))
} }
fn mul_m(&self, other: &Matrix2<S>) -> Matrix2<S> { fn mul_m(&self, other: &Matrix2<S>) -> Matrix2<S> {
Matrix2::new(self.r(0).dot(&other[0]), self.r(1).dot(&other[0]), Matrix2::new(self.row(0).dot(&other[0]), self.row(1).dot(&other[0]),
self.r(0).dot(&other[1]), self.r(1).dot(&other[1])) self.row(0).dot(&other[1]), self.row(1).dot(&other[1]))
} }
#[inline] #[inline]
@ -598,7 +727,7 @@ impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
#[inline] #[inline]
fn transpose_self(&mut self) { fn transpose_self(&mut self) {
self.swap_cr((0, 1), (1, 0)); self.swap_elems((0, 1), (1, 0));
} }
#[inline] #[inline]
@ -675,15 +804,15 @@ impl<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
#[inline] #[inline]
fn mul_v(&self, v: &Vector3<S>) -> Vector3<S> { fn mul_v(&self, v: &Vector3<S>) -> Vector3<S> {
Vector3::new(self.r(0).dot(v), Vector3::new(self.row(0).dot(v),
self.r(1).dot(v), self.row(1).dot(v),
self.r(2).dot(v)) self.row(2).dot(v))
} }
fn mul_m(&self, other: &Matrix3<S>) -> Matrix3<S> { fn mul_m(&self, other: &Matrix3<S>) -> Matrix3<S> {
Matrix3::new(self.r(0).dot(&other[0]),self.r(1).dot(&other[0]),self.r(2).dot(&other[0]), Matrix3::new(self.row(0).dot(&other[0]),self.row(1).dot(&other[0]),self.row(2).dot(&other[0]),
self.r(0).dot(&other[1]),self.r(1).dot(&other[1]),self.r(2).dot(&other[1]), self.row(0).dot(&other[1]),self.row(1).dot(&other[1]),self.row(2).dot(&other[1]),
self.r(0).dot(&other[2]),self.r(1).dot(&other[2]),self.r(2).dot(&other[2])) self.row(0).dot(&other[2]),self.row(1).dot(&other[2]),self.row(2).dot(&other[2]))
} }
#[inline] #[inline]
@ -736,9 +865,9 @@ impl<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
#[inline] #[inline]
fn transpose_self(&mut self) { fn transpose_self(&mut self) {
self.swap_cr((0, 1), (1, 0)); self.swap_elems((0, 1), (1, 0));
self.swap_cr((0, 2), (2, 0)); self.swap_elems((0, 2), (2, 0));
self.swap_cr((1, 2), (2, 1)); self.swap_elems((1, 2), (2, 1));
} }
fn determinant(&self) -> S { fn determinant(&self) -> S {
@ -786,7 +915,7 @@ impl<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
} }
} }
// Using self.r(0).dot(other.c(0)) like the other matrix multiplies // Using self.row(0).dot(other[0]) like the other matrix multiplies
// causes the LLVM to miss identical loads and multiplies. This optimization // causes the LLVM to miss identical loads and multiplies. This optimization
// causes the code to be auto vectorized properly increasing the performance // causes the code to be auto vectorized properly increasing the performance
// around ~4 times. // around ~4 times.
@ -841,10 +970,10 @@ impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> {
#[inline] #[inline]
fn mul_v(&self, v: &Vector4<S>) -> Vector4<S> { fn mul_v(&self, v: &Vector4<S>) -> Vector4<S> {
Vector4::new(self.r(0).dot(v), Vector4::new(self.row(0).dot(v),
self.r(1).dot(v), self.row(1).dot(v),
self.r(2).dot(v), self.row(2).dot(v),
self.r(3).dot(v)) self.row(3).dot(v))
} }
fn mul_m(&self, other: &Matrix4<S>) -> Matrix4<S> { fn mul_m(&self, other: &Matrix4<S>) -> Matrix4<S> {
@ -910,12 +1039,12 @@ impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> {
} }
fn transpose_self(&mut self) { fn transpose_self(&mut self) {
self.swap_cr((0, 1), (1, 0)); self.swap_elems((0, 1), (1, 0));
self.swap_cr((0, 2), (2, 0)); self.swap_elems((0, 2), (2, 0));
self.swap_cr((0, 3), (3, 0)); self.swap_elems((0, 3), (3, 0));
self.swap_cr((1, 2), (2, 1)); self.swap_elems((1, 2), (2, 1));
self.swap_cr((1, 3), (3, 1)); self.swap_elems((1, 3), (3, 1));
self.swap_cr((2, 3), (3, 2)); self.swap_elems((2, 3), (3, 2));
} }
fn determinant(&self) -> S { fn determinant(&self) -> S {

View file

@ -22,7 +22,7 @@ use std::mem;
use std::num::{one, zero}; use std::num::{one, zero};
use approx::ApproxEq; use approx::ApproxEq;
use array::Array1; use array::{Array1, FixedArray};
use num::{BaseNum, BaseFloat}; use num::{BaseNum, BaseFloat};
use vector::*; use vector::*;
@ -102,28 +102,59 @@ pub trait Point<S: BaseNum, V: Vector<S>>: Array1<S> + Clone {
fn max(&self, p: &Self) -> Self; fn max(&self, p: &Self) -> Self;
} }
impl<S: BaseNum> Array1<S> for Point2<S> { impl<S> FixedArray<[S, ..2]> for Point2<S> {
#[inline] #[inline]
fn map(&mut self, op: |S| -> S) -> Point2<S> { fn into_fixed(self) -> [S, ..2] {
self.x = op(self.x); match self { Point2 { x, y } => [x, y] }
self.y = op(self.y); }
*self
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [S, ..2] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [S, ..2] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [S, ..2]) -> Point2<S> {
// match v { [x, y] => Point2 { x: x, y: y } }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [S, ..2]) -> &'a Point2<S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [S, ..2]) -> &'a mut Point2<S> {
unsafe { mem::transmute(v) }
} }
} }
impl<S: BaseNum> Index<uint, S> for Point2<S> { impl<S: BaseNum> Index<uint, S> for Point2<S> {
#[inline] #[inline]
fn index<'a>(&'a self, i: &uint) -> &'a S { fn index<'a>(&'a self, i: &uint) -> &'a S {
let slice: &[S, ..2] = unsafe { mem::transmute(self) }; &self.as_fixed()[*i]
&slice[*i]
} }
} }
impl<S: BaseNum> IndexMut<uint, S> for Point2<S> { impl<S: BaseNum> IndexMut<uint, S> for Point2<S> {
#[inline] #[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S { fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S {
let slice: &'a mut [S, ..2] = unsafe { mem::transmute(self) }; &mut self.as_mut_fixed()[*i]
&mut slice[*i] }
}
impl<S: BaseNum> Array1<S> for Point2<S> {
#[inline]
fn map(&mut self, op: |S| -> S) -> Point2<S> {
self.x = op(self.x);
self.y = op(self.y);
*self
} }
} }
@ -225,6 +256,53 @@ impl<S: BaseFloat> ApproxEq<S> for Point2<S> {
} }
} }
impl<S> FixedArray<[S, ..3]> for Point3<S> {
#[inline]
fn into_fixed(self) -> [S, ..3] {
match self { Point3 { x, y, z } => [x, y, z] }
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [S, ..3] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [S, ..3] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [S, ..3]) -> Point3<S> {
// match v { [x, y, z] => Point3 { x: x, y: y, z: z } }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [S, ..3]) -> &'a Point3<S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [S, ..3]) -> &'a mut Point3<S> {
unsafe { mem::transmute(v) }
}
}
impl<S: BaseNum> Index<uint, S> for Point3<S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a S {
&self.as_fixed()[*i]
}
}
impl<S: BaseNum> IndexMut<uint, S> for Point3<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S {
&mut self.as_mut_fixed()[*i]
}
}
impl<S: BaseNum> Array1<S> for Point3<S> { impl<S: BaseNum> Array1<S> for Point3<S> {
#[inline] #[inline]
fn map(&mut self, op: |S| -> S) -> Point3<S> { fn map(&mut self, op: |S| -> S) -> Point3<S> {
@ -235,22 +313,6 @@ impl<S: BaseNum> Array1<S> for Point3<S> {
} }
} }
impl<S: BaseNum> Index<uint, S> for Point3<S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a S {
let slice: &[S, ..3] = unsafe { mem::transmute(self) };
&slice[*i]
}
}
impl<S: BaseNum> IndexMut<uint, S> for Point3<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S {
let slice: &'a mut [S, ..3] = unsafe { mem::transmute(self) };
&mut slice[*i]
}
}
impl<S: BaseNum> Point<S, Vector3<S>> for Point3<S> { impl<S: BaseNum> Point<S, Vector3<S>> for Point3<S> {
#[inline] #[inline]
fn origin() -> Point3<S> { fn origin() -> Point3<S> {

View file

@ -105,7 +105,7 @@ use std::num::{Zero, zero, One, one};
use angle::{Rad, atan2, acos}; use angle::{Rad, atan2, acos};
use approx::ApproxEq; use approx::ApproxEq;
use array::Array1; use array::{Array1, FixedArray};
use num::{BaseNum, BaseFloat}; use num::{BaseNum, BaseFloat};
/// A trait that specifies a range of numeric operations for vectors. Not all /// A trait that specifies a range of numeric operations for vectors. Not all
@ -212,9 +212,56 @@ macro_rules! vec(
pub fn ident() -> $Self<$S> { $Self::from_value(one()) } pub fn ident() -> $Self<$S> { $Self::from_value(one()) }
} }
impl<S: Copy> Array1<S> for $Self<S> { impl<$S> FixedArray<[$S, ..$n]> for $Self<$S> {
#[inline] #[inline]
fn map(&mut self, op: |S| -> S) -> $Self<S> { fn into_fixed(self) -> [$S, ..$n] {
match self { $Self { $($field),+ } => [$($field),+] }
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [$S, ..$n] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [$S, ..$n] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [$S, ..$n]) -> $Self<$S> {
// match v { [$($field),+] => $Self { $($field: $field),+ } }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [$S, ..$n]) -> &'a $Self<$S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [$S, ..$n]) -> &'a mut $Self<$S> {
unsafe { mem::transmute(v) }
}
}
impl<$S: Copy> Index<uint, S> for $Self<$S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a $S {
&self.as_fixed()[*i]
}
}
impl<$S: Copy> IndexMut<uint, S> for $Self<$S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut $S {
&mut self.as_mut_fixed()[*i]
}
}
impl<$S: Copy> Array1<$S> for $Self<$S> {
#[inline]
fn map(&mut self, op: |$S| -> $S) -> $Self<$S> {
$(self.$field = op(self.$field);)+ *self $(self.$field = op(self.$field);)+ *self
} }
} }
@ -285,22 +332,6 @@ macro_rules! vec(
#[inline] fn one() -> $Self<S> { $Self::from_value(one()) } #[inline] fn one() -> $Self<S> { $Self::from_value(one()) }
} }
impl<S: Copy> Index<uint, S> for $Self<S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a S {
let slice: &[S, ..$n] = unsafe { mem::transmute(self) };
&slice[*i]
}
}
impl<S: Copy> IndexMut<uint, S> for $Self<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S {
let slice: &'a mut [S, ..$n] = unsafe { mem::transmute(self) };
&mut slice[*i]
}
}
impl<S: BaseFloat> ApproxEq<S> for $Self<S> { impl<S: BaseFloat> ApproxEq<S> for $Self<S> {
#[inline] #[inline]
fn approx_eq_eps(&self, other: &$Self<S>, epsilon: &S) -> bool { fn approx_eq_eps(&self, other: &$Self<S>, epsilon: &S) -> bool {