// Copyright 2013 The CGMath Developers. For a full listing of the authors, // refer to the AUTHORS file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use std::num::{One, one, zero}; use traits::alg::*; use traits::util::*; use types::vector::*; #[deriving(Clone, Eq, Zero)] pub struct Mat2 { x: Vec2, y: Vec2 } #[deriving(Clone, Eq, Zero)] pub struct Mat3 { x: Vec3, y: Vec3, z: Vec3 } #[deriving(Clone, Eq, Zero)] pub struct Mat4 { x: Vec4, y: Vec4, z: Vec4, w: Vec4 } // Constructors impl Mat2 { #[inline] pub fn new(c0r0: S, c0r1: S, c1r0: S, c1r1: S) -> Mat2 { Mat2::from_cols(Vec2::new(c0r0, c0r1), Vec2::new(c1r0, c1r1)) } #[inline] pub fn from_cols(c0: Vec2, c1: Vec2) -> Mat2 { Mat2 { x: c0, y: c1 } } } impl Mat3 { #[inline] pub fn new(c0r0:S, c0r1:S, c0r2:S, c1r0:S, c1r1:S, c1r2:S, c2r0:S, c2r1:S, c2r2:S) -> Mat3 { Mat3::from_cols(Vec3::new(c0r0, c0r1, c0r2), Vec3::new(c1r0, c1r1, c1r2), Vec3::new(c2r0, c2r1, c2r2)) } #[inline] pub fn from_cols(c0: Vec3, c1: Vec3, c2: Vec3) -> Mat3 { Mat3 { x: c0, y: c1, z: c2 } } } impl Mat4 { #[inline] pub fn new(c0r0: S, c0r1: S, c0r2: S, c0r3: S, c1r0: S, c1r1: S, c1r2: S, c1r3: S, c2r0: S, c2r1: S, c2r2: S, c2r3: S, c3r0: S, c3r1: S, c3r2: S, c3r3: S) -> Mat4 { Mat4::from_cols(Vec4::new(c0r0, c0r1, c0r2, c0r3), Vec4::new(c1r0, c1r1, c1r2, c1r3), Vec4::new(c2r0, c2r1, c2r2, c2r3), Vec4::new(c3r0, c3r1, c3r2, c3r3)) } #[inline] pub fn from_cols(c0: Vec4, c1: Vec4, c2: Vec4, c3: Vec4) -> Mat4 { Mat4 { x: c0, y: c1, z: c2, w: c3 } } } // Trait impls impl_indexable!(Mat2, [Vec2, ..2]) impl_indexable!(Mat3, [Vec3, ..3]) impl_indexable!(Mat4, [Vec4, ..4]) impl Swappable, [Vec2, ..2]> for Mat2; impl Swappable, [Vec3, ..3]> for Mat3; impl Swappable, [Vec4, ..4]> for Mat4; impl_scalar_binop!(Mat2, Mul, mul) impl_scalar_binop!(Mat3, Mul, mul) impl_scalar_binop!(Mat4, Mul, mul) impl_scalar_binop!(Mat2, Div, div) impl_scalar_binop!(Mat3, Div, div) impl_scalar_binop!(Mat4, Div, div) impl_scalar_binop!(Mat2, Rem, rem) impl_scalar_binop!(Mat3, Rem, rem) impl_scalar_binop!(Mat4, Rem, rem) impl ScalarMul for Mat2; impl ScalarMul for Mat3; impl ScalarMul for Mat4; impl_coordinate_binop!(Mat2, Mat2, Mat2, Add, add) impl_coordinate_binop!(Mat3, Mat3, Mat3, Add, add) impl_coordinate_binop!(Mat4, Mat4, Mat4, Add, add) impl_coordinate_binop!(Mat2, Mat2, Mat2, Sub, sub) impl_coordinate_binop!(Mat3, Mat3, Mat3, Sub, sub) impl_coordinate_binop!(Mat4, Mat4, Mat4, Sub, sub) impl_coordinate_op!(Mat2, Mat2, Neg, neg) impl_coordinate_op!(Mat3, Mat3, Neg, neg) impl_coordinate_op!(Mat4, Mat4, Neg, neg) impl Module for Mat2; impl Module for Mat3; impl Module for Mat4; impl One for Mat2 { fn one() -> Mat2 { Mat2::new(one(), zero(), zero(), one()) } } impl One for Mat3 { fn one() -> Mat3 { Mat3::new(one(), zero(), zero(), zero(), one(), zero(), zero(), zero(), one()) } } impl One for Mat4 { fn one() -> Mat4 { Mat4::new(one(), zero(), zero(), zero(), zero(), one(), zero(), zero(), zero(), zero(), one(), zero(), zero(), zero(), zero(), one()) } } impl Ring for Mat2; impl Ring for Mat3; impl Ring for Mat4; impl Matrix < S, Vec2, [S, ..2], [Vec2, ..2], Vec2, [S, ..2], [Vec2, ..2], Mat2 > for Mat2 { #[inline] fn r(&self, r: uint) -> Vec2 { Vec2::new(self.i(0).i(r).clone(), self.i(1).i(r).clone()) } #[inline] fn swap_r(&mut self, a: uint, b: uint) { self.mut_c(0).swap(a, b); self.mut_c(1).swap(a, b); } fn transpose(&self) -> Mat2 { Mat2::new(self.cr(0, 0).clone(), self.cr(1, 0).clone(), self.cr(0, 1).clone(), self.cr(1, 1).clone()) } } impl Matrix < S, Vec3, [S, ..3], [Vec3, ..3], Vec3, [S, ..3], [Vec3, ..3], Mat3 > for Mat3 { #[inline] fn r(&self, r: uint) -> Vec3 { Vec3::new(self.i(0).i(r).clone(), self.i(1).i(r).clone(), self.i(2).i(r).clone()) } #[inline] fn swap_r(&mut self, a: uint, b: uint) { self.mut_c(0).swap(a, b); self.mut_c(1).swap(a, b); self.mut_c(2).swap(a, b); } fn transpose(&self) -> Mat3 { Mat3::new(self.cr(0, 0).clone(), self.cr(1, 0).clone(), self.cr(2, 0).clone(), self.cr(0, 1).clone(), self.cr(1, 1).clone(), self.cr(2, 1).clone(), self.cr(0, 2).clone(), self.cr(1, 2).clone(), self.cr(2, 2).clone()) } } impl Matrix < S, Vec4, [S, ..4], [Vec4, ..4], Vec4, [S, ..4], [Vec4, ..4], Mat4 > for Mat4 { #[inline] fn r(&self, r: uint) -> Vec4 { Vec4::new(self.i(0).i(r).clone(), self.i(1).i(r).clone(), self.i(2).i(r).clone(), self.i(2).i(r).clone()) } #[inline] fn swap_r(&mut self, a: uint, b: uint) { self.mut_c(0).swap(a, b); self.mut_c(1).swap(a, b); self.mut_c(2).swap(a, b); self.mut_c(3).swap(a, b); } fn transpose(&self) -> Mat4 { Mat4::new(self.cr(0, 0).clone(), self.cr(1, 0).clone(), self.cr(2, 0).clone(), self.cr(3, 0).clone(), self.cr(0, 1).clone(), self.cr(1, 1).clone(), self.cr(2, 1).clone(), self.cr(3, 1).clone(), self.cr(0, 2).clone(), self.cr(1, 2).clone(), self.cr(2, 2).clone(), self.cr(3, 2).clone(), self.cr(0, 3).clone(), self.cr(1, 3).clone(), self.cr(2, 3).clone(), self.cr(3, 3).clone()) } }