commit
4a45bf3b53
5 changed files with 407 additions and 168 deletions
97
src/array.rs
97
src/array.rs
|
@ -28,30 +28,30 @@ pub trait Array1<Element: Copy>: Index<uint, Element> + IndexMut<uint, Element>
|
|||
&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<Column: Array1<Element>, Row: Array1<Element>, 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<Column: Array1<Element>, Row: Array1<Element>, 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<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;
|
||||
}
|
||||
|
|
|
@ -50,12 +50,12 @@ Frustum<S> {
|
|||
|
||||
/// Extracts frustum planes from a projection matrix
|
||||
pub fn from_matrix4(mat: Matrix4<S>) -> Frustum<S> {
|
||||
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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
283
src/matrix.rs
283
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<S> {
|
|||
_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> {
|
||||
Matrix3::new(value.x, zero(), 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<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<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<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<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[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[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 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 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> {
|
||||
#[inline]
|
||||
fn r(&self, r: uint) -> Vector2<S> {
|
||||
fn row(&self, r: uint) -> Vector2<S> {
|
||||
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<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]
|
||||
fn index<'a>(&'a self, c: &uint) -> &'a Vector2<S> {
|
||||
let slice: &'a [Vector2<S>, ..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<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]
|
||||
fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector2<S> {
|
||||
let slice: &'a mut [Vector2<S>, ..2] = unsafe { mem::transmute(self) };
|
||||
&mut slice[*c]
|
||||
fn index<'a>(&'a self, i: &uint) -> &'a Vector3<S> {
|
||||
FixedArray::from_fixed_ref(&self.as_fixed()[*i])
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
#[inline]
|
||||
fn r(&self, r: uint) -> Vector3<S> {
|
||||
fn row(&self, r: uint) -> Vector3<S> {
|
||||
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<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]
|
||||
fn index<'a>(&'a self, c: &uint) -> &'a Vector3<S> {
|
||||
let slice: &'a [Vector3<S>, ..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<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]
|
||||
fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector3<S> {
|
||||
let slice: &'a mut [Vector3<S>, ..3] = unsafe { mem::transmute(self) };
|
||||
&mut slice[*c]
|
||||
fn index<'a>(&'a self, i: &uint) -> &'a Vector4<S> {
|
||||
FixedArray::from_fixed_ref(&self.as_fixed()[*i])
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
#[inline]
|
||||
fn r(&self, r: uint) -> Vector4<S> {
|
||||
fn row(&self, r: uint) -> Vector4<S> {
|
||||
Vector4::new(self[0][r],
|
||||
self[1][r],
|
||||
self[2][r],
|
||||
|
@ -480,11 +625,11 @@ impl<S: Copy> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
|
|||
}
|
||||
|
||||
#[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<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> {
|
||||
#[inline]
|
||||
fn mul_s(&self, s: S) -> Matrix2<S> {
|
||||
|
@ -546,13 +675,13 @@ impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
|
|||
|
||||
#[inline]
|
||||
fn mul_v(&self, v: &Vector2<S>) -> Vector2<S> {
|
||||
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<S>) -> Matrix2<S> {
|
||||
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<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
|
|||
|
||||
#[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<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
|
|||
|
||||
#[inline]
|
||||
fn mul_v(&self, v: &Vector3<S>) -> Vector3<S> {
|
||||
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<S>) -> Matrix3<S> {
|
||||
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<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
|
|||
|
||||
#[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<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 code to be auto vectorized properly increasing the performance
|
||||
// around ~4 times.
|
||||
|
@ -841,10 +970,10 @@ impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> {
|
|||
|
||||
#[inline]
|
||||
fn mul_v(&self, v: &Vector4<S>) -> Vector4<S> {
|
||||
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<S>) -> Matrix4<S> {
|
||||
|
@ -910,12 +1039,12 @@ impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
|
114
src/point.rs
114
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<S: BaseNum, V: Vector<S>>: Array1<S> + Clone {
|
|||
fn max(&self, p: &Self) -> Self;
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Array1<S> for Point2<S> {
|
||||
impl<S> FixedArray<[S, ..2]> for Point2<S> {
|
||||
#[inline]
|
||||
fn map(&mut self, op: |S| -> S) -> Point2<S> {
|
||||
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<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> {
|
||||
#[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<S: BaseNum> IndexMut<uint, S> for Point2<S> {
|
||||
#[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<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> {
|
||||
#[inline]
|
||||
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> {
|
||||
#[inline]
|
||||
fn origin() -> Point3<S> {
|
||||
|
|
|
@ -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<S: Copy> Array1<S> for $Self<S> {
|
||||
impl<$S> FixedArray<[$S, ..$n]> for $Self<$S> {
|
||||
#[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
|
||||
}
|
||||
}
|
||||
|
@ -285,22 +332,6 @@ macro_rules! vec(
|
|||
#[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> {
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &$Self<S>, epsilon: &S) -> bool {
|
||||
|
|
Loading…
Reference in a new issue