Replaced partial_{min,max} funcs with PartOrdPrim trait
This commit is contained in:
parent
5c504d4701
commit
83943cd5b5
13 changed files with 161 additions and 101 deletions
|
@ -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<S: Ord>(a: S, b: S) -> S { if a < b { a } else { b }}
|
||||
fn partial_max<S: Ord>(a: S, b: S) -> S { if a > b { a } else { b }}
|
||||
|
||||
pub trait Aabb
|
||||
<
|
||||
S: Primitive,
|
||||
S: PartOrdPrim,
|
||||
V: Vector<S, Slice>,
|
||||
P: Point<S, V, Slice>,
|
||||
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<S> {
|
|||
max: Point2<S>,
|
||||
}
|
||||
|
||||
impl<S: Num + Ord + Clone> Aabb2<S> {
|
||||
impl<S: PartOrdPrim> Aabb2<S> {
|
||||
/// Construct a new axis-aligned bounding box from two points.
|
||||
#[inline]
|
||||
pub fn new(p1: Point2<S>, p2: Point2<S>) -> Aabb2<S> {
|
||||
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<S: Primitive> Aabb<S, Vec2<S>, Point2<S>, [S, ..2]> for Aabb2<S> {
|
||||
impl<S: PartOrdPrim> Aabb<S, Vec2<S>, Point2<S>, [S, ..2]> for Aabb2<S> {
|
||||
fn new(p1: Point2<S>, p2: Point2<S>) -> Aabb2<S> { Aabb2::new(p1, p2) }
|
||||
#[inline] fn min<'a>(&'a self) -> &'a Point2<S> { &self.min }
|
||||
#[inline] fn max<'a>(&'a self) -> &'a Point2<S> { &self.max }
|
||||
|
@ -109,22 +107,22 @@ pub struct Aabb3<S> {
|
|||
max: Point3<S>,
|
||||
}
|
||||
|
||||
impl<S: Num + Ord + Clone> Aabb3<S> {
|
||||
impl<S: PartOrdPrim> Aabb3<S> {
|
||||
/// Construct a new axis-aligned bounding box from two points.
|
||||
#[inline]
|
||||
pub fn new(p1: Point3<S>, p2: Point3<S>) -> Aabb3<S> {
|
||||
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<S: Primitive> Aabb<S, Vec3<S>, Point3<S>, [S, ..3]> for Aabb3<S> {
|
||||
impl<S: PartOrdPrim> Aabb<S, Vec3<S>, Point3<S>, [S, ..3]> for Aabb3<S> {
|
||||
fn new(p1: Point3<S>, p2: Point3<S>) -> Aabb3<S> { Aabb3::new(p1, p2) }
|
||||
#[inline] fn min<'a>(&'a self) -> &'a Point3<S> { &self.min }
|
||||
#[inline] fn max<'a>(&'a self) -> &'a Point3<S> { &self.max }
|
||||
|
|
|
@ -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<S> {
|
||||
|
@ -31,7 +31,7 @@ pub struct Frustum<S> {
|
|||
far: Plane<S>,
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Frustum<S> {
|
||||
/// Constructs a frustum
|
||||
pub fn new(left: Plane<S>, right: Plane<S>,
|
||||
|
|
|
@ -45,3 +45,5 @@ pub mod sphere;
|
|||
|
||||
pub mod approx;
|
||||
pub mod ptr;
|
||||
|
||||
pub mod partial_ord;
|
||||
|
|
|
@ -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<S: Primitive> Mat2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>> Mat2<S> {
|
||||
impl<S: PartOrdFloat<S>> Mat2<S> {
|
||||
pub fn look_at(dir: &Vec2<S>, up: &Vec2<S>) -> Mat2<S> {
|
||||
//TODO: verify look_at 2D
|
||||
Mat2::from_cols(up.clone(), dir.clone()).transpose()
|
||||
|
@ -118,7 +119,7 @@ impl<S: Primitive> Mat3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Mat3<S> {
|
||||
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Mat3<S> {
|
||||
let dir = dir.normalize();
|
||||
|
@ -228,7 +229,7 @@ impl<S: Primitive> Mat4<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Mat4<S> {
|
||||
pub fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vec3<S>) -> Mat4<S> {
|
||||
let f = center.sub_p(eye).normalize();
|
||||
|
@ -248,7 +249,7 @@ array!(impl<S> Mat4<S> -> [Vec4<S>, ..4] _4)
|
|||
|
||||
pub trait Matrix
|
||||
<
|
||||
S: Float + ApproxEq<S>, Slice,
|
||||
S: PartOrdFloat<S>, Slice,
|
||||
V: Clone + Vector<S, VSlice> + Array<S, VSlice>, VSlice
|
||||
>
|
||||
: Array<V, Slice>
|
||||
|
@ -360,31 +361,31 @@ pub trait Matrix
|
|||
fn is_symmetric(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<S: Float> Add<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn add(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
impl<S: Float> Add<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn add(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
impl<S: Float> Add<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn add(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Add<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn add(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Add<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn add(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Add<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn add(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
|
||||
impl<S: Float> Sub<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn sub(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
impl<S: Float> Sub<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn sub(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
impl<S: Float> Sub<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn sub(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Sub<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn sub(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Sub<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn sub(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Sub<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn sub(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
|
||||
impl<S: Float> Neg<Mat2<S>> for Mat2<S> { #[inline] fn neg(&self) -> Mat2<S> { build(|i| self.i(i).neg()) } }
|
||||
impl<S: Float> Neg<Mat3<S>> for Mat3<S> { #[inline] fn neg(&self) -> Mat3<S> { build(|i| self.i(i).neg()) } }
|
||||
impl<S: Float> Neg<Mat4<S>> for Mat4<S> { #[inline] fn neg(&self) -> Mat4<S> { build(|i| self.i(i).neg()) } }
|
||||
impl<S: PartOrdFloat<S>> Neg<Mat2<S>> for Mat2<S> { #[inline] fn neg(&self) -> Mat2<S> { build(|i| self.i(i).neg()) } }
|
||||
impl<S: PartOrdFloat<S>> Neg<Mat3<S>> for Mat3<S> { #[inline] fn neg(&self) -> Mat3<S> { build(|i| self.i(i).neg()) } }
|
||||
impl<S: PartOrdFloat<S>> Neg<Mat4<S>> for Mat4<S> { #[inline] fn neg(&self) -> Mat4<S> { build(|i| self.i(i).neg()) } }
|
||||
|
||||
impl<S: Float> Zero for Mat2<S> { #[inline] fn zero() -> Mat2<S> { Mat2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
impl<S: Float> Zero for Mat3<S> { #[inline] fn zero() -> Mat3<S> { Mat3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
impl<S: Float> Zero for Mat4<S> { #[inline] fn zero() -> Mat4<S> { Mat4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
impl<S: PartOrdFloat<S>> Zero for Mat2<S> { #[inline] fn zero() -> Mat2<S> { Mat2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
impl<S: PartOrdFloat<S>> Zero for Mat3<S> { #[inline] fn zero() -> Mat3<S> { Mat3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
impl<S: PartOrdFloat<S>> Zero for Mat4<S> { #[inline] fn zero() -> Mat4<S> { Mat4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
|
||||
impl<S: Float> Mul<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn mul(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
impl<S: Float> Mul<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn mul(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
impl<S: Float> Mul<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn mul(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Mul<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn mul(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Mul<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn mul(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Mul<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn mul(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
|
||||
impl<S: Float> One for Mat2<S> { #[inline] fn one() -> Mat2<S> { Mat2::identity() } }
|
||||
impl<S: Float> One for Mat3<S> { #[inline] fn one() -> Mat3<S> { Mat3::identity() } }
|
||||
impl<S: Float> One for Mat4<S> { #[inline] fn one() -> Mat4<S> { Mat4::identity() } }
|
||||
impl<S: PartOrdFloat<S>> One for Mat2<S> { #[inline] fn one() -> Mat2<S> { Mat2::identity() } }
|
||||
impl<S: PartOrdFloat<S>> One for Mat3<S> { #[inline] fn one() -> Mat3<S> { Mat3::identity() } }
|
||||
impl<S: PartOrdFloat<S>> One for Mat4<S> { #[inline] fn one() -> Mat4<S> { Mat4::identity() } }
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Matrix<S, [Vec2<S>, ..2], Vec2<S>, [S, ..2]>
|
||||
for Mat2<S>
|
||||
{
|
||||
|
@ -433,7 +434,7 @@ for Mat2<S>
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Matrix<S, [Vec3<S>, ..3], Vec3<S>, [S, ..3]>
|
||||
for Mat3<S>
|
||||
{
|
||||
|
@ -506,7 +507,7 @@ macro_rules! dot_mat4(
|
|||
(*$A.cr(3, $I)) * (*$B.cr($J, 3))
|
||||
))
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Matrix<S, [Vec4<S>, ..4], Vec4<S>, [S, ..4]>
|
||||
for Mat4<S>
|
||||
{
|
||||
|
@ -639,7 +640,7 @@ pub trait ToMat2<S: Primitive> { fn to_mat2(&self) -> Mat2<S>; }
|
|||
pub trait ToMat3<S: Primitive> { fn to_mat3(&self) -> Mat3<S>; }
|
||||
pub trait ToMat4<S: Primitive> { fn to_mat4(&self) -> Mat4<S>; }
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
ToMat3<S> for Mat2<S> {
|
||||
/// Clone the elements of a 2-dimensional matrix into the top corner of a
|
||||
/// 3-dimensional identity matrix.
|
||||
|
@ -650,7 +651,7 @@ ToMat3<S> for Mat2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
ToMat4<S> for Mat2<S> {
|
||||
/// Clone the elements of a 2-dimensional matrix into the top corner of a
|
||||
/// 4-dimensional identity matrix.
|
||||
|
@ -662,7 +663,7 @@ ToMat4<S> for Mat2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
ToMat4<S> for Mat3<S> {
|
||||
/// Clone the elements of a 3-dimensional matrix into the top corner of a
|
||||
/// 4-dimensional identity matrix.
|
||||
|
@ -674,7 +675,7 @@ ToMat4<S> for Mat3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
ToQuat<S> for Mat3<S> {
|
||||
/// Convert the matrix to a quaternion
|
||||
fn to_quat(&self) -> Quat<S> {
|
||||
|
@ -722,7 +723,7 @@ ToQuat<S> for Mat3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S> + fmt::Show> fmt::Show for Mat2<S> {
|
||||
impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Mat2<S> {
|
||||
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<S: Float + ApproxEq<S> + fmt::Show> fmt::Show for Mat2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S> + fmt::Show> fmt::Show for Mat3<S> {
|
||||
impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Mat3<S> {
|
||||
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<S: Float + ApproxEq<S> + fmt::Show> fmt::Show for Mat3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S> + fmt::Show> fmt::Show for Mat4<S> {
|
||||
impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Mat4<S> {
|
||||
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),
|
||||
|
|
52
src/cgmath/partial_ord.rs
Normal file
52
src/cgmath/partial_ord.rs
Normal file
|
@ -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<S> : Float + ApproxEq<S> + PartOrdPrim {}
|
||||
impl PartOrdFloat<f32> for f32 {}
|
||||
impl PartOrdFloat<f64> for f64 {}
|
||||
|
|
@ -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<S> {
|
|||
d: S,
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Plane<S> {
|
||||
/// Construct a plane from a normal vector and a scalar distance
|
||||
pub fn new(n: Vec3<S>, d: S) -> Plane<S> {
|
||||
|
@ -88,7 +89,7 @@ Plane<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float> Intersect<Option<Point3<S>>> for (Plane<S>, Ray3<S>) {
|
||||
impl<S: PartOrdFloat<S>> Intersect<Option<Point3<S>>> for (Plane<S>, Ray3<S>) {
|
||||
fn intersection(&self) -> Option<Point3<S>> {
|
||||
match *self {
|
||||
(ref p, ref r) => {
|
||||
|
|
|
@ -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<S: Num> Point3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Clone + Num + Primitive> Point3<S> {
|
||||
impl<S: PartOrdPrim> Point3<S> {
|
||||
#[inline]
|
||||
pub fn from_homogeneous(v: &Vec4<S>) -> Point3<S> {
|
||||
let e = v.truncate().mul_s(one::<S>() / v.w);
|
||||
|
@ -62,7 +63,7 @@ impl<S: Clone + Num + Primitive> Point3<S> {
|
|||
/// Specifies the numeric operations for point types.
|
||||
pub trait Point
|
||||
<
|
||||
S: Primitive,
|
||||
S: PartOrdPrim,
|
||||
V: Vector<S, Slice>,
|
||||
Slice
|
||||
>
|
||||
|
@ -96,8 +97,8 @@ pub trait Point
|
|||
array!(impl<S> Point2<S> -> [S, ..2] _2)
|
||||
array!(impl<S> Point3<S> -> [S, ..3] _3)
|
||||
|
||||
impl<S: Primitive> Point<S, Vec2<S>, [S, ..2]> for Point2<S> {}
|
||||
impl<S: Primitive> Point<S, Vec3<S>, [S, ..3]> for Point3<S> {}
|
||||
impl<S: PartOrdPrim> Point<S, Vec2<S>, [S, ..2]> for Point2<S> {}
|
||||
impl<S: PartOrdPrim> Point<S, Vec3<S>, [S, ..3]> for Point3<S> {}
|
||||
|
||||
impl<S: fmt::Show> fmt::Show for Point2<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
|
|
@ -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<S: Float, A: Angle<S>> PerspectiveFov<S, A> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>, A: Angle<S>>
|
||||
impl<S: PartOrdFloat<S>, A: Angle<S>>
|
||||
Projection<S> for PerspectiveFov<S, A> {
|
||||
fn to_frustum(&self) -> Frustum<S> {
|
||||
// TODO: Could this be faster?
|
||||
|
@ -151,7 +151,7 @@ pub struct Perspective<S> {
|
|||
near: S, far: S,
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Projection<S> for Perspective<S> {
|
||||
fn to_frustum(&self) -> Frustum<S> {
|
||||
// TODO: Could this be faster?
|
||||
|
@ -202,7 +202,7 @@ pub struct Ortho<S> {
|
|||
near: S, far: S,
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Projection<S> for Ortho<S> {
|
||||
fn to_frustum(&self) -> Frustum<S> {
|
||||
Frustum {
|
||||
|
|
|
@ -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<S: Float> {
|
|||
fn to_quat(&self) -> Quat<S>;
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Quat<S> {
|
||||
/// Construct a new quaternion from one scalar component and three
|
||||
/// imaginary components
|
||||
|
@ -173,7 +174,7 @@ Quat<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S> + Ord>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Quat<S> {
|
||||
/// Spherical Linear Intoperlation
|
||||
///
|
||||
|
@ -279,7 +280,7 @@ ToMat4<S> for Quat<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Neg<Quat<S>> for Quat<S> {
|
||||
#[inline]
|
||||
fn neg(&self) -> Quat<S> {
|
||||
|
@ -299,7 +300,7 @@ impl<S: fmt::Show> fmt::Show for Quat<S> {
|
|||
|
||||
// Quaternion Rotation impls
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
ToBasis3<S> for Quat<S> {
|
||||
#[inline]
|
||||
fn to_rot3(&self) -> Basis3<S> { Basis3::from_quat(self) }
|
||||
|
@ -310,7 +311,7 @@ impl<S: Float> ToQuat<S> for Quat<S> {
|
|||
fn to_quat(&self) -> Quat<S> { self.clone() }
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> {
|
||||
#[inline]
|
||||
fn identity() -> Quat<S> { Quat::identity() }
|
||||
|
@ -343,7 +344,7 @@ Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> {
|
|||
fn invert_self(&mut self) { *self = self.invert() }
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation3<S> for Quat<S>
|
||||
{
|
||||
#[inline]
|
||||
|
|
|
@ -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<S,Slice>,
|
||||
P: Point<S,V,Slice>
|
||||
|
@ -156,7 +157,7 @@ impl<S: Float> ToMat2<S> for Basis2<S> {
|
|||
fn to_mat2(&self) -> Mat2<S> { self.mat.clone() }
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
|
||||
#[inline]
|
||||
fn identity() -> Basis2<S> { Basis2{ mat: Mat2::identity() } }
|
||||
|
@ -191,7 +192,7 @@ Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
|
|||
fn invert_self(&mut self) { self.mat.invert_self(); }
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
ApproxEq<S> for Basis2<S> {
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Basis2<S>, epsilon: &S) -> bool {
|
||||
|
@ -199,7 +200,7 @@ ApproxEq<S> for Basis2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation2<S> for Basis2<S> {
|
||||
fn from_angle(theta: Rad<S>) -> Basis2<S> { Basis2 { mat: Mat2::from_angle(theta) } }
|
||||
}
|
||||
|
@ -215,7 +216,7 @@ pub struct Basis3<S> {
|
|||
priv mat: Mat3<S>
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Basis3<S> {
|
||||
#[inline]
|
||||
pub fn from_quat(quat: &Quat<S>) -> Basis3<S> { Basis3 { mat: quat.to_mat3() } }
|
||||
|
@ -238,13 +239,13 @@ impl<S: Float> ToMat3<S> for Basis3<S> {
|
|||
fn to_mat3(&self) -> Mat3<S> { self.mat.clone() }
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
ToQuat<S> for Basis3<S> {
|
||||
#[inline]
|
||||
fn to_quat(&self) -> Quat<S> { self.mat.to_quat() }
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Basis3<S> {
|
||||
#[inline]
|
||||
fn identity() -> Basis3<S> { Basis3{ mat: Mat3::identity() } }
|
||||
|
@ -288,7 +289,7 @@ ApproxEq<S> for Basis3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation3<S> for Basis3<S> {
|
||||
fn from_axis_angle(axis: &Vec3<S>, angle: Rad<S>) -> Basis3<S> {
|
||||
Basis3 { mat: Mat3::from_axis_angle(axis, angle) }
|
||||
|
|
|
@ -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<S> {
|
|||
radius: S,
|
||||
}
|
||||
|
||||
impl<S: Float> Intersect<Option<Point3<S>>> for (Sphere<S>, Ray3<S>) {
|
||||
impl<S: PartOrdFloat<S>> Intersect<Option<Point3<S>>> for (Sphere<S>, Ray3<S>) {
|
||||
fn intersection(&self) -> Option<Point3<S>> {
|
||||
match *self {
|
||||
(ref s, ref r) => {
|
||||
|
|
|
@ -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<S,Slice>,
|
||||
P: Point<S,V,Slice>
|
||||
|
@ -77,7 +78,7 @@ pub struct Decomposed<S,V,R> {
|
|||
|
||||
impl
|
||||
<
|
||||
S: Float + ApproxEq<S>,
|
||||
S: PartOrdFloat<S>,
|
||||
Slice,
|
||||
V: Vector<S, Slice>,
|
||||
P: Point<S, V, Slice>,
|
||||
|
@ -145,7 +146,7 @@ pub trait Transform3<S>
|
|||
+ ToMat4<S>
|
||||
{}
|
||||
|
||||
impl<S: Float + Clone + ApproxEq<S>, R: Rotation3<S>>
|
||||
impl<S: PartOrdFloat<S>, R: Rotation3<S>>
|
||||
ToMat4<S> for Decomposed<S, Vec3<S>, R> {
|
||||
fn to_mat4(&self) -> Mat4<S> {
|
||||
let mut m = self.rot.to_mat3().mul_s( self.scale.clone() ).to_mat4();
|
||||
|
@ -154,7 +155,7 @@ ToMat4<S> for Decomposed<S, Vec3<S>, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>, R: Rotation3<S>>
|
||||
impl<S: PartOrdFloat<S>, R: Rotation3<S>>
|
||||
Transform3<S> for Decomposed<S,Vec3<S>,R> {}
|
||||
|
||||
impl<S: fmt::Show + Float, R: fmt::Show + Rotation3<S>>
|
||||
|
@ -171,7 +172,7 @@ pub struct AffineMatrix3<S> {
|
|||
mat: Mat4<S>,
|
||||
}
|
||||
|
||||
impl<S : Clone + Float + ApproxEq<S>>
|
||||
impl<S : PartOrdFloat<S>>
|
||||
Transform<S, [S, ..3], Vec3<S>, Point3<S>> for AffineMatrix3<S> {
|
||||
#[inline]
|
||||
fn identity() -> AffineMatrix3<S> {
|
||||
|
@ -204,12 +205,12 @@ Transform<S, [S, ..3], Vec3<S>, Point3<S>> for AffineMatrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Clone + Primitive>
|
||||
impl<S: PartOrdPrim>
|
||||
ToMat4<S> for AffineMatrix3<S> {
|
||||
#[inline] fn to_mat4(&self) -> Mat4<S> { self.mat.clone() }
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Transform3<S> for AffineMatrix3<S> {}
|
||||
|
||||
|
||||
|
@ -217,7 +218,7 @@ Transform3<S> for AffineMatrix3<S> {}
|
|||
/// displacement vector and scale amount.
|
||||
pub struct Transform3D<S>( Decomposed<S,Vec3<S>,Quat<S>> );
|
||||
|
||||
impl<S: Float + ApproxEq<S>> Transform3D<S> {
|
||||
impl<S: PartOrdFloat<S>> Transform3D<S> {
|
||||
#[inline]
|
||||
pub fn new(scale: S, rot: Quat<S>, disp: Vec3<S>) -> Transform3D<S> {
|
||||
Transform3D( Decomposed { scale: scale, rot: rot, disp: disp })
|
||||
|
@ -235,6 +236,6 @@ impl<S: Float + ApproxEq<S>> Transform3D<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>> ToMat4<S> for Transform3D<S> {
|
||||
impl<S: PartOrdFloat<S>> ToMat4<S> for Transform3D<S> {
|
||||
fn to_mat4(&self) -> Mat4<S> { self.get().to_mat4() }
|
||||
}
|
||||
|
|
|
@ -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<S, Slice>
|
||||
|
@ -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<S: Primitive, Slice, V: Vector<S, Slice>>(a: V, b: V) -> S { a.dot(&b) }
|
||||
#[inline] pub fn dot<S: PartOrdPrim, Slice, V: Vector<S, Slice>>(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<S: Primitive> Add<$Self<S>, $Self<S>> for $Self<S> {
|
||||
impl<S: PartOrdPrim> Add<$Self<S>, $Self<S>> for $Self<S> {
|
||||
#[inline] fn add(&self, other: &$Self<S>) -> $Self<S> { self.add_v(other) }
|
||||
}
|
||||
|
||||
impl<S: Primitive> Sub<$Self<S>, $Self<S>> for $Self<S> {
|
||||
impl<S: PartOrdPrim> Sub<$Self<S>, $Self<S>> for $Self<S> {
|
||||
#[inline] fn sub(&self, other: &$Self<S>) -> $Self<S> { self.sub_v(other) }
|
||||
}
|
||||
|
||||
impl<S: Primitive> Zero for $Self<S> {
|
||||
impl<S: PartOrdPrim> Zero for $Self<S> {
|
||||
#[inline] fn zero() -> $Self<S> { $Self::from_value(zero()) }
|
||||
#[inline] fn is_zero(&self) -> bool { *self == zero() }
|
||||
}
|
||||
|
||||
impl<S: Primitive> Neg<$Self<S>> for $Self<S> {
|
||||
impl<S: PartOrdPrim> Neg<$Self<S>> for $Self<S> {
|
||||
#[inline] fn neg(&self) -> $Self<S> { build(|i| self.i(i).neg()) }
|
||||
}
|
||||
|
||||
impl<S: Primitive> Mul<$Self<S>, $Self<S>> for $Self<S> {
|
||||
impl<S: PartOrdPrim> Mul<$Self<S>, $Self<S>> for $Self<S> {
|
||||
#[inline] fn mul(&self, other: &$Self<S>) -> $Self<S> { self.mul_v(other) }
|
||||
}
|
||||
|
||||
impl<S: Primitive> One for $Self<S> {
|
||||
impl<S: PartOrdPrim> One for $Self<S> {
|
||||
#[inline] fn one() -> $Self<S> { $Self::from_value(one()) }
|
||||
}
|
||||
|
||||
impl<S: Primitive> Vector<S, [S, ..$n]> for $Self<S> {}
|
||||
impl<S: PartOrdPrim> Vector<S, [S, ..$n]> for $Self<S> {}
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -206,7 +207,7 @@ impl<S: Primitive> Vec4<S> {
|
|||
/// 2-dimensional and 3-dimensional vectors.
|
||||
pub trait EuclideanVector
|
||||
<
|
||||
S: Float + ApproxEq<S>,
|
||||
S: PartOrdFloat<S>,
|
||||
Slice
|
||||
>
|
||||
: Vector<S, Slice>
|
||||
|
@ -277,7 +278,7 @@ pub trait EuclideanVector
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
EuclideanVector<S, [S, ..2]> for Vec2<S> {
|
||||
#[inline]
|
||||
fn angle(&self, other: &Vec2<S>) -> Rad<S> {
|
||||
|
@ -285,7 +286,7 @@ EuclideanVector<S, [S, ..2]> for Vec2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
EuclideanVector<S, [S, ..3]> for Vec3<S> {
|
||||
#[inline]
|
||||
fn angle(&self, other: &Vec3<S>) -> Rad<S> {
|
||||
|
@ -293,7 +294,7 @@ EuclideanVector<S, [S, ..3]> for Vec3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: PartOrdFloat<S>>
|
||||
EuclideanVector<S, [S, ..4]> for Vec4<S> {
|
||||
#[inline]
|
||||
fn angle(&self, other: &Vec4<S>) -> Rad<S> {
|
||||
|
|
Loading…
Reference in a new issue