diff --git a/src/cgmath/aabb.rs b/src/cgmath/aabb.rs index ab001fc..cb7ae9c 100644 --- a/src/cgmath/aabb.rs +++ b/src/cgmath/aabb.rs @@ -18,16 +18,14 @@ use point::{Point, Point2, Point3}; use vector::{Vector, Vec2, Vec3}; use array::build; +use partial_ord::PartOrdPrim; use std::fmt; use std::num::{zero, one}; use std::iter::Iterator; -fn partial_min(a: S, b: S) -> S { if a < b { a } else { b }} -fn partial_max(a: S, b: S) -> S { if a > b { a } else { b }} - pub trait Aabb < - S: Primitive, + S: PartOrdPrim, V: Vector, P: Point, Slice @@ -51,8 +49,8 @@ pub trait Aabb // Returns a new AABB that is grown to include the given point. fn grow(&self, p: &P) -> Self { - let min : P = build(|i| partial_min(*self.min().i(i), *p.i(i))); - let max : P = build(|i| partial_max(*self.max().i(i), *p.i(i))); + let min : P = build(|i| self.min().i(i).min(*p.i(i))); + let max : P = build(|i| self.max().i(i).max(*p.i(i))); Aabb::new(min, max) } @@ -78,20 +76,20 @@ pub struct Aabb2 { max: Point2, } -impl Aabb2 { +impl Aabb2 { /// Construct a new axis-aligned bounding box from two points. #[inline] pub fn new(p1: Point2, p2: Point2) -> Aabb2 { Aabb2 { - min: Point2::new(partial_min(p1.x.clone(), p2.x.clone()), - partial_min(p1.y.clone(), p2.y.clone())), - max: Point2::new(partial_max(p1.x.clone(), p2.x.clone()), - partial_max(p1.y.clone(), p2.y.clone())), + min: Point2::new(p1.x.min(p2.x), + p1.y.min(p2.y)), + max: Point2::new(p1.x.max(p2.x), + p1.y.max(p2.y)), } } } -impl Aabb, Point2, [S, ..2]> for Aabb2 { +impl Aabb, Point2, [S, ..2]> for Aabb2 { fn new(p1: Point2, p2: Point2) -> Aabb2 { Aabb2::new(p1, p2) } #[inline] fn min<'a>(&'a self) -> &'a Point2 { &self.min } #[inline] fn max<'a>(&'a self) -> &'a Point2 { &self.max } @@ -109,22 +107,22 @@ pub struct Aabb3 { max: Point3, } -impl Aabb3 { +impl Aabb3 { /// Construct a new axis-aligned bounding box from two points. #[inline] pub fn new(p1: Point3, p2: Point3) -> Aabb3 { Aabb3 { - min: Point3::new(partial_min(p1.x.clone(), p2.x.clone()), - partial_min(p1.y.clone(), p2.y.clone()), - partial_min(p1.z.clone(), p2.z.clone())), - max: Point3::new(partial_max(p1.x.clone(), p2.x.clone()), - partial_max(p1.y.clone(), p2.y.clone()), - partial_max(p1.z.clone(), p2.z.clone())), + min: Point3::new(p1.x.min(p2.x), + p1.y.min(p2.y), + p1.z.min(p2.z)), + max: Point3::new(p1.x.max(p2.x), + p1.y.max(p2.y), + p1.z.max(p2.z)), } } } -impl Aabb, Point3, [S, ..3]> for Aabb3 { +impl Aabb, Point3, [S, ..3]> for Aabb3 { fn new(p1: Point3, p2: Point3) -> Aabb3 { Aabb3::new(p1, p2) } #[inline] fn min<'a>(&'a self) -> &'a Point3 { &self.min } #[inline] fn max<'a>(&'a self) -> &'a Point3 { &self.max } diff --git a/src/cgmath/frustum.rs b/src/cgmath/frustum.rs index 6de6a99..d181b82 100644 --- a/src/cgmath/frustum.rs +++ b/src/cgmath/frustum.rs @@ -15,11 +15,11 @@ //! View frustum for visibility determination -use approx::ApproxEq; use matrix::{Matrix, Mat4}; use plane::Plane; use point::Point3; use vector::{Vector, EuclideanVector}; +use partial_ord::PartOrdFloat; #[deriving(Clone, Eq)] pub struct Frustum { @@ -31,7 +31,7 @@ pub struct Frustum { far: Plane, } -impl> +impl> Frustum { /// Constructs a frustum pub fn new(left: Plane, right: Plane, diff --git a/src/cgmath/lib.rs b/src/cgmath/lib.rs index 3ceb124..f16ad36 100644 --- a/src/cgmath/lib.rs +++ b/src/cgmath/lib.rs @@ -45,3 +45,5 @@ pub mod sphere; pub mod approx; pub mod ptr; + +pub mod partial_ord; diff --git a/src/cgmath/matrix.rs b/src/cgmath/matrix.rs index f6a9e74..6e4210e 100644 --- a/src/cgmath/matrix.rs +++ b/src/cgmath/matrix.rs @@ -25,6 +25,7 @@ use point::{Point, Point3}; use quaternion::{Quat, ToQuat}; use vector::{Vector, EuclideanVector}; use vector::{Vec2, Vec3, Vec4}; +use partial_ord::PartOrdFloat; /// A 2 x 2, column major matrix #[deriving(Clone, Eq)] @@ -69,7 +70,7 @@ impl Mat2 { } } -impl> Mat2 { +impl> Mat2 { pub fn look_at(dir: &Vec2, up: &Vec2) -> Mat2 { //TODO: verify look_at 2D Mat2::from_cols(up.clone(), dir.clone()).transpose() @@ -118,7 +119,7 @@ impl Mat3 { } } -impl> +impl> Mat3 { pub fn look_at(dir: &Vec3, up: &Vec3) -> Mat3 { let dir = dir.normalize(); @@ -228,7 +229,7 @@ impl Mat4 { } } -impl> +impl> Mat4 { pub fn look_at(eye: &Point3, center: &Point3, up: &Vec3) -> Mat4 { let f = center.sub_p(eye).normalize(); @@ -248,7 +249,7 @@ array!(impl Mat4 -> [Vec4, ..4] _4) pub trait Matrix < - S: Float + ApproxEq, Slice, + S: PartOrdFloat, Slice, V: Clone + Vector + Array, VSlice > : Array @@ -360,31 +361,31 @@ pub trait Matrix fn is_symmetric(&self) -> bool; } -impl Add, Mat2> for Mat2 { #[inline] fn add(&self, other: &Mat2) -> Mat2 { build(|i| self.i(i).add_v(other.i(i))) } } -impl Add, Mat3> for Mat3 { #[inline] fn add(&self, other: &Mat3) -> Mat3 { build(|i| self.i(i).add_v(other.i(i))) } } -impl Add, Mat4> for Mat4 { #[inline] fn add(&self, other: &Mat4) -> Mat4 { build(|i| self.i(i).add_v(other.i(i))) } } +impl> Add, Mat2> for Mat2 { #[inline] fn add(&self, other: &Mat2) -> Mat2 { build(|i| self.i(i).add_v(other.i(i))) } } +impl> Add, Mat3> for Mat3 { #[inline] fn add(&self, other: &Mat3) -> Mat3 { build(|i| self.i(i).add_v(other.i(i))) } } +impl> Add, Mat4> for Mat4 { #[inline] fn add(&self, other: &Mat4) -> Mat4 { build(|i| self.i(i).add_v(other.i(i))) } } -impl Sub, Mat2> for Mat2 { #[inline] fn sub(&self, other: &Mat2) -> Mat2 { build(|i| self.i(i).sub_v(other.i(i))) } } -impl Sub, Mat3> for Mat3 { #[inline] fn sub(&self, other: &Mat3) -> Mat3 { build(|i| self.i(i).sub_v(other.i(i))) } } -impl Sub, Mat4> for Mat4 { #[inline] fn sub(&self, other: &Mat4) -> Mat4 { build(|i| self.i(i).sub_v(other.i(i))) } } +impl> Sub, Mat2> for Mat2 { #[inline] fn sub(&self, other: &Mat2) -> Mat2 { build(|i| self.i(i).sub_v(other.i(i))) } } +impl> Sub, Mat3> for Mat3 { #[inline] fn sub(&self, other: &Mat3) -> Mat3 { build(|i| self.i(i).sub_v(other.i(i))) } } +impl> Sub, Mat4> for Mat4 { #[inline] fn sub(&self, other: &Mat4) -> Mat4 { build(|i| self.i(i).sub_v(other.i(i))) } } -impl Neg> for Mat2 { #[inline] fn neg(&self) -> Mat2 { build(|i| self.i(i).neg()) } } -impl Neg> for Mat3 { #[inline] fn neg(&self) -> Mat3 { build(|i| self.i(i).neg()) } } -impl Neg> for Mat4 { #[inline] fn neg(&self) -> Mat4 { build(|i| self.i(i).neg()) } } +impl> Neg> for Mat2 { #[inline] fn neg(&self) -> Mat2 { build(|i| self.i(i).neg()) } } +impl> Neg> for Mat3 { #[inline] fn neg(&self) -> Mat3 { build(|i| self.i(i).neg()) } } +impl> Neg> for Mat4 { #[inline] fn neg(&self) -> Mat4 { build(|i| self.i(i).neg()) } } -impl Zero for Mat2 { #[inline] fn zero() -> Mat2 { Mat2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } -impl Zero for Mat3 { #[inline] fn zero() -> Mat3 { Mat3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } -impl Zero for Mat4 { #[inline] fn zero() -> Mat4 { Mat4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } +impl> Zero for Mat2 { #[inline] fn zero() -> Mat2 { Mat2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } +impl> Zero for Mat3 { #[inline] fn zero() -> Mat3 { Mat3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } +impl> Zero for Mat4 { #[inline] fn zero() -> Mat4 { Mat4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } -impl Mul, Mat2> for Mat2 { #[inline] fn mul(&self, other: &Mat2) -> Mat2 { build(|i| self.i(i).mul_v(other.i(i))) } } -impl Mul, Mat3> for Mat3 { #[inline] fn mul(&self, other: &Mat3) -> Mat3 { build(|i| self.i(i).mul_v(other.i(i))) } } -impl Mul, Mat4> for Mat4 { #[inline] fn mul(&self, other: &Mat4) -> Mat4 { build(|i| self.i(i).mul_v(other.i(i))) } } +impl> Mul, Mat2> for Mat2 { #[inline] fn mul(&self, other: &Mat2) -> Mat2 { build(|i| self.i(i).mul_v(other.i(i))) } } +impl> Mul, Mat3> for Mat3 { #[inline] fn mul(&self, other: &Mat3) -> Mat3 { build(|i| self.i(i).mul_v(other.i(i))) } } +impl> Mul, Mat4> for Mat4 { #[inline] fn mul(&self, other: &Mat4) -> Mat4 { build(|i| self.i(i).mul_v(other.i(i))) } } -impl One for Mat2 { #[inline] fn one() -> Mat2 { Mat2::identity() } } -impl One for Mat3 { #[inline] fn one() -> Mat3 { Mat3::identity() } } -impl One for Mat4 { #[inline] fn one() -> Mat4 { Mat4::identity() } } +impl> One for Mat2 { #[inline] fn one() -> Mat2 { Mat2::identity() } } +impl> One for Mat3 { #[inline] fn one() -> Mat3 { Mat3::identity() } } +impl> One for Mat4 { #[inline] fn one() -> Mat4 { Mat4::identity() } } -impl> +impl> Matrix, ..2], Vec2, [S, ..2]> for Mat2 { @@ -433,7 +434,7 @@ for Mat2 } } -impl> +impl> Matrix, ..3], Vec3, [S, ..3]> for Mat3 { @@ -506,7 +507,7 @@ macro_rules! dot_mat4( (*$A.cr(3, $I)) * (*$B.cr($J, 3)) )) -impl> +impl> Matrix, ..4], Vec4, [S, ..4]> for Mat4 { @@ -639,7 +640,7 @@ pub trait ToMat2 { fn to_mat2(&self) -> Mat2; } pub trait ToMat3 { fn to_mat3(&self) -> Mat3; } pub trait ToMat4 { fn to_mat4(&self) -> Mat4; } -impl> +impl> ToMat3 for Mat2 { /// Clone the elements of a 2-dimensional matrix into the top corner of a /// 3-dimensional identity matrix. @@ -650,7 +651,7 @@ ToMat3 for Mat2 { } } -impl> +impl> ToMat4 for Mat2 { /// Clone the elements of a 2-dimensional matrix into the top corner of a /// 4-dimensional identity matrix. @@ -662,7 +663,7 @@ ToMat4 for Mat2 { } } -impl> +impl> ToMat4 for Mat3 { /// Clone the elements of a 3-dimensional matrix into the top corner of a /// 4-dimensional identity matrix. @@ -674,7 +675,7 @@ ToMat4 for Mat3 { } } -impl> +impl> ToQuat for Mat3 { /// Convert the matrix to a quaternion fn to_quat(&self) -> Quat { @@ -722,7 +723,7 @@ ToQuat for Mat3 { } } -impl + fmt::Show> fmt::Show for Mat2 { +impl + fmt::Show> fmt::Show for Mat2 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f.buf, "[[{}, {}], [{}, {}]]", self.cr(0, 0), self.cr(0, 1), @@ -730,7 +731,7 @@ impl + fmt::Show> fmt::Show for Mat2 { } } -impl + fmt::Show> fmt::Show for Mat3 { +impl + fmt::Show> fmt::Show for Mat3 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f.buf, "[[{}, {}, {}], [{}, {}, {}], [{}, {}, {}]]", self.cr(0, 0), self.cr(0, 1), self.cr(0, 2), @@ -739,7 +740,7 @@ impl + fmt::Show> fmt::Show for Mat3 { } } -impl + fmt::Show> fmt::Show for Mat4 { +impl + fmt::Show> fmt::Show for Mat4 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f.buf, "[[{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}]]", self.cr(0, 0), self.cr(0, 1), self.cr(0, 2), self.cr(0, 3), diff --git a/src/cgmath/partial_ord.rs b/src/cgmath/partial_ord.rs new file mode 100644 index 0000000..37e24b9 --- /dev/null +++ b/src/cgmath/partial_ord.rs @@ -0,0 +1,52 @@ +// 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 approx::ApproxEq; +use std::cmp; + +pub trait PartOrdPrim : Primitive { + fn min(&self, b: Self) -> Self; + fn max(&self, b: Self) -> Self; +} + +macro_rules! gen_minmax_for_floats ( + ( $($T:ident),+ ) => ( + $( + impl PartOrdPrim for $T { + fn min(&self, b: $T) -> $T { (*self).min(b) } + fn max(&self, b: $T) -> $T { (*self).max(b) } + } + )+ + ) +) + +macro_rules! gen_minmax_for_not_floats ( + ( $($T:ident),+ ) => ( + $( + impl PartOrdPrim for $T { + fn min(&self, b: $T) -> $T { cmp::min((*self), b) } + fn max(&self, b: $T) -> $T { cmp::max((*self), b) } + } + )+ + ) +) + +gen_minmax_for_floats!(f32, f64) +gen_minmax_for_not_floats!(int, i8, i16, i32, i64, uint, u8, u16, u32, u64) + +pub trait PartOrdFloat : Float + ApproxEq + PartOrdPrim {} +impl PartOrdFloat for f32 {} +impl PartOrdFloat for f64 {} + diff --git a/src/cgmath/plane.rs b/src/cgmath/plane.rs index a18d2d9..1b772c5 100644 --- a/src/cgmath/plane.rs +++ b/src/cgmath/plane.rs @@ -23,6 +23,7 @@ use point::{Point, Point3}; use ray::Ray3; use vector::{Vec3, Vec4}; use vector::{Vector, EuclideanVector}; +use partial_ord::PartOrdFloat; /// A 3-dimendional plane formed from the equation: `a*x + b*y + c*z - d = 0`. @@ -46,7 +47,7 @@ pub struct Plane { d: S, } -impl> +impl> Plane { /// Construct a plane from a normal vector and a scalar distance pub fn new(n: Vec3, d: S) -> Plane { @@ -88,7 +89,7 @@ Plane { } } -impl Intersect>> for (Plane, Ray3) { +impl> Intersect>> for (Plane, Ray3) { fn intersection(&self) -> Option> { match *self { (ref p, ref r) => { diff --git a/src/cgmath/point.rs b/src/cgmath/point.rs index 8a68c74..2313614 100644 --- a/src/cgmath/point.rs +++ b/src/cgmath/point.rs @@ -22,6 +22,7 @@ use std::num::{one, zero}; use array::*; use vector::*; +use partial_ord::PartOrdPrim; /// A point in 2-dimensional space. #[deriving(Eq, Clone, Hash)] @@ -46,7 +47,7 @@ impl Point3 { } } -impl Point3 { +impl Point3 { #[inline] pub fn from_homogeneous(v: &Vec4) -> Point3 { let e = v.truncate().mul_s(one::() / v.w); @@ -62,7 +63,7 @@ impl Point3 { /// Specifies the numeric operations for point types. pub trait Point < - S: Primitive, + S: PartOrdPrim, V: Vector, Slice > @@ -96,8 +97,8 @@ pub trait Point array!(impl Point2 -> [S, ..2] _2) array!(impl Point3 -> [S, ..3] _3) -impl Point, [S, ..2]> for Point2 {} -impl Point, [S, ..3]> for Point3 {} +impl Point, [S, ..2]> for Point2 {} +impl Point, [S, ..3]> for Point3 {} impl fmt::Show for Point2 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/cgmath/projection.rs b/src/cgmath/projection.rs index 3a541cc..b743c2b 100644 --- a/src/cgmath/projection.rs +++ b/src/cgmath/projection.rs @@ -16,10 +16,10 @@ use std::num::{zero, one, cast}; use angle::{Angle, tan, cot}; -use approx::ApproxEq; use frustum::Frustum; use matrix::{Mat4, ToMat4}; use plane::Plane; +use partial_ord::PartOrdFloat; /// Create a perspective projection matrix. /// @@ -94,7 +94,7 @@ impl> PerspectiveFov { } } -impl, A: Angle> +impl, A: Angle> Projection for PerspectiveFov { fn to_frustum(&self) -> Frustum { // TODO: Could this be faster? @@ -151,7 +151,7 @@ pub struct Perspective { near: S, far: S, } -impl> +impl> Projection for Perspective { fn to_frustum(&self) -> Frustum { // TODO: Could this be faster? @@ -202,7 +202,7 @@ pub struct Ortho { near: S, far: S, } -impl> +impl> Projection for Ortho { fn to_frustum(&self) -> Frustum { Frustum { diff --git a/src/cgmath/quaternion.rs b/src/cgmath/quaternion.rs index da76ab7..ae1b8ed 100644 --- a/src/cgmath/quaternion.rs +++ b/src/cgmath/quaternion.rs @@ -23,6 +23,7 @@ use matrix::{Mat3, ToMat3, ToMat4, Mat4}; use point::{Point3}; use rotation::{Rotation, Rotation3, Basis3, ToBasis3}; use vector::{Vec3, Vector, EuclideanVector}; +use partial_ord::PartOrdFloat; /// A quaternion in scalar/vector form #[deriving(Clone, Eq)] @@ -34,7 +35,7 @@ pub trait ToQuat { fn to_quat(&self) -> Quat; } -impl> +impl> Quat { /// Construct a new quaternion from one scalar component and three /// imaginary components @@ -173,7 +174,7 @@ Quat { } } -impl + Ord> +impl> Quat { /// Spherical Linear Intoperlation /// @@ -279,7 +280,7 @@ ToMat4 for Quat { } } -impl> +impl> Neg> for Quat { #[inline] fn neg(&self) -> Quat { @@ -299,7 +300,7 @@ impl fmt::Show for Quat { // Quaternion Rotation impls -impl> +impl> ToBasis3 for Quat { #[inline] fn to_rot3(&self) -> Basis3 { Basis3::from_quat(self) } @@ -310,7 +311,7 @@ impl ToQuat for Quat { fn to_quat(&self) -> Quat { self.clone() } } -impl> +impl> Rotation, Point3> for Quat { #[inline] fn identity() -> Quat { Quat::identity() } @@ -343,7 +344,7 @@ Rotation, Point3> for Quat { fn invert_self(&mut self) { *self = self.invert() } } -impl> +impl> Rotation3 for Quat { #[inline] diff --git a/src/cgmath/rotation.rs b/src/cgmath/rotation.rs index 2cf680c..9623b0b 100644 --- a/src/cgmath/rotation.rs +++ b/src/cgmath/rotation.rs @@ -23,11 +23,12 @@ use point::{Point, Point2, Point3}; use quaternion::{Quat, ToQuat}; use ray::Ray; use vector::{Vector, Vec2, Vec3}; +use partial_ord::{PartOrdPrim, PartOrdFloat}; /// A trait for generic rotation pub trait Rotation < - S: Primitive, + S: PartOrdPrim, Slice, V: Vector, P: Point @@ -156,7 +157,7 @@ impl ToMat2 for Basis2 { fn to_mat2(&self) -> Mat2 { self.mat.clone() } } -impl> +impl> Rotation, Point2> for Basis2 { #[inline] fn identity() -> Basis2 { Basis2{ mat: Mat2::identity() } } @@ -191,7 +192,7 @@ Rotation, Point2> for Basis2 { fn invert_self(&mut self) { self.mat.invert_self(); } } -impl> +impl> ApproxEq for Basis2 { #[inline] fn approx_eq_eps(&self, other: &Basis2, epsilon: &S) -> bool { @@ -199,7 +200,7 @@ ApproxEq for Basis2 { } } -impl> +impl> Rotation2 for Basis2 { fn from_angle(theta: Rad) -> Basis2 { Basis2 { mat: Mat2::from_angle(theta) } } } @@ -215,7 +216,7 @@ pub struct Basis3 { priv mat: Mat3 } -impl> +impl> Basis3 { #[inline] pub fn from_quat(quat: &Quat) -> Basis3 { Basis3 { mat: quat.to_mat3() } } @@ -238,13 +239,13 @@ impl ToMat3 for Basis3 { fn to_mat3(&self) -> Mat3 { self.mat.clone() } } -impl> +impl> ToQuat for Basis3 { #[inline] fn to_quat(&self) -> Quat { self.mat.to_quat() } } -impl> +impl> Rotation, Point3> for Basis3 { #[inline] fn identity() -> Basis3 { Basis3{ mat: Mat3::identity() } } @@ -288,7 +289,7 @@ ApproxEq for Basis3 { } } -impl> +impl> Rotation3 for Basis3 { fn from_axis_angle(axis: &Vec3, angle: Rad) -> Basis3 { Basis3 { mat: Mat3::from_axis_angle(axis, angle) } diff --git a/src/cgmath/sphere.rs b/src/cgmath/sphere.rs index 53808e4..0153f35 100644 --- a/src/cgmath/sphere.rs +++ b/src/cgmath/sphere.rs @@ -19,6 +19,7 @@ use intersect::Intersect; use point::{Point, Point3}; use ray::Ray3; use vector::Vector; +use partial_ord::PartOrdFloat; use std::num::NumCast; use std::num; @@ -33,7 +34,7 @@ pub struct Sphere { radius: S, } -impl Intersect>> for (Sphere, Ray3) { +impl> Intersect>> for (Sphere, Ray3) { fn intersection(&self) -> Option> { match *self { (ref s, ref r) => { diff --git a/src/cgmath/transform.rs b/src/cgmath/transform.rs index 253d879..85ba383 100644 --- a/src/cgmath/transform.rs +++ b/src/cgmath/transform.rs @@ -24,11 +24,12 @@ use ray::Ray; use rotation::{Rotation, Rotation3}; use quaternion::Quat; use vector::{Vector, Vec3}; +use partial_ord::{PartOrdPrim, PartOrdFloat}; /// A trait of affine transformation, that can be applied to points or vectors pub trait Transform < - S: Primitive, + S: PartOrdPrim, Slice, V: Vector, P: Point @@ -77,7 +78,7 @@ pub struct Decomposed { impl < - S: Float + ApproxEq, + S: PartOrdFloat, Slice, V: Vector, P: Point, @@ -145,7 +146,7 @@ pub trait Transform3 + ToMat4 {} -impl, R: Rotation3> +impl, R: Rotation3> ToMat4 for Decomposed, R> { fn to_mat4(&self) -> Mat4 { let mut m = self.rot.to_mat3().mul_s( self.scale.clone() ).to_mat4(); @@ -154,7 +155,7 @@ ToMat4 for Decomposed, R> { } } -impl, R: Rotation3> +impl, R: Rotation3> Transform3 for Decomposed,R> {} impl> @@ -171,7 +172,7 @@ pub struct AffineMatrix3 { mat: Mat4, } -impl> +impl> Transform, Point3> for AffineMatrix3 { #[inline] fn identity() -> AffineMatrix3 { @@ -204,12 +205,12 @@ Transform, Point3> for AffineMatrix3 { } } -impl +impl ToMat4 for AffineMatrix3 { #[inline] fn to_mat4(&self) -> Mat4 { self.mat.clone() } } -impl> +impl> Transform3 for AffineMatrix3 {} @@ -217,7 +218,7 @@ Transform3 for AffineMatrix3 {} /// displacement vector and scale amount. pub struct Transform3D( Decomposed,Quat> ); -impl> Transform3D { +impl> Transform3D { #[inline] pub fn new(scale: S, rot: Quat, disp: Vec3) -> Transform3D { Transform3D( Decomposed { scale: scale, rot: rot, disp: disp }) @@ -235,6 +236,6 @@ impl> Transform3D { } } -impl> ToMat4 for Transform3D { +impl> ToMat4 for Transform3D { fn to_mat4(&self) -> Mat4 { self.get().to_mat4() } } diff --git a/src/cgmath/vector.rs b/src/cgmath/vector.rs index 9b82f09..fee05c2 100644 --- a/src/cgmath/vector.rs +++ b/src/cgmath/vector.rs @@ -19,13 +19,14 @@ use std::num::{Zero, zero, One, one, sqrt}; use angle::{Rad, atan2, acos}; use approx::ApproxEq; use array::{Array, build}; +use partial_ord::{PartOrdPrim, PartOrdFloat}; /// A trait that specifies a range of numeric operations for vectors. Not all /// of these make sense from a linear algebra point of view, but are included /// for pragmatic reasons. pub trait Vector < - S: Primitive, + S: PartOrdPrim, Slice > : Array @@ -74,7 +75,7 @@ pub trait Vector #[inline] fn comp_max(&self) -> S { self.fold(|a, b| if *a > *b { *a } else {*b }) } } -#[inline] pub fn dot>(a: V, b: V) -> S { a.dot(&b) } +#[inline] pub fn dot>(a: V, b: V) -> S { a.dot(&b) } // Utility macro for generating associated functions for the vectors macro_rules! vec( @@ -103,32 +104,32 @@ macro_rules! vec( pub fn ident() -> $Self<$S> { $Self::from_value(one()) } } - impl Add<$Self, $Self> for $Self { + impl Add<$Self, $Self> for $Self { #[inline] fn add(&self, other: &$Self) -> $Self { self.add_v(other) } } - impl Sub<$Self, $Self> for $Self { + impl Sub<$Self, $Self> for $Self { #[inline] fn sub(&self, other: &$Self) -> $Self { self.sub_v(other) } } - impl Zero for $Self { + impl Zero for $Self { #[inline] fn zero() -> $Self { $Self::from_value(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } } - impl Neg<$Self> for $Self { + impl Neg<$Self> for $Self { #[inline] fn neg(&self) -> $Self { build(|i| self.i(i).neg()) } } - impl Mul<$Self, $Self> for $Self { + impl Mul<$Self, $Self> for $Self { #[inline] fn mul(&self, other: &$Self) -> $Self { self.mul_v(other) } } - impl One for $Self { + impl One for $Self { #[inline] fn one() -> $Self { $Self::from_value(one()) } } - impl Vector for $Self {} + impl Vector for $Self {} ) ) @@ -206,7 +207,7 @@ impl Vec4 { /// 2-dimensional and 3-dimensional vectors. pub trait EuclideanVector < - S: Float + ApproxEq, + S: PartOrdFloat, Slice > : Vector @@ -277,7 +278,7 @@ pub trait EuclideanVector } } -impl> +impl> EuclideanVector for Vec2 { #[inline] fn angle(&self, other: &Vec2) -> Rad { @@ -285,7 +286,7 @@ EuclideanVector for Vec2 { } } -impl> +impl> EuclideanVector for Vec3 { #[inline] fn angle(&self, other: &Vec3) -> Rad { @@ -293,7 +294,7 @@ EuclideanVector for Vec3 { } } -impl> +impl> EuclideanVector for Vec4 { #[inline] fn angle(&self, other: &Vec4) -> Rad {