Clean up numeric traits
This commit is contained in:
parent
c54dc4fd61
commit
d4ce9c7613
18 changed files with 317 additions and 317 deletions
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -23,14 +23,14 @@
|
|||
use point::{Point, Point2, Point3};
|
||||
use vector::{Vector, Vector2, Vector3};
|
||||
use array::build;
|
||||
use partial_ord::PartOrdPrim;
|
||||
use num::BaseNum;
|
||||
use std::fmt;
|
||||
use std::num::{zero, one};
|
||||
use std::iter::Iterator;
|
||||
|
||||
pub trait Aabb
|
||||
<
|
||||
S: PartOrdPrim,
|
||||
S: BaseNum,
|
||||
V: Vector<S, Slice>,
|
||||
P: Point<S, V, Slice>,
|
||||
Slice
|
||||
|
@ -65,8 +65,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| self.min().i(i).min(*p.i(i)));
|
||||
let max : P = build(|i| self.max().i(i).max(*p.i(i)));
|
||||
let min : P = build(|i| self.min().i(i).partial_min(*p.i(i)));
|
||||
let max : P = build(|i| self.max().i(i).partial_max(*p.i(i)));
|
||||
Aabb::new(min, max)
|
||||
}
|
||||
|
||||
|
@ -95,26 +95,26 @@ pub struct Aabb2<S> {
|
|||
pub max: Point2<S>,
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Aabb2<S> {
|
||||
impl<S: BaseNum> 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(p1.x.min(p2.x),
|
||||
p1.y.min(p2.y)),
|
||||
max: Point2::new(p1.x.max(p2.x),
|
||||
p1.y.max(p2.y)),
|
||||
min: Point2::new(p1.x.partial_min(p2.x),
|
||||
p1.y.partial_min(p2.y)),
|
||||
max: Point2::new(p1.x.partial_max(p2.x),
|
||||
p1.y.partial_max(p2.y)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Aabb<S, Vector2<S>, Point2<S>, [S, ..2]> for Aabb2<S> {
|
||||
impl<S: BaseNum> Aabb<S, Vector2<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 }
|
||||
}
|
||||
|
||||
impl<S: fmt::Show> fmt::Show for Aabb2<S> {
|
||||
impl<S: BaseNum> fmt::Show for Aabb2<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[{} - {}]", self.min, self.max)
|
||||
}
|
||||
|
@ -127,28 +127,28 @@ pub struct Aabb3<S> {
|
|||
pub max: Point3<S>,
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Aabb3<S> {
|
||||
impl<S: BaseNum> 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(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)),
|
||||
min: Point3::new(p1.x.partial_min(p2.x),
|
||||
p1.y.partial_min(p2.y),
|
||||
p1.z.partial_min(p2.z)),
|
||||
max: Point3::new(p1.x.partial_max(p2.x),
|
||||
p1.y.partial_max(p2.y),
|
||||
p1.z.partial_max(p2.z)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Aabb<S, Vector3<S>, Point3<S>, [S, ..3]> for Aabb3<S> {
|
||||
impl<S: BaseNum> Aabb<S, Vector3<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 }
|
||||
}
|
||||
|
||||
impl<S: fmt::Show> fmt::Show for Aabb3<S> {
|
||||
impl<S: BaseNum> fmt::Show for Aabb3<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[{} - {}]", self.min, self.max)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -19,6 +19,7 @@ use std::fmt;
|
|||
use std::num::{One, one, Zero, zero, cast};
|
||||
|
||||
use approx::ApproxEq;
|
||||
use num::BaseFloat;
|
||||
|
||||
/// An angle, in radians
|
||||
#[deriving(Clone, Eq, Ord, Hash)] pub struct Rad<S> { pub s: S }
|
||||
|
@ -26,27 +27,27 @@ use approx::ApproxEq;
|
|||
#[deriving(Clone, Eq, Ord, Hash)] pub struct Deg<S> { pub s: S }
|
||||
|
||||
/// Create a new angle, in radians
|
||||
#[inline] pub fn rad<S: Float>(s: S) -> Rad<S> { Rad { s: s } }
|
||||
#[inline] pub fn rad<S: BaseFloat>(s: S) -> Rad<S> { Rad { s: s } }
|
||||
/// Create a new angle, in degrees
|
||||
#[inline] pub fn deg<S: Float>(s: S) -> Deg<S> { Deg { s: s } }
|
||||
#[inline] pub fn deg<S: BaseFloat>(s: S) -> Deg<S> { Deg { s: s } }
|
||||
|
||||
/// Represents types that can be converted to radians.
|
||||
pub trait ToRad<S: Float> {
|
||||
pub trait ToRad<S: BaseFloat> {
|
||||
/// Convert this value to radians.
|
||||
fn to_rad(&self) -> Rad<S>;
|
||||
}
|
||||
|
||||
/// Represents types that can be converted to degrees.
|
||||
pub trait ToDeg<S: Float> {
|
||||
pub trait ToDeg<S: BaseFloat> {
|
||||
/// Convert this value to degrees.
|
||||
fn to_deg(&self) -> Deg<S>;
|
||||
}
|
||||
|
||||
impl<S: Float> ToRad<S> for Rad<S> { #[inline] fn to_rad(&self) -> Rad<S> { self.clone() } }
|
||||
impl<S: Float> ToRad<S> for Deg<S> { #[inline] fn to_rad(&self) -> Rad<S> { rad(self.s.to_radians()) } }
|
||||
impl<S: BaseFloat> ToRad<S> for Rad<S> { #[inline] fn to_rad(&self) -> Rad<S> { self.clone() } }
|
||||
impl<S: BaseFloat> ToRad<S> for Deg<S> { #[inline] fn to_rad(&self) -> Rad<S> { rad(self.s.to_radians()) } }
|
||||
|
||||
impl<S: Float> ToDeg<S> for Rad<S> { #[inline] fn to_deg(&self) -> Deg<S> { deg(self.s.to_degrees()) } }
|
||||
impl<S: Float> ToDeg<S> for Deg<S> { #[inline] fn to_deg(&self) -> Deg<S> { self.clone() } }
|
||||
impl<S: BaseFloat> ToDeg<S> for Rad<S> { #[inline] fn to_deg(&self) -> Deg<S> { deg(self.s.to_degrees()) } }
|
||||
impl<S: BaseFloat> ToDeg<S> for Deg<S> { #[inline] fn to_deg(&self) -> Deg<S> { self.clone() } }
|
||||
|
||||
/// Private utility functions for converting to/from scalars
|
||||
trait ScalarConv<S> {
|
||||
|
@ -55,13 +56,13 @@ trait ScalarConv<S> {
|
|||
fn mut_s<'a>(&'a mut self) -> &'a mut S;
|
||||
}
|
||||
|
||||
impl<S: Float> ScalarConv<S> for Rad<S> {
|
||||
impl<S: BaseFloat> ScalarConv<S> for Rad<S> {
|
||||
#[inline] fn from(s: S) -> Rad<S> { rad(s) }
|
||||
#[inline] fn s<'a>(&'a self) -> &'a S { &'a self.s }
|
||||
#[inline] fn mut_s<'a>(&'a mut self) -> &'a mut S { &'a mut self.s }
|
||||
}
|
||||
|
||||
impl<S: Float> ScalarConv<S> for Deg<S> {
|
||||
impl<S: BaseFloat> ScalarConv<S> for Deg<S> {
|
||||
#[inline] fn from(s: S) -> Deg<S> { deg(s) }
|
||||
#[inline] fn s<'a>(&'a self) -> &'a S { &'a self.s }
|
||||
#[inline] fn mut_s<'a>(&'a mut self) -> &'a mut S { &'a mut self.s }
|
||||
|
@ -70,7 +71,7 @@ impl<S: Float> ScalarConv<S> for Deg<S> {
|
|||
/// Operations on angles.
|
||||
pub trait Angle
|
||||
<
|
||||
S: Float
|
||||
S: BaseFloat
|
||||
>
|
||||
: Clone + Zero
|
||||
+ Eq + Equiv<Self> + Ord
|
||||
|
@ -150,9 +151,9 @@ pub trait Angle
|
|||
#[inline] fn turn_div_6() -> Self { let full_turn: Self = Angle::full_turn(); full_turn.div_s(cast(6).unwrap()) }
|
||||
}
|
||||
|
||||
#[inline] pub fn bisect<S: Float, A: Angle<S>>(a: A, b: A) -> A { a.bisect(b) }
|
||||
#[inline] pub fn bisect<S: BaseFloat, A: Angle<S>>(a: A, b: A) -> A { a.bisect(b) }
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: BaseFloat>
|
||||
Rad<S> {
|
||||
#[inline] pub fn zero() -> Rad<S> { zero() }
|
||||
#[inline] pub fn full_turn() -> Rad<S> { Angle::full_turn() }
|
||||
|
@ -162,7 +163,7 @@ Rad<S> {
|
|||
#[inline] pub fn turn_div_6() -> Rad<S> { Angle::turn_div_6() }
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: BaseFloat>
|
||||
Deg<S> {
|
||||
#[inline] pub fn zero() -> Deg<S> { zero() }
|
||||
#[inline] pub fn full_turn() -> Deg<S> { Angle::full_turn() }
|
||||
|
@ -173,79 +174,79 @@ Deg<S> {
|
|||
}
|
||||
|
||||
|
||||
impl<S: Float> Add<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn add(&self, other: &Rad<S>) -> Rad<S> { rad(self.s + other.s) } }
|
||||
impl<S: Float> Add<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn add(&self, other: &Deg<S>) -> Deg<S> { deg(self.s + other.s) } }
|
||||
impl<S: BaseFloat> Add<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn add(&self, other: &Rad<S>) -> Rad<S> { rad(self.s + other.s) } }
|
||||
impl<S: BaseFloat> Add<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn add(&self, other: &Deg<S>) -> Deg<S> { deg(self.s + other.s) } }
|
||||
|
||||
impl<S: Float> Sub<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn sub(&self, other: &Rad<S>) -> Rad<S> { rad(self.s - other.s) } }
|
||||
impl<S: Float> Sub<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn sub(&self, other: &Deg<S>) -> Deg<S> { deg(self.s - other.s) } }
|
||||
impl<S: BaseFloat> Sub<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn sub(&self, other: &Rad<S>) -> Rad<S> { rad(self.s - other.s) } }
|
||||
impl<S: BaseFloat> Sub<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn sub(&self, other: &Deg<S>) -> Deg<S> { deg(self.s - other.s) } }
|
||||
|
||||
impl<S: Float> Neg<Rad<S>> for Rad<S> { #[inline] fn neg(&self) -> Rad<S> { rad(-self.s) } }
|
||||
impl<S: Float> Neg<Deg<S>> for Deg<S> { #[inline] fn neg(&self) -> Deg<S> { deg(-self.s) } }
|
||||
impl<S: BaseFloat> Neg<Rad<S>> for Rad<S> { #[inline] fn neg(&self) -> Rad<S> { rad(-self.s) } }
|
||||
impl<S: BaseFloat> Neg<Deg<S>> for Deg<S> { #[inline] fn neg(&self) -> Deg<S> { deg(-self.s) } }
|
||||
|
||||
impl<S: Float> Zero for Rad<S> { #[inline] fn zero() -> Rad<S> { rad(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
impl<S: Float> Zero for Deg<S> { #[inline] fn zero() -> Deg<S> { deg(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
impl<S: BaseFloat> Zero for Rad<S> { #[inline] fn zero() -> Rad<S> { rad(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
impl<S: BaseFloat> Zero for Deg<S> { #[inline] fn zero() -> Deg<S> { deg(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
|
||||
impl<S: Float> Mul<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn mul(&self, other: &Rad<S>) -> Rad<S> { rad(self.s * other.s) } }
|
||||
impl<S: Float> Mul<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn mul(&self, other: &Deg<S>) -> Deg<S> { deg(self.s * other.s) } }
|
||||
impl<S: BaseFloat> Mul<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn mul(&self, other: &Rad<S>) -> Rad<S> { rad(self.s * other.s) } }
|
||||
impl<S: BaseFloat> Mul<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn mul(&self, other: &Deg<S>) -> Deg<S> { deg(self.s * other.s) } }
|
||||
|
||||
impl<S: Float> One for Rad<S> { #[inline] fn one() -> Rad<S> { rad(one()) } }
|
||||
impl<S: Float> One for Deg<S> { #[inline] fn one() -> Deg<S> { deg(one()) } }
|
||||
impl<S: BaseFloat> One for Rad<S> { #[inline] fn one() -> Rad<S> { rad(one()) } }
|
||||
impl<S: BaseFloat> One for Deg<S> { #[inline] fn one() -> Deg<S> { deg(one()) } }
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: BaseFloat>
|
||||
Equiv<Rad<S>> for Rad<S> {
|
||||
fn equiv(&self, other: &Rad<S>) -> bool {
|
||||
self.normalize() == other.normalize()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: BaseFloat>
|
||||
Equiv<Deg<S>> for Deg<S> {
|
||||
fn equiv(&self, other: &Deg<S>) -> bool {
|
||||
self.normalize() == other.normalize()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: BaseFloat>
|
||||
Angle<S> for Rad<S> {
|
||||
#[inline] fn from<A: Angle<S>>(theta: A) -> Rad<S> { theta.to_rad() }
|
||||
#[inline] fn full_turn() -> Rad<S> { rad(Float::two_pi()) }
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: BaseFloat>
|
||||
Angle<S> for Deg<S> {
|
||||
#[inline] fn from<A: Angle<S>>(theta: A) -> Deg<S> { theta.to_deg() }
|
||||
#[inline] fn full_turn() -> Deg<S> { deg(cast(360).unwrap()) }
|
||||
}
|
||||
|
||||
#[inline] pub fn sin<S: FloatMath>(theta: Rad<S>) -> S { theta.s.sin() }
|
||||
#[inline] pub fn cos<S: FloatMath>(theta: Rad<S>) -> S { theta.s.cos() }
|
||||
#[inline] pub fn tan<S: FloatMath>(theta: Rad<S>) -> S { theta.s.tan() }
|
||||
#[inline] pub fn sin_cos<S: FloatMath>(theta: Rad<S>) -> (S, S) { theta.s.sin_cos() }
|
||||
#[inline] pub fn sin<S: BaseFloat>(theta: Rad<S>) -> S { theta.s.sin() }
|
||||
#[inline] pub fn cos<S: BaseFloat>(theta: Rad<S>) -> S { theta.s.cos() }
|
||||
#[inline] pub fn tan<S: BaseFloat>(theta: Rad<S>) -> S { theta.s.tan() }
|
||||
#[inline] pub fn sin_cos<S: BaseFloat>(theta: Rad<S>) -> (S, S) { theta.s.sin_cos() }
|
||||
|
||||
#[inline] pub fn cot<S: FloatMath>(theta: Rad<S>) -> S { tan(theta).recip() }
|
||||
#[inline] pub fn sec<S: FloatMath>(theta: Rad<S>) -> S { cos(theta).recip() }
|
||||
#[inline] pub fn csc<S: FloatMath>(theta: Rad<S>) -> S { sin(theta).recip() }
|
||||
#[inline] pub fn cot<S: BaseFloat>(theta: Rad<S>) -> S { tan(theta).recip() }
|
||||
#[inline] pub fn sec<S: BaseFloat>(theta: Rad<S>) -> S { cos(theta).recip() }
|
||||
#[inline] pub fn csc<S: BaseFloat>(theta: Rad<S>) -> S { sin(theta).recip() }
|
||||
|
||||
#[inline] pub fn asin<S: FloatMath>(s: S) -> Rad<S> { rad(s.asin()) }
|
||||
#[inline] pub fn acos<S: FloatMath>(s: S) -> Rad<S> { rad(s.acos()) }
|
||||
#[inline] pub fn atan<S: FloatMath>(s: S) -> Rad<S> { rad(s.atan()) }
|
||||
#[inline] pub fn atan2<S: FloatMath>(a: S, b: S) -> Rad<S> { rad(a.atan2(b)) }
|
||||
#[inline] pub fn asin<S: BaseFloat>(s: S) -> Rad<S> { rad(s.asin()) }
|
||||
#[inline] pub fn acos<S: BaseFloat>(s: S) -> Rad<S> { rad(s.acos()) }
|
||||
#[inline] pub fn atan<S: BaseFloat>(s: S) -> Rad<S> { rad(s.atan()) }
|
||||
#[inline] pub fn atan2<S: BaseFloat>(a: S, b: S) -> Rad<S> { rad(a.atan2(b)) }
|
||||
|
||||
impl<S: Float + fmt::Show>
|
||||
impl<S: BaseFloat + fmt::Show>
|
||||
fmt::Show for Rad<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} rad", self.s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Float + fmt::Show>
|
||||
impl<S: BaseFloat + fmt::Show>
|
||||
fmt::Show for Deg<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}°", self.s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: BaseFloat>
|
||||
ApproxEq<S> for Rad<S> {
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Rad<S>, epsilon: &S) -> bool {
|
||||
|
@ -253,7 +254,7 @@ ApproxEq<S> for Rad<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: BaseFloat>
|
||||
ApproxEq<S> for Deg<S> {
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Deg<S>, epsilon: &S) -> bool {
|
||||
|
|
|
@ -74,4 +74,3 @@ approx_array!(impl<S> Vector4<S>)
|
|||
|
||||
approx_array!(impl<S> Point2<S>)
|
||||
approx_array!(impl<S> Point3<S>)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -16,10 +16,10 @@
|
|||
//! View frustum for visibility determination
|
||||
|
||||
use matrix::{Matrix, Matrix4};
|
||||
use num::BaseFloat;
|
||||
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> {
|
|||
pub far: Plane<S>,
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
Frustum<S> {
|
||||
/// Constructs a frustum
|
||||
pub fn new(left: Plane<S>, right: Plane<S>,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -62,6 +62,6 @@ pub mod obb;
|
|||
pub mod sphere;
|
||||
|
||||
pub mod approx;
|
||||
pub mod num;
|
||||
pub mod ptr;
|
||||
|
||||
pub mod partial_ord;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
|
||||
// refer to the AUTHORS file at the top-level directionectory of this distribution.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -17,9 +17,9 @@
|
|||
|
||||
use std::num::{Zero, zero, One, one};
|
||||
|
||||
use num::{BaseFloat, BaseNum};
|
||||
use point::{Point, Point2, Point3};
|
||||
use vector::{Vector, Vector2};
|
||||
use partial_ord::PartOrdFloat;
|
||||
use intersect::Intersect;
|
||||
|
||||
/// A generic directed line segment from `origin` to `dest`.
|
||||
|
@ -32,7 +32,7 @@ pub struct Line<P>
|
|||
|
||||
impl
|
||||
<
|
||||
S: Primitive,
|
||||
S: BaseNum,
|
||||
Slice,
|
||||
V: Vector<S,Slice>,
|
||||
P: Point<S,V,Slice>
|
||||
|
@ -49,7 +49,7 @@ pub type Line3<S> = Line<Point3<S>>;
|
|||
/// Determines if an intersection between two line segments is found. If the segments are
|
||||
/// collinear and overlapping, the intersection point that will be returned will be the first
|
||||
/// intersection point found by traversing the first line segment, starting at its origin.
|
||||
impl<S: PartOrdFloat<S>> Intersect<Option<Point2<S>>> for (Line2<S>, Line2<S>) {
|
||||
impl<S: BaseFloat> Intersect<Option<Point2<S>>> for (Line2<S>, Line2<S>) {
|
||||
fn intersection(&self) -> Option<Point2<S>> {
|
||||
match *self {
|
||||
(ref l1, ref l2) => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -21,11 +21,11 @@ use std::num::{Zero, zero, One, one, cast};
|
|||
use angle::{Rad, sin, cos, sin_cos};
|
||||
use approx::ApproxEq;
|
||||
use array::{Array, build};
|
||||
use num::{BaseFloat, BaseNum};
|
||||
use point::{Point, Point3};
|
||||
use quaternion::{Quaternion, ToQuaternion};
|
||||
use vector::{Vector, EuclideanVector};
|
||||
use vector::{Vector2, Vector3, Vector4};
|
||||
use partial_ord::PartOrdFloat;
|
||||
|
||||
/// A 2 x 2, column major matrix
|
||||
#[deriving(Clone, Eq)]
|
||||
|
@ -40,7 +40,7 @@ pub struct Matrix3<S> { pub x: Vector3<S>, pub y: Vector3<S>, pub z: Vector3<S>
|
|||
pub struct Matrix4<S> { pub x: Vector4<S>, pub y: Vector4<S>, pub z: Vector4<S>, pub w: Vector4<S> }
|
||||
|
||||
|
||||
impl<S: Primitive> Matrix2<S> {
|
||||
impl<S: BaseNum> Matrix2<S> {
|
||||
/// Create a new matrix, providing values for each index.
|
||||
#[inline]
|
||||
pub fn new(c0r0: S, c0r1: S,
|
||||
|
@ -76,7 +76,7 @@ impl<S: Primitive> Matrix2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>> Matrix2<S> {
|
||||
impl<S: BaseFloat> Matrix2<S> {
|
||||
/// Create a transformation matrix that will cause a vector to point at
|
||||
/// `dir`, using `up` for orientation.
|
||||
pub fn look_at(dir: &Vector2<S>, up: &Vector2<S>) -> Matrix2<S> {
|
||||
|
@ -94,7 +94,7 @@ impl<S: PartOrdFloat<S>> Matrix2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Primitive> Matrix3<S> {
|
||||
impl<S: BaseNum> Matrix3<S> {
|
||||
/// Create a new matrix, providing values for each index.
|
||||
#[inline]
|
||||
pub fn new(c0r0:S, c0r1:S, c0r2:S,
|
||||
|
@ -133,7 +133,7 @@ impl<S: Primitive> Matrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
Matrix3<S> {
|
||||
/// Create a transformation matrix that will cause a vector to point at
|
||||
/// `dir`, using `up` for orientation.
|
||||
|
@ -209,7 +209,7 @@ Matrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Primitive> Matrix4<S> {
|
||||
impl<S: BaseNum> Matrix4<S> {
|
||||
/// Create a new matrix, providing values for each index.
|
||||
#[inline]
|
||||
pub fn new(c0r0: S, c0r1: S, c0r2: S, c0r3: S,
|
||||
|
@ -251,7 +251,7 @@ impl<S: Primitive> Matrix4<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
Matrix4<S> {
|
||||
/// Create a transformation matrix that will cause a vector to point at
|
||||
/// `dir`, using `up` for orientation.
|
||||
|
@ -273,7 +273,7 @@ array!(impl<S> Matrix4<S> -> [Vector4<S>, ..4] _4)
|
|||
|
||||
pub trait Matrix
|
||||
<
|
||||
S: PartOrdFloat<S>, Slice,
|
||||
S: BaseFloat, Slice,
|
||||
V: Clone + Vector<S, VSlice> + Array<S, VSlice>, VSlice
|
||||
>
|
||||
: Array<V, Slice>
|
||||
|
@ -417,31 +417,31 @@ pub trait Matrix
|
|||
fn is_symmetric(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>> Add<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn add(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Add<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn add(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Add<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn add(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
impl<S: BaseFloat> Add<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn add(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
impl<S: BaseFloat> Add<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn add(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
impl<S: BaseFloat> Add<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn add(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).add_v(other.i(i))) } }
|
||||
|
||||
impl<S: PartOrdFloat<S>> Sub<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn sub(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Sub<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn sub(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Sub<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn sub(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
impl<S: BaseFloat> Sub<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn sub(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
impl<S: BaseFloat> Sub<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn sub(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
impl<S: BaseFloat> Sub<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn sub(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
|
||||
|
||||
impl<S: PartOrdFloat<S>> Neg<Matrix2<S>> for Matrix2<S> { #[inline] fn neg(&self) -> Matrix2<S> { build(|i| self.i(i).neg()) } }
|
||||
impl<S: PartOrdFloat<S>> Neg<Matrix3<S>> for Matrix3<S> { #[inline] fn neg(&self) -> Matrix3<S> { build(|i| self.i(i).neg()) } }
|
||||
impl<S: PartOrdFloat<S>> Neg<Matrix4<S>> for Matrix4<S> { #[inline] fn neg(&self) -> Matrix4<S> { build(|i| self.i(i).neg()) } }
|
||||
impl<S: BaseFloat> Neg<Matrix2<S>> for Matrix2<S> { #[inline] fn neg(&self) -> Matrix2<S> { build(|i| self.i(i).neg()) } }
|
||||
impl<S: BaseFloat> Neg<Matrix3<S>> for Matrix3<S> { #[inline] fn neg(&self) -> Matrix3<S> { build(|i| self.i(i).neg()) } }
|
||||
impl<S: BaseFloat> Neg<Matrix4<S>> for Matrix4<S> { #[inline] fn neg(&self) -> Matrix4<S> { build(|i| self.i(i).neg()) } }
|
||||
|
||||
impl<S: PartOrdFloat<S>> Zero for Matrix2<S> { #[inline] fn zero() -> Matrix2<S> { Matrix2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
impl<S: PartOrdFloat<S>> Zero for Matrix3<S> { #[inline] fn zero() -> Matrix3<S> { Matrix3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
impl<S: PartOrdFloat<S>> Zero for Matrix4<S> { #[inline] fn zero() -> Matrix4<S> { Matrix4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
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() } }
|
||||
impl<S: BaseFloat> Zero for Matrix4<S> { #[inline] fn zero() -> Matrix4<S> { Matrix4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
|
||||
|
||||
impl<S: PartOrdFloat<S>> Mul<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn mul(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Mul<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn mul(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
impl<S: PartOrdFloat<S>> Mul<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn mul(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
impl<S: BaseFloat> Mul<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn mul(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
impl<S: BaseFloat> Mul<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn mul(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
impl<S: BaseFloat> Mul<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn mul(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
|
||||
|
||||
impl<S: PartOrdFloat<S>> One for Matrix2<S> { #[inline] fn one() -> Matrix2<S> { Matrix2::identity() } }
|
||||
impl<S: PartOrdFloat<S>> One for Matrix3<S> { #[inline] fn one() -> Matrix3<S> { Matrix3::identity() } }
|
||||
impl<S: PartOrdFloat<S>> One for Matrix4<S> { #[inline] fn one() -> Matrix4<S> { Matrix4::identity() } }
|
||||
impl<S: BaseFloat> One for Matrix2<S> { #[inline] fn one() -> Matrix2<S> { Matrix2::identity() } }
|
||||
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: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
Matrix<S, [Vector2<S>, ..2], Vector2<S>, [S, ..2]>
|
||||
for Matrix2<S>
|
||||
{
|
||||
|
@ -490,7 +490,7 @@ for Matrix2<S>
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
Matrix<S, [Vector3<S>, ..3], Vector3<S>, [S, ..3]>
|
||||
for Matrix3<S>
|
||||
{
|
||||
|
@ -563,7 +563,7 @@ macro_rules! dot_matrix4(
|
|||
(*$A.cr(3, $I)) * (*$B.cr($J, 3))
|
||||
))
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
Matrix<S, [Vector4<S>, ..4], Vector4<S>, [S, ..4]>
|
||||
for Matrix4<S>
|
||||
{
|
||||
|
@ -694,24 +694,24 @@ for Matrix4<S>
|
|||
// Conversion traits
|
||||
|
||||
/// Represents types which can be converted to a Matrix2
|
||||
pub trait ToMatrix2<S: Primitive> {
|
||||
pub trait ToMatrix2<S: BaseNum> {
|
||||
/// Convert this value to a Matrix2
|
||||
fn to_matrix2(&self) -> Matrix2<S>;
|
||||
}
|
||||
|
||||
/// Represents types which can be converted to a Matrix3
|
||||
pub trait ToMatrix3<S: Primitive> {
|
||||
pub trait ToMatrix3<S: BaseNum> {
|
||||
/// Convert this value to a Matrix3
|
||||
fn to_matrix3(&self) -> Matrix3<S>;
|
||||
}
|
||||
|
||||
/// Represents types which can be converted to a Matrix4
|
||||
pub trait ToMatrix4<S: Primitive> {
|
||||
pub trait ToMatrix4<S: BaseNum> {
|
||||
/// Convert this value to a Matrix4
|
||||
fn to_matrix4(&self) -> Matrix4<S>;
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
ToMatrix3<S> for Matrix2<S> {
|
||||
/// Clone the elements of a 2-dimensional matrix into the top-left corner
|
||||
/// of a 3-dimensional identity matrix.
|
||||
|
@ -722,7 +722,7 @@ ToMatrix3<S> for Matrix2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
ToMatrix4<S> for Matrix2<S> {
|
||||
/// Clone the elements of a 2-dimensional matrix into the top-left corner
|
||||
/// of a 4-dimensional identity matrix.
|
||||
|
@ -734,7 +734,7 @@ ToMatrix4<S> for Matrix2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
ToMatrix4<S> for Matrix3<S> {
|
||||
/// Clone the elements of a 3-dimensional matrix into the top-left corner
|
||||
/// of a 4-dimensional identity matrix.
|
||||
|
@ -746,7 +746,7 @@ ToMatrix4<S> for Matrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
ToQuaternion<S> for Matrix3<S> {
|
||||
/// Convert the matrix to a quaternion
|
||||
fn to_quaternion(&self) -> Quaternion<S> {
|
||||
|
@ -794,7 +794,7 @@ ToQuaternion<S> for Matrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Matrix2<S> {
|
||||
impl<S: BaseFloat> fmt::Show for Matrix2<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[[{}, {}], [{}, {}]]",
|
||||
self.cr(0, 0), self.cr(0, 1),
|
||||
|
@ -802,7 +802,7 @@ impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Matrix2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Matrix3<S> {
|
||||
impl<S: BaseFloat> fmt::Show for Matrix3<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[[{}, {}, {}], [{}, {}, {}], [{}, {}, {}]]",
|
||||
self.cr(0, 0), self.cr(0, 1), self.cr(0, 2),
|
||||
|
@ -811,7 +811,7 @@ impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Matrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Matrix4<S> {
|
||||
impl<S: BaseFloat> fmt::Show for Matrix4<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[[{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}]]",
|
||||
self.cr(0, 0), self.cr(0, 1), self.cr(0, 2), self.cr(0, 3),
|
||||
|
|
95
src/cgmath/num.rs
Normal file
95
src/cgmath/num.rs
Normal file
|
@ -0,0 +1,95 @@
|
|||
// Copyright 2013-2014 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;
|
||||
use std::fmt;
|
||||
|
||||
/// A trait providing a [partial ordering][po]
|
||||
///
|
||||
/// [po]: http://mathworld.wolfram.com/PartialOrder.html
|
||||
pub trait PartialOrd {
|
||||
fn partial_min(self, other: Self) -> Self;
|
||||
fn partial_max(self, other: Self) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! partial_ord_int (
|
||||
($T:ident) => (
|
||||
impl PartialOrd for $T {
|
||||
fn partial_min(self, other: $T) -> $T { cmp::min(self, other) }
|
||||
fn partial_max(self, other: $T) -> $T { cmp::max(self, other) }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
partial_ord_int!(int)
|
||||
partial_ord_int!(i8)
|
||||
partial_ord_int!(i16)
|
||||
partial_ord_int!(i32)
|
||||
partial_ord_int!(i64)
|
||||
partial_ord_int!(uint)
|
||||
partial_ord_int!(u8)
|
||||
partial_ord_int!(u16)
|
||||
partial_ord_int!(u32)
|
||||
partial_ord_int!(u64)
|
||||
|
||||
macro_rules! partial_ord_float (
|
||||
($T:ident) => (
|
||||
impl PartialOrd for $T {
|
||||
fn partial_min(self, other: $T) -> $T { self.min(other) }
|
||||
fn partial_max(self, other: $T) -> $T { self.max(other) }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
partial_ord_float!(f32)
|
||||
partial_ord_float!(f64)
|
||||
|
||||
/// Base numeric types with partial ordering
|
||||
pub trait BaseNum: Primitive + PartialOrd + fmt::Show {}
|
||||
|
||||
impl BaseNum for i8 {}
|
||||
impl BaseNum for i16 {}
|
||||
impl BaseNum for i32 {}
|
||||
impl BaseNum for i64 {}
|
||||
impl BaseNum for int {}
|
||||
impl BaseNum for u8 {}
|
||||
impl BaseNum for u16 {}
|
||||
impl BaseNum for u32 {}
|
||||
impl BaseNum for u64 {}
|
||||
impl BaseNum for uint {}
|
||||
impl BaseNum for f32 {}
|
||||
impl BaseNum for f64 {}
|
||||
|
||||
/// Base integer types
|
||||
pub trait BaseInt : BaseNum + Int {}
|
||||
|
||||
impl BaseInt for i8 {}
|
||||
impl BaseInt for i16 {}
|
||||
impl BaseInt for i32 {}
|
||||
impl BaseInt for i64 {}
|
||||
impl BaseInt for int {}
|
||||
impl BaseInt for u8 {}
|
||||
impl BaseInt for u16 {}
|
||||
impl BaseInt for u32 {}
|
||||
impl BaseInt for u64 {}
|
||||
impl BaseInt for uint {}
|
||||
|
||||
/// Base floating point types
|
||||
pub trait BaseFloat : BaseNum + FloatMath + ApproxEq<Self> + fmt::Float {}
|
||||
|
||||
impl BaseFloat for f32 {}
|
||||
impl BaseFloat for f64 {}
|
|
@ -1,55 +0,0 @@
|
|||
// 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;
|
||||
|
||||
/// A trait providing a [partial order][po] over a primitive type.
|
||||
///
|
||||
/// [po]: http://mathworld.wolfram.com/PartialOrder.html
|
||||
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> : FloatMath + ApproxEq<S> + PartOrdPrim {}
|
||||
impl PartOrdFloat<f32> for f32 {}
|
||||
impl PartOrdFloat<f64> for f64 {}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -19,11 +19,11 @@ use std::num::Zero;
|
|||
|
||||
use approx::ApproxEq;
|
||||
use intersect::Intersect;
|
||||
use num::BaseFloat;
|
||||
use point::{Point, Point3};
|
||||
use ray::Ray3;
|
||||
use vector::{Vector3, Vector4};
|
||||
use vector::{Vector, EuclideanVector};
|
||||
use partial_ord::PartOrdFloat;
|
||||
|
||||
|
||||
/// A 3-dimensional plane formed from the equation: `A*x + B*y + C*z - D = 0`.
|
||||
|
@ -47,8 +47,7 @@ pub struct Plane<S> {
|
|||
pub d: S,
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Plane<S> {
|
||||
impl<S: BaseFloat> Plane<S> {
|
||||
/// Construct a plane from a normal vector and a scalar distance. The
|
||||
/// plane will be perpendicular to `n`, and `d` units offset from the
|
||||
/// origin.
|
||||
|
@ -91,7 +90,7 @@ Plane<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>> Intersect<Option<Point3<S>>> for (Plane<S>, Ray3<S>) {
|
||||
impl<S: BaseFloat> Intersect<Option<Point3<S>>> for (Plane<S>, Ray3<S>) {
|
||||
fn intersection(&self) -> Option<Point3<S>> {
|
||||
match *self {
|
||||
(ref p, ref r) => {
|
||||
|
@ -103,19 +102,19 @@ impl<S: PartOrdFloat<S>> Intersect<Option<Point3<S>>> for (Plane<S>, Ray3<S>) {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float> Intersect<Option<Ray3<S>>> for (Plane<S>, Plane<S>) {
|
||||
impl<S: BaseFloat> Intersect<Option<Ray3<S>>> for (Plane<S>, Plane<S>) {
|
||||
fn intersection(&self) -> Option<Ray3<S>> {
|
||||
fail!("Not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Float> Intersect<Option<Point3<S>>> for (Plane<S>, Plane<S>, Plane<S>) {
|
||||
impl<S: BaseFloat> Intersect<Option<Point3<S>>> for (Plane<S>, Plane<S>, Plane<S>) {
|
||||
fn intersection(&self) -> Option<Point3<S>> {
|
||||
fail!("Not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
impl<S: BaseFloat + ApproxEq<S>>
|
||||
ApproxEq<S> for Plane<S> {
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Plane<S>, epsilon: &S) -> bool {
|
||||
|
@ -124,7 +123,7 @@ ApproxEq<S> for Plane<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Clone + fmt::Float> fmt::Show for Plane<S> {
|
||||
impl<S: BaseFloat> fmt::Show for Plane<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:f}x + {:f}y + {:f}z - {:f} = 0",
|
||||
self.n.x, self.n.y, self.n.z, self.d)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -21,8 +21,8 @@ use std::fmt;
|
|||
use std::num::{one, zero};
|
||||
|
||||
use array::*;
|
||||
use num::BaseNum;
|
||||
use vector::*;
|
||||
use partial_ord::PartOrdPrim;
|
||||
|
||||
/// A point in 2-dimensional space.
|
||||
#[deriving(Eq, Clone, Hash)]
|
||||
|
@ -33,21 +33,21 @@ pub struct Point2<S> { pub x: S, pub y: S }
|
|||
pub struct Point3<S> { pub x: S, pub y: S, pub z: S }
|
||||
|
||||
|
||||
impl<S: Num> Point2<S> {
|
||||
impl<S: BaseNum> Point2<S> {
|
||||
#[inline]
|
||||
pub fn new(x: S, y: S) -> Point2<S> {
|
||||
Point2 { x: x, y: y }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Num> Point3<S> {
|
||||
impl<S: BaseNum> Point3<S> {
|
||||
#[inline]
|
||||
pub fn new(x: S, y: S, z: S) -> Point3<S> {
|
||||
Point3 { x: x, y: y, z: z }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Point3<S> {
|
||||
impl<S: BaseNum> Point3<S> {
|
||||
#[inline]
|
||||
pub fn from_homogeneous(v: &Vector4<S>) -> Point3<S> {
|
||||
let e = v.truncate().mul_s(one::<S>() / v.w);
|
||||
|
@ -63,7 +63,7 @@ impl<S: PartOrdPrim> Point3<S> {
|
|||
/// Specifies the numeric operations for point types.
|
||||
pub trait Point
|
||||
<
|
||||
S: PartOrdPrim,
|
||||
S: BaseNum,
|
||||
V: Vector<S, Slice>,
|
||||
Slice
|
||||
>
|
||||
|
@ -109,16 +109,16 @@ pub trait Point
|
|||
array!(impl<S> Point2<S> -> [S, ..2] _2)
|
||||
array!(impl<S> Point3<S> -> [S, ..3] _3)
|
||||
|
||||
impl<S: PartOrdPrim> Point<S, Vector2<S>, [S, ..2]> for Point2<S> {}
|
||||
impl<S: PartOrdPrim> Point<S, Vector3<S>, [S, ..3]> for Point3<S> {}
|
||||
impl<S: BaseNum> Point<S, Vector2<S>, [S, ..2]> for Point2<S> {}
|
||||
impl<S: BaseNum> Point<S, Vector3<S>, [S, ..3]> for Point3<S> {}
|
||||
|
||||
impl<S: fmt::Show> fmt::Show for Point2<S> {
|
||||
impl<S: BaseNum> fmt::Show for Point2<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[{}, {}]", self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: fmt::Show> fmt::Show for Point3<S> {
|
||||
impl<S: BaseNum> fmt::Show for Point3<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[{}, {}, {}]", self.x, self.y, self.z)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -18,14 +18,14 @@ use std::num::{zero, one, cast};
|
|||
use angle::{Angle, tan, cot};
|
||||
use frustum::Frustum;
|
||||
use matrix::{Matrix4, ToMatrix4};
|
||||
use num::BaseFloat;
|
||||
use plane::Plane;
|
||||
use partial_ord::PartOrdFloat;
|
||||
|
||||
/// Create a perspective projection matrix.
|
||||
///
|
||||
/// This is the equivalent to the [gluPerspective]
|
||||
/// (http://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml) function.
|
||||
pub fn perspective<S: FloatMath, A: Angle<S>>(fovy: A, aspect: S, near: S, far: S) -> Matrix4<S> {
|
||||
pub fn perspective<S: BaseFloat, A: Angle<S>>(fovy: A, aspect: S, near: S, far: S) -> Matrix4<S> {
|
||||
PerspectiveFov {
|
||||
fovy: fovy,
|
||||
aspect: aspect,
|
||||
|
@ -38,7 +38,7 @@ pub fn perspective<S: FloatMath, A: Angle<S>>(fovy: A, aspect: S, near: S, far:
|
|||
///
|
||||
/// This is the equivalent of the now deprecated [glFrustrum]
|
||||
/// (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml) function.
|
||||
pub fn frustum<S: Float>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
|
||||
pub fn frustum<S: BaseFloat>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
|
||||
Perspective {
|
||||
left: left,
|
||||
right: right,
|
||||
|
@ -53,7 +53,7 @@ pub fn frustum<S: Float>(left: S, right: S, bottom: S, top: S, near: S, far: S)
|
|||
///
|
||||
/// This is the equivalent of the now deprecated [glOrtho]
|
||||
/// (http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml) function.
|
||||
pub fn ortho<S: Float>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
|
||||
pub fn ortho<S: BaseFloat>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
|
||||
Ortho {
|
||||
left: left,
|
||||
right: right,
|
||||
|
@ -77,7 +77,7 @@ pub struct PerspectiveFov<S, A> {
|
|||
pub far: S,
|
||||
}
|
||||
|
||||
impl<S: FloatMath, A: Angle<S>> PerspectiveFov<S, A> {
|
||||
impl<S: BaseFloat, A: Angle<S>> PerspectiveFov<S, A> {
|
||||
pub fn to_perspective(&self) -> Perspective<S> {
|
||||
let angle = self.fovy.div_s(cast(2).unwrap());
|
||||
let ymax = self.near * tan(angle.to_rad());
|
||||
|
@ -94,15 +94,14 @@ impl<S: FloatMath, A: Angle<S>> PerspectiveFov<S, A> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>, A: Angle<S>>
|
||||
Projection<S> for PerspectiveFov<S, A> {
|
||||
impl<S: BaseFloat, A: Angle<S>> Projection<S> for PerspectiveFov<S, A> {
|
||||
fn to_frustum(&self) -> Frustum<S> {
|
||||
// TODO: Could this be faster?
|
||||
Frustum::from_matrix4(self.to_matrix4())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: FloatMath, A: Angle<S>> ToMatrix4<S> for PerspectiveFov<S, A> {
|
||||
impl<S: BaseFloat, A: Angle<S>> ToMatrix4<S> for PerspectiveFov<S, A> {
|
||||
fn to_matrix4(&self) -> Matrix4<S> {
|
||||
let half_turn: A = Angle::turn_div_2();
|
||||
|
||||
|
@ -151,15 +150,14 @@ pub struct Perspective<S> {
|
|||
pub near: S, far: S,
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Projection<S> for Perspective<S> {
|
||||
impl<S: BaseFloat> Projection<S> for Perspective<S> {
|
||||
fn to_frustum(&self) -> Frustum<S> {
|
||||
// TODO: Could this be faster?
|
||||
Frustum::from_matrix4(self.to_matrix4())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Float> ToMatrix4<S> for Perspective<S> {
|
||||
impl<S: BaseFloat> ToMatrix4<S> for Perspective<S> {
|
||||
fn to_matrix4(&self) -> Matrix4<S> {
|
||||
assert!(self.left > self.right, "`left` cannot be greater than `right`, found: left: {:?} right: {:?}", self.left, self.right);
|
||||
assert!(self.bottom > self.top, "`bottom` cannot be greater than `top`, found: bottom: {:?} top: {:?}", self.bottom, self.top);
|
||||
|
@ -202,8 +200,7 @@ pub struct Ortho<S> {
|
|||
pub near: S, far: S,
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Projection<S> for Ortho<S> {
|
||||
impl<S: BaseFloat> Projection<S> for Ortho<S> {
|
||||
fn to_frustum(&self) -> Frustum<S> {
|
||||
Frustum {
|
||||
left: Plane::from_abcd( one::<S>(), zero::<S>(), zero::<S>(), self.left.clone()),
|
||||
|
@ -216,7 +213,7 @@ Projection<S> for Ortho<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float> ToMatrix4<S> for Ortho<S> {
|
||||
impl<S: BaseFloat> ToMatrix4<S> for Ortho<S> {
|
||||
fn to_matrix4(&self) -> Matrix4<S> {
|
||||
assert!(self.left < self.right, "`left` cannot be greater than `right`, found: left: {:?} right: {:?}", self.left, self.right);
|
||||
assert!(self.bottom < self.top, "`bottom` cannot be greater than `top`, found: bottom: {:?} top: {:?}", self.bottom, self.top);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -17,13 +17,12 @@ use std::fmt;
|
|||
use std::num::{zero, one, cast};
|
||||
|
||||
use angle::{Angle, Rad, acos, sin, sin_cos};
|
||||
use approx::ApproxEq;
|
||||
use array::{Array, build};
|
||||
use matrix::{Matrix3, ToMatrix3, ToMatrix4, Matrix4};
|
||||
use num::BaseFloat;
|
||||
use point::{Point3};
|
||||
use rotation::{Rotation, Rotation3, Basis3, ToBasis3};
|
||||
use vector::{Vector3, Vector, EuclideanVector};
|
||||
use partial_ord::PartOrdFloat;
|
||||
|
||||
/// A [quaternion](https://en.wikipedia.org/wiki/Quaternion) in scalar/vector
|
||||
/// form.
|
||||
|
@ -33,13 +32,12 @@ pub struct Quaternion<S> { pub s: S, pub v: Vector3<S> }
|
|||
array!(impl<S> Quaternion<S> -> [S, ..4] _4)
|
||||
|
||||
/// Represents types which can be expressed as a quaternion.
|
||||
pub trait ToQuaternion<S: Float> {
|
||||
pub trait ToQuaternion<S: BaseFloat> {
|
||||
/// Convert this value to a quaternion.
|
||||
fn to_quaternion(&self) -> Quaternion<S>;
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Quaternion<S> {
|
||||
impl<S: BaseFloat> Quaternion<S> {
|
||||
/// Construct a new quaternion from one scalar component and three
|
||||
/// imaginary components
|
||||
#[inline]
|
||||
|
@ -178,8 +176,7 @@ Quaternion<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Quaternion<S> {
|
||||
impl<S: BaseFloat> Quaternion<S> {
|
||||
/// Spherical Linear Intoperlation
|
||||
///
|
||||
/// Return the spherical linear interpolation between the quaternion and
|
||||
|
@ -228,8 +225,7 @@ Quaternion<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
ToMatrix3<S> for Quaternion<S> {
|
||||
impl<S: BaseFloat> ToMatrix3<S> for Quaternion<S> {
|
||||
/// Convert the quaternion to a 3 x 3 rotation matrix
|
||||
fn to_matrix3(&self) -> Matrix3<S> {
|
||||
let x2 = self.v.x + self.v.x;
|
||||
|
@ -254,8 +250,7 @@ ToMatrix3<S> for Quaternion<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
ToMatrix4<S> for Quaternion<S> {
|
||||
impl<S: BaseFloat> ToMatrix4<S> for Quaternion<S> {
|
||||
/// Convert the quaternion to a 4 x 4 rotation matrix
|
||||
fn to_matrix4(&self) -> Matrix4<S> {
|
||||
let x2 = self.v.x + self.v.x;
|
||||
|
@ -281,15 +276,14 @@ ToMatrix4<S> for Quaternion<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Neg<Quaternion<S>> for Quaternion<S> {
|
||||
impl<S: BaseFloat> Neg<Quaternion<S>> for Quaternion<S> {
|
||||
#[inline]
|
||||
fn neg(&self) -> Quaternion<S> {
|
||||
Quaternion::from_sv(-self.s, -self.v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: fmt::Show> fmt::Show for Quaternion<S> {
|
||||
impl<S: BaseFloat> fmt::Show for Quaternion<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} + {}i + {}j + {}k",
|
||||
self.s,
|
||||
|
@ -301,19 +295,17 @@ impl<S: fmt::Show> fmt::Show for Quaternion<S> {
|
|||
|
||||
// Quaternion Rotation impls
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
ToBasis3<S> for Quaternion<S> {
|
||||
impl<S: BaseFloat> ToBasis3<S> for Quaternion<S> {
|
||||
#[inline]
|
||||
fn to_rot3(&self) -> Basis3<S> { Basis3::from_quaternion(self) }
|
||||
}
|
||||
|
||||
impl<S: Float> ToQuaternion<S> for Quaternion<S> {
|
||||
impl<S: BaseFloat> ToQuaternion<S> for Quaternion<S> {
|
||||
#[inline]
|
||||
fn to_quaternion(&self) -> Quaternion<S> { self.clone() }
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Quaternion<S> {
|
||||
impl<S: BaseFloat> Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Quaternion<S> {
|
||||
#[inline]
|
||||
fn identity() -> Quaternion<S> { Quaternion::identity() }
|
||||
|
||||
|
@ -345,9 +337,7 @@ Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Quaternion<S> {
|
|||
fn invert_self(&mut self) { *self = self.invert() }
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation3<S> for Quaternion<S>
|
||||
{
|
||||
impl<S: BaseFloat> Rotation3<S> for Quaternion<S> {
|
||||
#[inline]
|
||||
fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Quaternion<S> {
|
||||
let (s, c) = sin_cos(angle.mul_s(cast(0.5).unwrap()));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
|
||||
// refer to the AUTHORS file at the top-level directionectory of this distribution.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -13,30 +13,23 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use num::BaseNum;
|
||||
use point::{Point, Point2, Point3};
|
||||
use vector::{Vector, Vector2, Vector3};
|
||||
|
||||
/// A generic ray starting at `origin` and extending infinitely in
|
||||
/// `direction`.
|
||||
#[deriving(Clone, Eq)]
|
||||
pub struct Ray<P,V>
|
||||
{
|
||||
pub struct Ray<P,V> {
|
||||
pub origin: P,
|
||||
pub direction: V,
|
||||
}
|
||||
|
||||
impl
|
||||
<
|
||||
S: Primitive,
|
||||
Slice,
|
||||
V: Vector<S,Slice>,
|
||||
P: Point<S,V,Slice>
|
||||
> Ray<P,V>
|
||||
{
|
||||
impl<S: BaseNum, Slice, V: Vector<S, Slice>, P: Point<S, V, Slice>> Ray<P, V> {
|
||||
pub fn new(origin: P, direction: V) -> Ray<P,V> {
|
||||
Ray { origin:origin, direction:direction }
|
||||
Ray { origin: origin, direction: direction }
|
||||
}
|
||||
}
|
||||
|
||||
pub type Ray2<S> = Ray<Point2<S>,Vector2<S>>;
|
||||
pub type Ray3<S> = Ray<Point3<S>,Vector3<S>>;
|
||||
pub type Ray2<S> = Ray<Point2<S>, Vector2<S>>;
|
||||
pub type Ray3<S> = Ray<Point3<S>, Vector3<S>>;
|
||||
|
|
|
@ -19,17 +19,17 @@ use array::Array;
|
|||
use matrix::Matrix;
|
||||
use matrix::{Matrix2, ToMatrix2};
|
||||
use matrix::{Matrix3, ToMatrix3};
|
||||
use num::{BaseNum, BaseFloat};
|
||||
use point::{Point, Point2, Point3};
|
||||
use quaternion::{Quaternion, ToQuaternion};
|
||||
use ray::Ray;
|
||||
use vector::{Vector, Vector2, Vector3};
|
||||
use partial_ord::{PartOrdPrim, PartOrdFloat};
|
||||
|
||||
/// A trait for a generic rotation. A rotation is a transformation that
|
||||
/// creates a circular motion, and preserves at least one point in the space.
|
||||
pub trait Rotation
|
||||
<
|
||||
S: PartOrdPrim,
|
||||
S: BaseNum,
|
||||
Slice,
|
||||
V: Vector<S,Slice>,
|
||||
P: Point<S,V,Slice>
|
||||
|
@ -102,7 +102,7 @@ pub trait Rotation2
|
|||
/// A three-dimensional rotation.
|
||||
pub trait Rotation3
|
||||
<
|
||||
S: Primitive
|
||||
S: BaseNum
|
||||
>
|
||||
: Rotation<S, [S, ..3], Vector3<S>, Point3<S>>
|
||||
+ ToMatrix3<S>
|
||||
|
@ -152,30 +152,29 @@ pub struct Basis2<S> {
|
|||
mat: Matrix2<S>
|
||||
}
|
||||
|
||||
impl<S: Float> Basis2<S> {
|
||||
impl<S: BaseFloat> Basis2<S> {
|
||||
/// Coerce to a `Matrix2`
|
||||
#[inline]
|
||||
pub fn as_matrix2<'a>(&'a self) -> &'a Matrix2<S> { &'a self.mat }
|
||||
}
|
||||
|
||||
/// Represents types which can be converted to a rotation matrix.
|
||||
pub trait ToBasis2<S: Float> {
|
||||
pub trait ToBasis2<S: BaseFloat> {
|
||||
/// Convert this type to a rotation matrix.
|
||||
fn to_rot2(&self) -> Basis2<S>;
|
||||
}
|
||||
|
||||
impl<S: Float> ToBasis2<S> for Basis2<S> {
|
||||
impl<S: BaseFloat> ToBasis2<S> for Basis2<S> {
|
||||
#[inline]
|
||||
fn to_rot2(&self) -> Basis2<S> { self.clone() }
|
||||
}
|
||||
|
||||
impl<S: Float> ToMatrix2<S> for Basis2<S> {
|
||||
impl<S: BaseFloat> ToMatrix2<S> for Basis2<S> {
|
||||
#[inline]
|
||||
fn to_matrix2(&self) -> Matrix2<S> { self.mat.clone() }
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation<S, [S, ..2], Vector2<S>, Point2<S>> for Basis2<S> {
|
||||
impl<S: BaseFloat> Rotation<S, [S, ..2], Vector2<S>, Point2<S>> for Basis2<S> {
|
||||
#[inline]
|
||||
fn identity() -> Basis2<S> { Basis2{ mat: Matrix2::identity() } }
|
||||
|
||||
|
@ -209,16 +208,14 @@ Rotation<S, [S, ..2], Vector2<S>, Point2<S>> for Basis2<S> {
|
|||
fn invert_self(&mut self) { self.mat.invert_self(); }
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
ApproxEq<S> for Basis2<S> {
|
||||
impl<S: BaseFloat> ApproxEq<S> for Basis2<S> {
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Basis2<S>, epsilon: &S) -> bool {
|
||||
self.mat.approx_eq_eps(&other.mat, epsilon)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation2<S> for Basis2<S> {
|
||||
impl<S: BaseFloat> Rotation2<S> for Basis2<S> {
|
||||
fn from_angle(theta: Rad<S>) -> Basis2<S> { Basis2 { mat: Matrix2::from_angle(theta) } }
|
||||
}
|
||||
|
||||
|
@ -233,8 +230,7 @@ pub struct Basis3<S> {
|
|||
mat: Matrix3<S>
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Basis3<S> {
|
||||
impl<S: BaseFloat> Basis3<S> {
|
||||
/// Create a new rotation matrix from a quaternion.
|
||||
#[inline]
|
||||
pub fn from_quaternion(quaternion: &Quaternion<S>) -> Basis3<S> {
|
||||
|
@ -247,29 +243,27 @@ Basis3<S> {
|
|||
}
|
||||
|
||||
/// Represents types which can be converted to a rotation matrix.
|
||||
pub trait ToBasis3<S: Float> {
|
||||
pub trait ToBasis3<S: BaseFloat> {
|
||||
/// Convert this type to a rotation matrix.
|
||||
fn to_rot3(&self) -> Basis3<S>;
|
||||
}
|
||||
|
||||
impl<S: Float> ToBasis3<S> for Basis3<S> {
|
||||
impl<S: BaseFloat> ToBasis3<S> for Basis3<S> {
|
||||
#[inline]
|
||||
fn to_rot3(&self) -> Basis3<S> { self.clone() }
|
||||
}
|
||||
|
||||
impl<S: Float> ToMatrix3<S> for Basis3<S> {
|
||||
impl<S: BaseFloat> ToMatrix3<S> for Basis3<S> {
|
||||
#[inline]
|
||||
fn to_matrix3(&self) -> Matrix3<S> { self.mat.clone() }
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
ToQuaternion<S> for Basis3<S> {
|
||||
impl<S: BaseFloat> ToQuaternion<S> for Basis3<S> {
|
||||
#[inline]
|
||||
fn to_quaternion(&self) -> Quaternion<S> { self.mat.to_quaternion() }
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Basis3<S> {
|
||||
impl<S: BaseFloat> Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Basis3<S> {
|
||||
#[inline]
|
||||
fn identity() -> Basis3<S> { Basis3{ mat: Matrix3::identity() } }
|
||||
|
||||
|
@ -304,16 +298,14 @@ Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Basis3<S> {
|
|||
fn invert_self(&mut self) { self.mat.invert_self(); }
|
||||
}
|
||||
|
||||
impl<S: Float + ApproxEq<S>>
|
||||
ApproxEq<S> for Basis3<S> {
|
||||
impl<S: BaseFloat> ApproxEq<S> for Basis3<S> {
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Basis3<S>, epsilon: &S) -> bool {
|
||||
self.mat.approx_eq_eps(&other.mat, epsilon)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Rotation3<S> for Basis3<S> {
|
||||
impl<S: BaseFloat> Rotation3<S> for Basis3<S> {
|
||||
fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Basis3<S> {
|
||||
Basis3 { mat: Matrix3::from_axis_angle(axis, angle) }
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -16,17 +16,12 @@
|
|||
//! Bounding sphere
|
||||
|
||||
use intersect::Intersect;
|
||||
use num::BaseFloat;
|
||||
use point::{Point, Point3};
|
||||
use ray::Ray3;
|
||||
use vector::Vector;
|
||||
use partial_ord::PartOrdFloat;
|
||||
|
||||
use std::num::NumCast;
|
||||
use std::num;
|
||||
|
||||
fn cast<T: NumCast, U: NumCast>(n: T) -> U {
|
||||
num::cast(n).unwrap()
|
||||
}
|
||||
use std::num::zero;
|
||||
|
||||
#[deriving(Clone, Eq)]
|
||||
pub struct Sphere<S> {
|
||||
|
@ -34,13 +29,13 @@ pub struct Sphere<S> {
|
|||
pub radius: S,
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>> Intersect<Option<Point3<S>>> for (Sphere<S>, Ray3<S>) {
|
||||
impl<S: BaseFloat> Intersect<Option<Point3<S>>> for (Sphere<S>, Ray3<S>) {
|
||||
fn intersection(&self) -> Option<Point3<S>> {
|
||||
match *self {
|
||||
(ref s, ref r) => {
|
||||
let l = s.center.sub_p(&r.origin);
|
||||
let tca = l.dot(&r.direction);
|
||||
if tca < cast(0.0) { return None; }
|
||||
if tca < zero() { return None; }
|
||||
let d2 = l.dot(&l) - tca*tca;
|
||||
if d2 > s.radius*s.radius { return None; }
|
||||
let thc = (s.radius*s.radius - d2).sqrt();
|
||||
|
|
|
@ -19,19 +19,19 @@ use std::num::one;
|
|||
|
||||
use approx::ApproxEq;
|
||||
use matrix::{Matrix, Matrix4, ToMatrix4};
|
||||
use num::{BaseNum, BaseFloat};
|
||||
use point::{Point, Point3};
|
||||
use ray::Ray;
|
||||
use rotation::{Rotation, Rotation3};
|
||||
use quaternion::Quaternion;
|
||||
use vector::{Vector, Vector3};
|
||||
use partial_ord::{PartOrdPrim, PartOrdFloat};
|
||||
|
||||
/// A trait representing an [affine
|
||||
/// transformation](https://en.wikipedia.org/wiki/Affine_transformation) that
|
||||
/// can be applied to points or vectors. An affine transformation is one which
|
||||
pub trait Transform
|
||||
<
|
||||
S: PartOrdPrim,
|
||||
S: BaseNum,
|
||||
Slice,
|
||||
V: Vector<S,Slice>,
|
||||
P: Point<S,V,Slice>
|
||||
|
@ -94,7 +94,7 @@ pub struct Decomposed<S,V,R> {
|
|||
|
||||
impl
|
||||
<
|
||||
S: PartOrdFloat<S>,
|
||||
S: BaseFloat,
|
||||
Slice,
|
||||
V: Vector<S, Slice>,
|
||||
P: Point<S, V, Slice>,
|
||||
|
@ -162,8 +162,7 @@ pub trait Transform3<S>
|
|||
+ ToMatrix4<S>
|
||||
{}
|
||||
|
||||
impl<S: PartOrdFloat<S>, R: Rotation3<S>>
|
||||
ToMatrix4<S> for Decomposed<S, Vector3<S>, R> {
|
||||
impl<S: BaseFloat, R: Rotation3<S>> ToMatrix4<S> for Decomposed<S, Vector3<S>, R> {
|
||||
fn to_matrix4(&self) -> Matrix4<S> {
|
||||
let mut m = self.rot.to_matrix3().mul_s( self.scale.clone() ).to_matrix4();
|
||||
m.w = self.disp.extend( num::one() );
|
||||
|
@ -171,11 +170,9 @@ ToMatrix4<S> for Decomposed<S, Vector3<S>, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>, R: Rotation3<S>>
|
||||
Transform3<S> for Decomposed<S,Vector3<S>,R> {}
|
||||
impl<S: BaseFloat, R: Rotation3<S>> Transform3<S> for Decomposed<S,Vector3<S>,R> {}
|
||||
|
||||
impl<S: fmt::Show + Float, R: fmt::Show + Rotation3<S>>
|
||||
fmt::Show for Decomposed<S,Vector3<S>,R> {
|
||||
impl<S: BaseFloat, R: fmt::Show + Rotation3<S>> fmt::Show for Decomposed<S,Vector3<S>,R> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "(scale({}), rot({}), disp{})",
|
||||
self.scale, self.rot, self.disp)
|
||||
|
@ -188,8 +185,7 @@ pub struct AffineMatrix3<S> {
|
|||
pub mat: Matrix4<S>,
|
||||
}
|
||||
|
||||
impl<S : PartOrdFloat<S>>
|
||||
Transform<S, [S, ..3], Vector3<S>, Point3<S>> for AffineMatrix3<S> {
|
||||
impl<S : BaseFloat> Transform<S, [S, ..3], Vector3<S>, Point3<S>> for AffineMatrix3<S> {
|
||||
#[inline]
|
||||
fn identity() -> AffineMatrix3<S> {
|
||||
AffineMatrix3 { mat: Matrix4::identity() }
|
||||
|
@ -221,20 +217,18 @@ Transform<S, [S, ..3], Vector3<S>, Point3<S>> for AffineMatrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim>
|
||||
ToMatrix4<S> for AffineMatrix3<S> {
|
||||
impl<S: BaseNum> ToMatrix4<S> for AffineMatrix3<S> {
|
||||
#[inline] fn to_matrix4(&self) -> Matrix4<S> { self.mat.clone() }
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
Transform3<S> for AffineMatrix3<S> {}
|
||||
impl<S: BaseFloat> Transform3<S> for AffineMatrix3<S> {}
|
||||
|
||||
|
||||
/// A transformation in three dimensions consisting of a rotation,
|
||||
/// displacement vector and scale amount.
|
||||
pub struct Transform3D<S>( Decomposed<S,Vector3<S>,Quaternion<S>> );
|
||||
|
||||
impl<S: PartOrdFloat<S>> Transform3D<S> {
|
||||
impl<S: BaseFloat> Transform3D<S> {
|
||||
#[inline]
|
||||
pub fn new(scale: S, rot: Quaternion<S>, disp: Vector3<S>) -> Transform3D<S> {
|
||||
Transform3D( Decomposed { scale: scale, rot: rot, disp: disp })
|
||||
|
@ -252,6 +246,6 @@ impl<S: PartOrdFloat<S>> Transform3D<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>> ToMatrix4<S> for Transform3D<S> {
|
||||
impl<S: BaseFloat> ToMatrix4<S> for Transform3D<S> {
|
||||
fn to_matrix4(&self) -> Matrix4<S> { self.get().to_matrix4() }
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||
// Copyright 2013-2014 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");
|
||||
|
@ -19,14 +19,14 @@ use std::num::{Zero, zero, One, one};
|
|||
use angle::{Rad, atan2, acos};
|
||||
use approx::ApproxEq;
|
||||
use array::{Array, build};
|
||||
use partial_ord::{PartOrdPrim, PartOrdFloat};
|
||||
use num::{BaseNum, BaseFloat, PartialOrd};
|
||||
|
||||
/// 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: PartOrdPrim,
|
||||
S: BaseNum,
|
||||
Slice
|
||||
>
|
||||
: Array<S, Slice>
|
||||
|
@ -90,14 +90,14 @@ pub trait Vector
|
|||
#[inline] fn dot(&self, other: &Self) -> S { self.mul_v(other).comp_add() }
|
||||
|
||||
/// The minimum component of the vector.
|
||||
#[inline] fn comp_min(&self) -> S { self.fold(|a, b| if *a < *b { *a } else {*b }) }
|
||||
#[inline] fn comp_min(&self) -> S { self.fold(|a, b| a.partial_min(*b)) }
|
||||
|
||||
/// The maximum component of the vector.
|
||||
#[inline] fn comp_max(&self) -> S { self.fold(|a, b| if *a > *b { *a } else {*b }) }
|
||||
#[inline] fn comp_max(&self) -> S { self.fold(|a, b| a.partial_max(*b)) }
|
||||
}
|
||||
|
||||
/// Dot product of two vectors.
|
||||
#[inline] pub fn dot<S: PartOrdPrim, Slice, V: Vector<S, Slice>>(a: V, b: V) -> S { a.dot(&b) }
|
||||
#[inline] pub fn dot<S: BaseNum, 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(
|
||||
|
@ -105,7 +105,7 @@ macro_rules! vec(
|
|||
#[deriving(Eq, TotalEq, Clone, Hash)]
|
||||
pub struct $Self<S> { $(pub $field: S),+ }
|
||||
|
||||
impl<$S: Primitive> $Self<$S> {
|
||||
impl<$S: BaseNum> $Self<$S> {
|
||||
/// Construct a new vector, using the provided values.
|
||||
#[inline]
|
||||
pub fn new($($field: $S),+) -> $Self<$S> {
|
||||
|
@ -127,32 +127,32 @@ macro_rules! vec(
|
|||
pub fn ident() -> $Self<$S> { $Self::from_value(one()) }
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Add<$Self<S>, $Self<S>> for $Self<S> {
|
||||
impl<S: BaseNum> Add<$Self<S>, $Self<S>> for $Self<S> {
|
||||
#[inline] fn add(&self, other: &$Self<S>) -> $Self<S> { self.add_v(other) }
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Sub<$Self<S>, $Self<S>> for $Self<S> {
|
||||
impl<S: BaseNum> Sub<$Self<S>, $Self<S>> for $Self<S> {
|
||||
#[inline] fn sub(&self, other: &$Self<S>) -> $Self<S> { self.sub_v(other) }
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Zero for $Self<S> {
|
||||
impl<S: BaseNum> Zero for $Self<S> {
|
||||
#[inline] fn zero() -> $Self<S> { $Self::from_value(zero()) }
|
||||
#[inline] fn is_zero(&self) -> bool { *self == zero() }
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Neg<$Self<S>> for $Self<S> {
|
||||
impl<S: BaseNum> Neg<$Self<S>> for $Self<S> {
|
||||
#[inline] fn neg(&self) -> $Self<S> { build(|i| self.i(i).neg()) }
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Mul<$Self<S>, $Self<S>> for $Self<S> {
|
||||
impl<S: BaseNum> Mul<$Self<S>, $Self<S>> for $Self<S> {
|
||||
#[inline] fn mul(&self, other: &$Self<S>) -> $Self<S> { self.mul_v(other) }
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> One for $Self<S> {
|
||||
impl<S: BaseNum> One for $Self<S> {
|
||||
#[inline] fn one() -> $Self<S> { $Self::from_value(one()) }
|
||||
}
|
||||
|
||||
impl<S: PartOrdPrim> Vector<S, [S, ..$n]> for $Self<S> {}
|
||||
impl<S: BaseNum> Vector<S, [S, ..$n]> for $Self<S> {}
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -165,7 +165,7 @@ array!(impl<S> Vector3<S> -> [S, ..3] _3)
|
|||
array!(impl<S> Vector4<S> -> [S, ..4] _4)
|
||||
|
||||
/// Operations specific to numeric two-dimensional vectors.
|
||||
impl<S: Primitive> Vector2<S> {
|
||||
impl<S: BaseNum> Vector2<S> {
|
||||
/// A unit vector in the `x` direction.
|
||||
#[inline] pub fn unit_x() -> Vector2<S> { Vector2::new(one(), zero()) }
|
||||
/// A unit vector in the `y` direction.
|
||||
|
@ -186,7 +186,7 @@ impl<S: Primitive> Vector2<S> {
|
|||
}
|
||||
|
||||
/// Operations specific to numeric three-dimensional vectors.
|
||||
impl<S: Primitive> Vector3<S> {
|
||||
impl<S: BaseNum> Vector3<S> {
|
||||
/// A unit vector in the `x` direction.
|
||||
#[inline] pub fn unit_x() -> Vector3<S> { Vector3::new(one(), zero(), zero()) }
|
||||
/// A unit vector in the `y` direction.
|
||||
|
@ -224,7 +224,7 @@ impl<S: Primitive> Vector3<S> {
|
|||
}
|
||||
|
||||
/// Operations specific to numeric four-dimensional vectors.
|
||||
impl<S: Primitive> Vector4<S> {
|
||||
impl<S: BaseNum> Vector4<S> {
|
||||
/// A unit vector in the `x` direction.
|
||||
#[inline] pub fn unit_x() -> Vector4<S> { Vector4::new(one(), zero(), zero(), zero()) }
|
||||
/// A unit vector in the `y` direction.
|
||||
|
@ -245,7 +245,7 @@ impl<S: Primitive> Vector4<S> {
|
|||
/// 2-dimensional and 3-dimensional vectors.
|
||||
pub trait EuclideanVector
|
||||
<
|
||||
S: PartOrdFloat<S>,
|
||||
S: BaseFloat,
|
||||
Slice
|
||||
>
|
||||
: Vector<S, Slice>
|
||||
|
@ -316,7 +316,7 @@ pub trait EuclideanVector
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
EuclideanVector<S, [S, ..2]> for Vector2<S> {
|
||||
#[inline]
|
||||
fn angle(&self, other: &Vector2<S>) -> Rad<S> {
|
||||
|
@ -324,7 +324,7 @@ EuclideanVector<S, [S, ..2]> for Vector2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
EuclideanVector<S, [S, ..3]> for Vector3<S> {
|
||||
#[inline]
|
||||
fn angle(&self, other: &Vector3<S>) -> Rad<S> {
|
||||
|
@ -332,7 +332,7 @@ EuclideanVector<S, [S, ..3]> for Vector3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartOrdFloat<S>>
|
||||
impl<S: BaseFloat>
|
||||
EuclideanVector<S, [S, ..4]> for Vector4<S> {
|
||||
#[inline]
|
||||
fn angle(&self, other: &Vector4<S>) -> Rad<S> {
|
||||
|
|
Loading…
Reference in a new issue