diff --git a/src/array.rs b/src/array.rs index b6b240e..821cdc4 100644 --- a/src/array.rs +++ b/src/array.rs @@ -28,30 +28,30 @@ pub trait Array1: Index + IndexMut &mut (*self)[0] } - /// Get a shared reference to the `i`th value. - #[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] - } - + #[deprecated = "Use `Array1::swap_elems` instead"] #[inline] /// Swap the elements at indices `i` and `j` in-place. 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 unsafe { ptr::swap(&mut (*self)[i], &mut (*self)[j]) }; } /// Replace an element in the array. + #[deprecated = "Use `Array1::replace_elem` instead"] #[inline] 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) } @@ -72,55 +72,61 @@ pub trait Array2, Row: Array1, Element: Copy>: &mut (*self)[0][0] } - /// Get a shared reference to a column of this array. - #[deprecated = "Use index operator instead"] + /// Swap two columns of this array. + #[deprecated = "Use `Array2::swap_cols` instead"] #[inline] - fn c<'a>(&'a self, c: uint) -> &'a Column { - &(*self)[c] - } - - /// 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] + fn swap_c(&mut self, a: uint, b: uint) { + self.swap_cols(a, b) } /// Swap two columns of this array. #[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]) }; } /// Replace a column in the array. + #[deprecated = "Use `Array2::replace_col` instead"] #[inline] 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) } /// Get a row from this array by-value. - fn r(&self, r: uint) -> Row; - - /// 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"] + #[deprecated = "Use `Array2::row` instead"] #[inline] - fn cr<'a>(&'a self, c: uint, r: uint) -> &'a Element { - &(*self)[c][r] + fn r(&self, r: uint) -> Row { + self.row(r) } - /// Return a mutable reference to the element at column `c` and row `r`. - #[deprecated = "Use index operators instead"] + /// Get a row from this array by-value. + fn row(&self, r: uint) -> Row; + + #[deprecated = "Use `Array2::swap_rows` instead"] #[inline] - fn mut_cr<'a>(&'a mut self, c: uint, r: uint) -> &'a mut Element { - &mut (*self)[c][r] + fn swap_r(&mut self, a: uint, b: uint) { + 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` #[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 (bc, br) = b; unsafe { ptr::swap(&mut (*self)[ac][ar], &mut (*self)[bc][br]) }; @@ -129,3 +135,14 @@ pub trait Array2, Row: Array1, Element: Copy>: /// Apply a function to each column. 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 { + 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; +} diff --git a/src/frustum.rs b/src/frustum.rs index 707989e..6adbd1f 100644 --- a/src/frustum.rs +++ b/src/frustum.rs @@ -50,12 +50,12 @@ Frustum { /// Extracts frustum planes from a projection matrix pub fn from_matrix4(mat: Matrix4) -> Frustum { - Frustum::new(Plane::from_vector4(mat.r(3).add_v(&mat.r(0)).normalize()), - Plane::from_vector4(mat.r(3).sub_v(&mat.r(0)).normalize()), - Plane::from_vector4(mat.r(3).add_v(&mat.r(1)).normalize()), - Plane::from_vector4(mat.r(3).sub_v(&mat.r(1)).normalize()), - Plane::from_vector4(mat.r(3).add_v(&mat.r(2)).normalize()), - Plane::from_vector4(mat.r(3).sub_v(&mat.r(2)).normalize())) + Frustum::new(Plane::from_vector4(mat.row(3).add_v(&mat.row(0)).normalize()), + Plane::from_vector4(mat.row(3).sub_v(&mat.row(0)).normalize()), + Plane::from_vector4(mat.row(3).add_v(&mat.row(1)).normalize()), + Plane::from_vector4(mat.row(3).sub_v(&mat.row(1)).normalize()), + Plane::from_vector4(mat.row(3).add_v(&mat.row(2)).normalize()), + Plane::from_vector4(mat.row(3).sub_v(&mat.row(2)).normalize())) } } diff --git a/src/matrix.rs b/src/matrix.rs index d6a3c20..5f62fcb 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -21,7 +21,7 @@ use std::num::{Zero, zero, One, one, cast}; use angle::{Rad, sin, cos, sin_cos}; use approx::ApproxEq; -use array::{Array1, Array2}; +use array::{Array1, Array2, FixedArray}; use num::{BaseFloat, BaseNum}; use point::{Point, Point3}; use quaternion::{Quaternion, ToQuaternion}; @@ -209,7 +209,7 @@ Matrix3 { _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) -> Matrix3 { Matrix3::new(value.x, zero(), zero(), zero(), value.y, zero(), @@ -377,9 +377,9 @@ impl Sub, Matrix2> for Matrix2 { #[inline] fn sub impl Sub, Matrix3> for Matrix3 { #[inline] fn sub(&self, other: &Matrix3) -> Matrix3 { self.sub_m(other) } } impl Sub, Matrix4> for Matrix4 { #[inline] fn sub(&self, other: &Matrix4) -> Matrix4 { self.sub_m(other) } } -impl Neg> for Matrix2 { #[inline] fn neg(&self) -> Matrix2 { Matrix2::from_cols(self.c(0).neg(), self.c(1).neg()) } } -impl Neg> for Matrix3 { #[inline] fn neg(&self) -> Matrix3 { Matrix3::from_cols(self.c(0).neg(), self.c(1).neg(), self.c(2).neg()) } } -impl Neg> for Matrix4 { #[inline] fn neg(&self) -> Matrix4 { Matrix4::from_cols(self.c(0).neg(), self.c(1).neg(), self.c(2).neg(), self.c(3).neg()) } } +impl Neg> for Matrix2 { #[inline] fn neg(&self) -> Matrix2 { Matrix2::from_cols(self[0].neg(), self[1].neg()) } } +impl Neg> for Matrix3 { #[inline] fn neg(&self) -> Matrix3 { Matrix3::from_cols(self[0].neg(), self[1].neg(), self[2].neg()) } } +impl Neg> for Matrix4 { #[inline] fn neg(&self) -> Matrix4 { Matrix4::from_cols(self[0].neg(), self[1].neg(), self[2].neg(), self[3].neg()) } } impl Zero for Matrix2 { #[inline] fn zero() -> Matrix2 { Matrix2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } impl Zero for Matrix3 { #[inline] fn zero() -> Matrix3 { Matrix3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } @@ -393,17 +393,74 @@ impl One for Matrix2 { #[inline] fn one() -> Matrix2 { Matri impl One for Matrix3 { #[inline] fn one() -> Matrix3 { Matrix3::identity() } } impl One for Matrix4 { #[inline] fn one() -> Matrix4 { Matrix4::identity() } } +impl FixedArray<[[S, ..2], ..2]> for Matrix2 { + #[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 { + // 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 { + unsafe { mem::transmute(v) } + } + + #[inline] + fn from_fixed_mut<'a>(v: &'a mut [[S, ..2], ..2]) -> &'a mut Matrix2 { + unsafe { mem::transmute(v) } + } +} + +impl Index> for Matrix2 { + #[inline] + fn index<'a>(&'a self, i: &uint) -> &'a Vector2 { + FixedArray::from_fixed_ref(&self.as_fixed()[*i]) + } +} + +impl IndexMut> for Matrix2 { + #[inline] + fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut Vector2 { + FixedArray::from_fixed_mut(&mut self.as_mut_fixed()[*i]) + } +} + impl Array2, Vector2, S> for Matrix2 { #[inline] - fn r(&self, r: uint) -> Vector2 { + fn row(&self, r: uint) -> Vector2 { Vector2::new(self[0][r], self[1][r]) } #[inline] - fn swap_r(&mut self, a: uint, b: uint) { - (&mut self[0]).swap_i(a, b); - (&mut self[1]).swap_i(a, b); + fn swap_rows(&mut self, a: uint, b: uint) { + (&mut self[0]).swap_elems(a, b); + (&mut self[1]).swap_elems(a, b); } #[inline] @@ -414,35 +471,78 @@ impl Array2, Vector2, S> for Matrix2 { } } -impl Index> for Matrix2 { +impl FixedArray<[[S, ..3], ..3]> for Matrix3 { #[inline] - fn index<'a>(&'a self, c: &uint) -> &'a Vector2 { - let slice: &'a [Vector2, ..2] = unsafe { mem::transmute(self) }; - &slice[*c] + fn into_fixed(self) -> [[S, ..3], ..3] { + match self { + 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 { + // 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 { + unsafe { mem::transmute(v) } + } + + #[inline] + fn from_fixed_mut<'a>(v: &'a mut [[S, ..3], ..3]) -> &'a mut Matrix3 { + unsafe { mem::transmute(v) } } } -impl IndexMut> for Matrix2 { +impl Index> for Matrix3 { #[inline] - fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector2 { - let slice: &'a mut [Vector2, ..2] = unsafe { mem::transmute(self) }; - &mut slice[*c] + fn index<'a>(&'a self, i: &uint) -> &'a Vector3 { + FixedArray::from_fixed_ref(&self.as_fixed()[*i]) + } +} + +impl IndexMut> for Matrix3 { + #[inline] + fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut Vector3 { + FixedArray::from_fixed_mut(&mut self.as_mut_fixed()[*i]) } } impl Array2, Vector3, S> for Matrix3 { #[inline] - fn r(&self, r: uint) -> Vector3 { + fn row(&self, r: uint) -> Vector3 { Vector3::new(self[0][r], self[1][r], self[2][r]) } #[inline] - fn swap_r(&mut self, a: uint, b: uint) { - (&mut self[0]).swap_i(a, b); - (&mut self[1]).swap_i(a, b); - (&mut self[2]).swap_i(a, b); + fn swap_rows(&mut self, a: uint, b: uint) { + (&mut self[0]).swap_elems(a, b); + (&mut self[1]).swap_elems(a, b); + (&mut self[2]).swap_elems(a, b); } #[inline] @@ -454,25 +554,70 @@ impl Array2, Vector3, S> for Matrix3 { } } -impl Index> for Matrix3 { +impl FixedArray<[[S, ..4], ..4]> for Matrix4 { #[inline] - fn index<'a>(&'a self, c: &uint) -> &'a Vector3 { - let slice: &'a [Vector3, ..3] = unsafe { mem::transmute(self) }; - &slice[*c] + fn into_fixed(self) -> [[S, ..4], ..4] { + match self { + 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 { + // 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 { + unsafe { mem::transmute(v) } + } + + #[inline] + fn from_fixed_mut<'a>(v: &'a mut [[S, ..4], ..4]) -> &'a mut Matrix4 { + unsafe { mem::transmute(v) } } } -impl IndexMut> for Matrix3 { +impl Index> for Matrix4 { #[inline] - fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector3 { - let slice: &'a mut [Vector3, ..3] = unsafe { mem::transmute(self) }; - &mut slice[*c] + fn index<'a>(&'a self, i: &uint) -> &'a Vector4 { + FixedArray::from_fixed_ref(&self.as_fixed()[*i]) + } +} + +impl IndexMut> for Matrix4 { + #[inline] + fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut Vector4 { + FixedArray::from_fixed_mut(&mut self.as_mut_fixed()[*i]) } } impl Array2, Vector4, S> for Matrix4 { #[inline] - fn r(&self, r: uint) -> Vector4 { + fn row(&self, r: uint) -> Vector4 { Vector4::new(self[0][r], self[1][r], self[2][r], @@ -480,11 +625,11 @@ impl Array2, Vector4, S> for Matrix4 { } #[inline] - fn swap_r(&mut self, a: uint, b: uint) { - (&mut self[0]).swap_i(a, b); - (&mut self[1]).swap_i(a, b); - (&mut self[2]).swap_i(a, b); - (&mut self[3]).swap_i(a, b); + fn swap_rows(&mut self, a: uint, b: uint) { + (&mut self[0]).swap_elems(a, b); + (&mut self[1]).swap_elems(a, b); + (&mut self[2]).swap_elems(a, b); + (&mut self[3]).swap_elems(a, b); } #[inline] @@ -497,22 +642,6 @@ impl Array2, Vector4, S> for Matrix4 { } } -impl Index> for Matrix4 { - #[inline] - fn index<'a>(&'a self, c: &uint) -> &'a Vector4 { - let slice: &'a [Vector4, ..4] = unsafe { mem::transmute(self) }; - &slice[*c] - } -} - -impl IndexMut> for Matrix4 { - #[inline] - fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector4 { - let slice: &'a mut [Vector4, ..4] = unsafe { mem::transmute(self) }; - &mut slice[*c] - } -} - impl Matrix> for Matrix2 { #[inline] fn mul_s(&self, s: S) -> Matrix2 { @@ -546,13 +675,13 @@ impl Matrix> for Matrix2 { #[inline] fn mul_v(&self, v: &Vector2) -> Vector2 { - Vector2::new(self.r(0).dot(v), - self.r(1).dot(v)) + Vector2::new(self.row(0).dot(v), + self.row(1).dot(v)) } fn mul_m(&self, other: &Matrix2) -> Matrix2 { - Matrix2::new(self.r(0).dot(&other[0]), self.r(1).dot(&other[0]), - self.r(0).dot(&other[1]), self.r(1).dot(&other[1])) + Matrix2::new(self.row(0).dot(&other[0]), self.row(1).dot(&other[0]), + self.row(0).dot(&other[1]), self.row(1).dot(&other[1])) } #[inline] @@ -598,7 +727,7 @@ impl Matrix> for Matrix2 { #[inline] fn transpose_self(&mut self) { - self.swap_cr((0, 1), (1, 0)); + self.swap_elems((0, 1), (1, 0)); } #[inline] @@ -675,15 +804,15 @@ impl Matrix> for Matrix3 { #[inline] fn mul_v(&self, v: &Vector3) -> Vector3 { - Vector3::new(self.r(0).dot(v), - self.r(1).dot(v), - self.r(2).dot(v)) + Vector3::new(self.row(0).dot(v), + self.row(1).dot(v), + self.row(2).dot(v)) } fn mul_m(&self, other: &Matrix3) -> Matrix3 { - Matrix3::new(self.r(0).dot(&other[0]),self.r(1).dot(&other[0]),self.r(2).dot(&other[0]), - self.r(0).dot(&other[1]),self.r(1).dot(&other[1]),self.r(2).dot(&other[1]), - self.r(0).dot(&other[2]),self.r(1).dot(&other[2]),self.r(2).dot(&other[2])) + Matrix3::new(self.row(0).dot(&other[0]),self.row(1).dot(&other[0]),self.row(2).dot(&other[0]), + self.row(0).dot(&other[1]),self.row(1).dot(&other[1]),self.row(2).dot(&other[1]), + self.row(0).dot(&other[2]),self.row(1).dot(&other[2]),self.row(2).dot(&other[2])) } #[inline] @@ -736,9 +865,9 @@ impl Matrix> for Matrix3 { #[inline] fn transpose_self(&mut self) { - self.swap_cr((0, 1), (1, 0)); - self.swap_cr((0, 2), (2, 0)); - self.swap_cr((1, 2), (2, 1)); + self.swap_elems((0, 1), (1, 0)); + self.swap_elems((0, 2), (2, 0)); + self.swap_elems((1, 2), (2, 1)); } fn determinant(&self) -> S { @@ -786,7 +915,7 @@ impl Matrix> for Matrix3 { } } -// 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 code to be auto vectorized properly increasing the performance // around ~4 times. @@ -841,10 +970,10 @@ impl Matrix> for Matrix4 { #[inline] fn mul_v(&self, v: &Vector4) -> Vector4 { - Vector4::new(self.r(0).dot(v), - self.r(1).dot(v), - self.r(2).dot(v), - self.r(3).dot(v)) + Vector4::new(self.row(0).dot(v), + self.row(1).dot(v), + self.row(2).dot(v), + self.row(3).dot(v)) } fn mul_m(&self, other: &Matrix4) -> Matrix4 { @@ -910,12 +1039,12 @@ impl Matrix> for Matrix4 { } fn transpose_self(&mut self) { - self.swap_cr((0, 1), (1, 0)); - self.swap_cr((0, 2), (2, 0)); - self.swap_cr((0, 3), (3, 0)); - self.swap_cr((1, 2), (2, 1)); - self.swap_cr((1, 3), (3, 1)); - self.swap_cr((2, 3), (3, 2)); + self.swap_elems((0, 1), (1, 0)); + self.swap_elems((0, 2), (2, 0)); + self.swap_elems((0, 3), (3, 0)); + self.swap_elems((1, 2), (2, 1)); + self.swap_elems((1, 3), (3, 1)); + self.swap_elems((2, 3), (3, 2)); } fn determinant(&self) -> S { diff --git a/src/point.rs b/src/point.rs index 16ec84d..cb7390c 100644 --- a/src/point.rs +++ b/src/point.rs @@ -22,7 +22,7 @@ use std::mem; use std::num::{one, zero}; use approx::ApproxEq; -use array::Array1; +use array::{Array1, FixedArray}; use num::{BaseNum, BaseFloat}; use vector::*; @@ -102,28 +102,59 @@ pub trait Point>: Array1 + Clone { fn max(&self, p: &Self) -> Self; } -impl Array1 for Point2 { +impl FixedArray<[S, ..2]> for Point2 { #[inline] - fn map(&mut self, op: |S| -> S) -> Point2 { - self.x = op(self.x); - self.y = op(self.y); - *self + fn into_fixed(self) -> [S, ..2] { + match self { Point2 { x, y } => [x, y] } + } + + #[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 { + // 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 { + unsafe { mem::transmute(v) } + } + + #[inline] + fn from_fixed_mut<'a>(v: &'a mut [S, ..2]) -> &'a mut Point2 { + unsafe { mem::transmute(v) } } } impl Index for Point2 { #[inline] fn index<'a>(&'a self, i: &uint) -> &'a S { - let slice: &[S, ..2] = unsafe { mem::transmute(self) }; - &slice[*i] + &self.as_fixed()[*i] } } impl IndexMut for Point2 { #[inline] fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S { - let slice: &'a mut [S, ..2] = unsafe { mem::transmute(self) }; - &mut slice[*i] + &mut self.as_mut_fixed()[*i] + } +} + +impl Array1 for Point2 { + #[inline] + fn map(&mut self, op: |S| -> S) -> Point2 { + self.x = op(self.x); + self.y = op(self.y); + *self } } @@ -225,6 +256,53 @@ impl ApproxEq for Point2 { } } +impl FixedArray<[S, ..3]> for Point3 { + #[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 { + // 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 { + unsafe { mem::transmute(v) } + } + + #[inline] + fn from_fixed_mut<'a>(v: &'a mut [S, ..3]) -> &'a mut Point3 { + unsafe { mem::transmute(v) } + } +} + +impl Index for Point3 { + #[inline] + fn index<'a>(&'a self, i: &uint) -> &'a S { + &self.as_fixed()[*i] + } +} + +impl IndexMut for Point3 { + #[inline] + fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S { + &mut self.as_mut_fixed()[*i] + } +} + impl Array1 for Point3 { #[inline] fn map(&mut self, op: |S| -> S) -> Point3 { @@ -235,22 +313,6 @@ impl Array1 for Point3 { } } -impl Index for Point3 { - #[inline] - fn index<'a>(&'a self, i: &uint) -> &'a S { - let slice: &[S, ..3] = unsafe { mem::transmute(self) }; - &slice[*i] - } -} - -impl IndexMut for Point3 { - #[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 Point> for Point3 { #[inline] fn origin() -> Point3 { diff --git a/src/vector.rs b/src/vector.rs index 8d9fda8..5834462 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -105,7 +105,7 @@ use std::num::{Zero, zero, One, one}; use angle::{Rad, atan2, acos}; use approx::ApproxEq; -use array::Array1; +use array::{Array1, FixedArray}; use num::{BaseNum, BaseFloat}; /// 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()) } } - impl Array1 for $Self { + impl<$S> FixedArray<[$S, ..$n]> for $Self<$S> { #[inline] - fn map(&mut self, op: |S| -> S) -> $Self { + 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 for $Self<$S> { + #[inline] + fn index<'a>(&'a self, i: &uint) -> &'a $S { + &self.as_fixed()[*i] + } + } + + impl<$S: Copy> IndexMut 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 } } @@ -285,22 +332,6 @@ macro_rules! vec( #[inline] fn one() -> $Self { $Self::from_value(one()) } } - impl Index for $Self { - #[inline] - fn index<'a>(&'a self, i: &uint) -> &'a S { - let slice: &[S, ..$n] = unsafe { mem::transmute(self) }; - &slice[*i] - } - } - - impl IndexMut for $Self { - #[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 ApproxEq for $Self { #[inline] fn approx_eq_eps(&self, other: &$Self, epsilon: &S) -> bool {