New ApproxEq replaced the one in std
This commit is contained in:
parent
c8134ee828
commit
2fdf34cd18
14 changed files with 189 additions and 152 deletions
|
@ -10,13 +10,13 @@ The library provides:
|
||||||
- square matrices: `Mat2`, `Mat3`, `Mat4`
|
- square matrices: `Mat2`, `Mat3`, `Mat4`
|
||||||
- a quaternion type: `Quat`
|
- a quaternion type: `Quat`
|
||||||
- rotation matrices: `Rot2`, `Rot3`
|
- rotation matrices: `Rot2`, `Rot3`
|
||||||
- rotations: `Euler`, `AxisAngle`
|
|
||||||
- angle units: `Rad`, `Deg`
|
- angle units: `Rad`, `Deg`
|
||||||
- points: `Point2`, `Point3`
|
- points: `Point2`, `Point3`
|
||||||
- rays: `Ray2`, `Ray3`
|
- rays: `Ray2`, `Ray3`
|
||||||
- plane: `Plane`
|
- a plane: `Plane`
|
||||||
- perspective projections: `Perspective`, `PerspectiveFov`, `Ortho`
|
- perspective projections: `Perspective`, `PerspectiveFov`, `Ortho`
|
||||||
- a view frustum: `Frustrum`
|
- a view frustum: `Frustrum`
|
||||||
|
- spatial transformations: `AffineMatrix3`, `Transform3D`
|
||||||
- axis-aligned bounding boxes: `Aabb2`, `Aabb3`
|
- axis-aligned bounding boxes: `Aabb2`, `Aabb3`
|
||||||
- oriented bounding boxes: `Obb2`, `Obb3`
|
- oriented bounding boxes: `Obb2`, `Obb3`
|
||||||
- collision primitives: `Sphere`, `Cylinder`
|
- collision primitives: `Sphere`, `Cylinder`
|
||||||
|
|
|
@ -21,6 +21,8 @@ pub use std::num::{asinh, acosh, atanh};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::num::{Zero, zero, cast};
|
use std::num::{Zero, zero, cast};
|
||||||
|
|
||||||
|
use approx::ApproxEq;
|
||||||
|
|
||||||
#[deriving(Clone, Eq, Ord, Zero)] pub struct Rad<S> { s: S }
|
#[deriving(Clone, Eq, Ord, Zero)] pub struct Rad<S> { s: S }
|
||||||
#[deriving(Clone, Eq, Ord, Zero)] pub struct Deg<S> { s: S }
|
#[deriving(Clone, Eq, Ord, Zero)] pub struct Deg<S> { s: S }
|
||||||
|
|
||||||
|
@ -126,7 +128,8 @@ pub trait Angle
|
||||||
|
|
||||||
#[inline] pub fn bisect<S: Float, A: Angle<S>>(a: A, b: A) -> A { a.bisect(b) }
|
#[inline] pub fn bisect<S: Float, A: Angle<S>>(a: A, b: A) -> A { a.bisect(b) }
|
||||||
|
|
||||||
impl<S: Float> Rad<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Rad<S> {
|
||||||
#[inline] pub fn zero() -> Rad<S> { zero() }
|
#[inline] pub fn zero() -> Rad<S> { zero() }
|
||||||
#[inline] pub fn full_turn() -> Rad<S> { Angle::full_turn() }
|
#[inline] pub fn full_turn() -> Rad<S> { Angle::full_turn() }
|
||||||
#[inline] pub fn turn_div_2() -> Rad<S> { Angle::turn_div_2() }
|
#[inline] pub fn turn_div_2() -> Rad<S> { Angle::turn_div_2() }
|
||||||
|
@ -135,7 +138,8 @@ impl<S: Float> Rad<S> {
|
||||||
#[inline] pub fn turn_div_6() -> Rad<S> { Angle::turn_div_6() }
|
#[inline] pub fn turn_div_6() -> Rad<S> { Angle::turn_div_6() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Deg<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Deg<S> {
|
||||||
#[inline] pub fn zero() -> Deg<S> { zero() }
|
#[inline] pub fn zero() -> Deg<S> { zero() }
|
||||||
#[inline] pub fn full_turn() -> Deg<S> { Angle::full_turn() }
|
#[inline] pub fn full_turn() -> Deg<S> { Angle::full_turn() }
|
||||||
#[inline] pub fn turn_div_2() -> Deg<S> { Angle::turn_div_2() }
|
#[inline] pub fn turn_div_2() -> Deg<S> { Angle::turn_div_2() }
|
||||||
|
@ -144,24 +148,28 @@ impl<S: Float> Deg<S> {
|
||||||
#[inline] pub fn turn_div_6() -> Deg<S> { Angle::turn_div_6() }
|
#[inline] pub fn turn_div_6() -> Deg<S> { Angle::turn_div_6() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Equiv<Rad<S>> for Rad<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Equiv<Rad<S>> for Rad<S> {
|
||||||
fn equiv(&self, other: &Rad<S>) -> bool {
|
fn equiv(&self, other: &Rad<S>) -> bool {
|
||||||
self.normalize() == other.normalize()
|
self.normalize() == other.normalize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Equiv<Deg<S>> for Deg<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Equiv<Deg<S>> for Deg<S> {
|
||||||
fn equiv(&self, other: &Deg<S>) -> bool {
|
fn equiv(&self, other: &Deg<S>) -> bool {
|
||||||
self.normalize() == other.normalize()
|
self.normalize() == other.normalize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Angle<S> for Rad<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Angle<S> for Rad<S> {
|
||||||
#[inline] fn from<A: Angle<S>>(theta: A) -> Rad<S> { theta.to_rad() }
|
#[inline] fn from<A: Angle<S>>(theta: A) -> Rad<S> { theta.to_rad() }
|
||||||
#[inline] fn full_turn() -> Rad<S> { rad(Real::two_pi()) }
|
#[inline] fn full_turn() -> Rad<S> { rad(Real::two_pi()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Angle<S> for Deg<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Angle<S> for Deg<S> {
|
||||||
#[inline] fn from<A: Angle<S>>(theta: A) -> Deg<S> { theta.to_deg() }
|
#[inline] fn from<A: Angle<S>>(theta: A) -> Deg<S> { theta.to_deg() }
|
||||||
#[inline] fn full_turn() -> Deg<S> { deg(cast(360).unwrap()) }
|
#[inline] fn full_turn() -> Deg<S> { deg(cast(360).unwrap()) }
|
||||||
}
|
}
|
||||||
|
@ -183,38 +191,18 @@ impl<S: Float> Angle<S> for Deg<S> {
|
||||||
impl<S: Float + fmt::Default> ToStr for Rad<S> { fn to_str(&self) -> ~str { format!("{} rad", self.s) } }
|
impl<S: Float + fmt::Default> ToStr for Rad<S> { fn to_str(&self) -> ~str { format!("{} rad", self.s) } }
|
||||||
impl<S: Float + fmt::Default> ToStr for Deg<S> { fn to_str(&self) -> ~str { format!("{}°", self.s) } }
|
impl<S: Float + fmt::Default> ToStr for Deg<S> { fn to_str(&self) -> ~str { format!("{}°", self.s) } }
|
||||||
|
|
||||||
impl<S: Float> ApproxEq<S> for Rad<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ApproxEq<S> for Rad<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> S {
|
fn approx_eq_eps(&self, other: &Rad<S>, epsilon: &S) -> bool {
|
||||||
// TODO: fix this after static methods are fixed in rustc
|
self.s.approx_eq_eps(&other.s, epsilon)
|
||||||
fail!(~"Doesn't work!");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, other: &Rad<S>) -> bool {
|
|
||||||
self.s.approx_eq(&other.s)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_eps(&self, other: &Rad<S>, approx_epsilon: &S) -> bool {
|
|
||||||
self.s.approx_eq_eps(&other.s, approx_epsilon)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> ApproxEq<S> for Deg<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ApproxEq<S> for Deg<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> S {
|
fn approx_eq_eps(&self, other: &Deg<S>, epsilon: &S) -> bool {
|
||||||
// TODO: fix this after static methods are fixed in rustc
|
self.s.approx_eq_eps(&other.s, epsilon)
|
||||||
fail!(~"Doesn't work!");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, other: &Deg<S>) -> bool {
|
|
||||||
self.s.approx_eq(&other.s)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_eps(&self, other: &Deg<S>, approx_epsilon: &S) -> bool {
|
|
||||||
self.s.approx_eq_eps(&other.s, approx_epsilon)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
77
src/cgmath/approx.rs
Normal file
77
src/cgmath/approx.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::num;
|
||||||
|
|
||||||
|
use array::Array;
|
||||||
|
use matrix::{Mat2, Mat3, Mat4};
|
||||||
|
use point::{Point2, Point3};
|
||||||
|
use quaternion::Quat;
|
||||||
|
use vector::{Vec2, Vec3, Vec4};
|
||||||
|
|
||||||
|
pub trait ApproxEq<T: Float> {
|
||||||
|
fn approx_epsilon(_hack: Option<Self>) -> T {
|
||||||
|
num::cast(1.0e-5).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn approx_eq(&self, other: &Self) -> bool {
|
||||||
|
let eps: T = ApproxEq::approx_epsilon(None::<Self>);
|
||||||
|
self.approx_eq_eps(other, &eps)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn approx_eq_eps(&self, other: &Self, epsilon: &T) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! approx_simple(
|
||||||
|
($S:ident) => (
|
||||||
|
impl ApproxEq<$S> for $S {
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq_eps(&self, other: &$S, epsilon: &$S) -> bool {
|
||||||
|
num::abs(*self - *other) < *epsilon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
approx_simple!(f32)
|
||||||
|
approx_simple!(f64)
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! approx_array(
|
||||||
|
(impl<$S:ident> $Self:ty) => (
|
||||||
|
impl<$S: Float + Clone + ApproxEq<$S>> ApproxEq<$S> for $Self {
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq_eps(&self, other: &$Self, epsilon: &$S) -> bool {
|
||||||
|
self.iter().zip(other.iter())
|
||||||
|
.all(|(a, b)| a.approx_eq_eps(b, epsilon))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
approx_array!(impl<S> Mat2<S>)
|
||||||
|
approx_array!(impl<S> Mat3<S>)
|
||||||
|
approx_array!(impl<S> Mat4<S>)
|
||||||
|
|
||||||
|
approx_array!(impl<S> Quat<S>)
|
||||||
|
|
||||||
|
approx_array!(impl<S> Vec2<S>)
|
||||||
|
approx_array!(impl<S> Vec3<S>)
|
||||||
|
approx_array!(impl<S> Vec4<S>)
|
||||||
|
|
||||||
|
approx_array!(impl<S> Point2<S>)
|
||||||
|
approx_array!(impl<S> Point3<S>)
|
||||||
|
|
|
@ -123,26 +123,3 @@ macro_rules! gen_each_mut(
|
||||||
(_4) => ({ f(0, self.mut_i(0)); f(1, self.mut_i(1)); f(2, self.mut_i(2)); f(3, self.mut_i(3)); });
|
(_4) => ({ f(0, self.mut_i(0)); f(1, self.mut_i(1)); f(2, self.mut_i(2)); f(3, self.mut_i(3)); });
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! approx_eq(
|
|
||||||
(impl<$S:ident> $Self:ty) => (
|
|
||||||
impl<$S: Clone + ApproxEq<$S>> ApproxEq<$S> for $Self {
|
|
||||||
#[inline]
|
|
||||||
fn approx_epsilon() -> $S {
|
|
||||||
// TODO: fix this after static methods are fixed in rustc
|
|
||||||
fail!(~"Doesn't work!");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, other: &$Self) -> bool {
|
|
||||||
self.iter().zip(other.iter())
|
|
||||||
.all(|(a, b)| a.approx_eq(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_eps(&self, other: &$Self, approx_epsilon: &$S) -> bool {
|
|
||||||
self.iter().zip(other.iter())
|
|
||||||
.all(|(a, b)| a.approx_eq_eps(b, approx_epsilon))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
//! View frustum for visibility determination
|
//! View frustum for visibility determination
|
||||||
|
|
||||||
|
use approx::ApproxEq;
|
||||||
use matrix::{Matrix, Mat4};
|
use matrix::{Matrix, Mat4};
|
||||||
use plane::Plane;
|
use plane::Plane;
|
||||||
use point::Point3;
|
use point::Point3;
|
||||||
|
@ -30,7 +31,8 @@ pub struct Frustum<S> {
|
||||||
far: Plane<S>,
|
far: Plane<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Frustum<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Frustum<S> {
|
||||||
/// Constructs a frustum
|
/// Constructs a frustum
|
||||||
pub fn new(left: Plane<S>, right: Plane<S>,
|
pub fn new(left: Plane<S>, right: Plane<S>,
|
||||||
bottom: Plane<S>, top: Plane<S>,
|
bottom: Plane<S>, top: Plane<S>,
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#[pkgid="cgmath#0.1"];
|
#[crate_id="cgmath#0.1"];
|
||||||
|
#[crate_type = "lib"];
|
||||||
#[comment = "A mathematics library for computer graphics."];
|
#[comment = "A mathematics library for computer graphics."];
|
||||||
#[license = "ASL2"];
|
#[license = "ASL2"];
|
||||||
#[crate_type = "lib"];
|
|
||||||
|
|
||||||
#[feature(globs)];
|
#[feature(globs)];
|
||||||
#[feature(macro_rules)];
|
#[feature(macro_rules)];
|
||||||
|
@ -42,4 +42,5 @@ pub mod intersect;
|
||||||
pub mod obb;
|
pub mod obb;
|
||||||
pub mod sphere;
|
pub mod sphere;
|
||||||
|
|
||||||
|
pub mod approx;
|
||||||
pub mod ptr;
|
pub mod ptr;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
use std::num::{Zero, zero, One, one, cast, sqrt};
|
use std::num::{Zero, zero, One, one, cast, sqrt};
|
||||||
|
|
||||||
use angle::{Rad, sin, cos, sin_cos};
|
use angle::{Rad, sin, cos, sin_cos};
|
||||||
|
use approx::ApproxEq;
|
||||||
use array::{Array, build};
|
use array::{Array, build};
|
||||||
use point::{Point, Point3};
|
use point::{Point, Point3};
|
||||||
use quaternion::{Quat, ToQuat};
|
use quaternion::{Quat, ToQuat};
|
||||||
|
@ -36,9 +37,6 @@ pub struct Mat3<S> { x: Vec3<S>, y: Vec3<S>, z: Vec3<S> }
|
||||||
#[deriving(Clone, Eq, Zero)]
|
#[deriving(Clone, Eq, Zero)]
|
||||||
pub struct Mat4<S> { x: Vec4<S>, y: Vec4<S>, z: Vec4<S>, w: Vec4<S> }
|
pub struct Mat4<S> { x: Vec4<S>, y: Vec4<S>, z: Vec4<S>, w: Vec4<S> }
|
||||||
|
|
||||||
approx_eq!(impl<S> Mat2<S>)
|
|
||||||
approx_eq!(impl<S> Mat3<S>)
|
|
||||||
approx_eq!(impl<S> Mat4<S>)
|
|
||||||
|
|
||||||
impl<S: Primitive> Mat2<S> {
|
impl<S: Primitive> Mat2<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -114,7 +112,8 @@ impl<S: Primitive> Mat3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Mat3<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Mat3<S> {
|
||||||
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Mat3<S> {
|
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Mat3<S> {
|
||||||
let dir = dir.normalize();
|
let dir = dir.normalize();
|
||||||
let side = dir.cross(&up.normalize());
|
let side = dir.cross(&up.normalize());
|
||||||
|
@ -223,7 +222,8 @@ impl<S: Primitive> Mat4<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Mat4<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Mat4<S> {
|
||||||
pub fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vec3<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();
|
let f = center.sub_p(eye).normalize();
|
||||||
let s = f.cross(up).normalize();
|
let s = f.cross(up).normalize();
|
||||||
|
@ -246,7 +246,7 @@ array!(impl<S> Mat4<S> -> [Vec4<S>, ..4] _4)
|
||||||
|
|
||||||
pub trait Matrix
|
pub trait Matrix
|
||||||
<
|
<
|
||||||
S: Float, Slice,
|
S: Float + ApproxEq<S>, Slice,
|
||||||
V: Clone + Vector<S, VSlice> + Array<S, VSlice>, VSlice
|
V: Clone + Vector<S, VSlice> + Array<S, VSlice>, VSlice
|
||||||
>
|
>
|
||||||
: Array<V, Slice>
|
: Array<V, Slice>
|
||||||
|
@ -362,7 +362,7 @@ impl<S: Float> Neg<Mat2<S>> for Mat2<S> { #[inline] fn neg(&self) -> Mat2<S> { b
|
||||||
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<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: Float> Neg<Mat4<S>> for Mat4<S> { #[inline] fn neg(&self) -> Mat4<S> { build(|i| self.i(i).neg()) } }
|
||||||
|
|
||||||
impl<S: Float>
|
impl<S: Float + ApproxEq<S>>
|
||||||
Matrix<S, [Vec2<S>, ..2], Vec2<S>, [S, ..2]>
|
Matrix<S, [Vec2<S>, ..2], Vec2<S>, [S, ..2]>
|
||||||
for Mat2<S>
|
for Mat2<S>
|
||||||
{
|
{
|
||||||
|
@ -411,7 +411,7 @@ for Mat2<S>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float>
|
impl<S: Float + ApproxEq<S>>
|
||||||
Matrix<S, [Vec3<S>, ..3], Vec3<S>, [S, ..3]>
|
Matrix<S, [Vec3<S>, ..3], Vec3<S>, [S, ..3]>
|
||||||
for Mat3<S>
|
for Mat3<S>
|
||||||
{
|
{
|
||||||
|
@ -484,7 +484,7 @@ macro_rules! dot_mat4(
|
||||||
(*$A.cr(3, $I)) * (*$B.cr($J, 3))
|
(*$A.cr(3, $I)) * (*$B.cr($J, 3))
|
||||||
))
|
))
|
||||||
|
|
||||||
impl<S: Float>
|
impl<S: Float + ApproxEq<S>>
|
||||||
Matrix<S, [Vec4<S>, ..4], Vec4<S>, [S, ..4]>
|
Matrix<S, [Vec4<S>, ..4], Vec4<S>, [S, ..4]>
|
||||||
for Mat4<S>
|
for Mat4<S>
|
||||||
{
|
{
|
||||||
|
@ -617,7 +617,8 @@ pub trait ToMat2<S: Primitive> { fn to_mat2(&self) -> Mat2<S>; }
|
||||||
pub trait ToMat3<S: Primitive> { fn to_mat3(&self) -> Mat3<S>; }
|
pub trait ToMat3<S: Primitive> { fn to_mat3(&self) -> Mat3<S>; }
|
||||||
pub trait ToMat4<S: Primitive> { fn to_mat4(&self) -> Mat4<S>; }
|
pub trait ToMat4<S: Primitive> { fn to_mat4(&self) -> Mat4<S>; }
|
||||||
|
|
||||||
impl<S: Float> ToMat3<S> for Mat2<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ToMat3<S> for Mat2<S> {
|
||||||
/// Clone the elements of a 2-dimensional matrix into the top corner of a
|
/// Clone the elements of a 2-dimensional matrix into the top corner of a
|
||||||
/// 3-dimensional identity matrix.
|
/// 3-dimensional identity matrix.
|
||||||
fn to_mat3(&self) -> Mat3<S> {
|
fn to_mat3(&self) -> Mat3<S> {
|
||||||
|
@ -627,7 +628,8 @@ impl<S: Float> ToMat3<S> for Mat2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> ToMat4<S> for Mat2<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ToMat4<S> for Mat2<S> {
|
||||||
/// Clone the elements of a 2-dimensional matrix into the top corner of a
|
/// Clone the elements of a 2-dimensional matrix into the top corner of a
|
||||||
/// 4-dimensional identity matrix.
|
/// 4-dimensional identity matrix.
|
||||||
fn to_mat4(&self) -> Mat4<S> {
|
fn to_mat4(&self) -> Mat4<S> {
|
||||||
|
@ -638,7 +640,8 @@ impl<S: Float> ToMat4<S> for Mat2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> ToMat4<S> for Mat3<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ToMat4<S> for Mat3<S> {
|
||||||
/// Clone the elements of a 3-dimensional matrix into the top corner of a
|
/// Clone the elements of a 3-dimensional matrix into the top corner of a
|
||||||
/// 4-dimensional identity matrix.
|
/// 4-dimensional identity matrix.
|
||||||
fn to_mat4(&self) -> Mat4<S> {
|
fn to_mat4(&self) -> Mat4<S> {
|
||||||
|
@ -649,7 +652,8 @@ impl<S: Float> ToMat4<S> for Mat3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S:Float> ToQuat<S> for Mat3<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ToQuat<S> for Mat3<S> {
|
||||||
/// Convert the matrix to a quaternion
|
/// Convert the matrix to a quaternion
|
||||||
fn to_quat(&self) -> Quat<S> {
|
fn to_quat(&self) -> Quat<S> {
|
||||||
// http://www.cs.ucr.edu/~vbz/resources/Quatut.pdf
|
// http://www.cs.ucr.edu/~vbz/resources/Quatut.pdf
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::cast::transmute;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::num::Zero;
|
use std::num::Zero;
|
||||||
|
|
||||||
|
use approx::ApproxEq;
|
||||||
use intersect::Intersect;
|
use intersect::Intersect;
|
||||||
use point::{Point, Point3};
|
use point::{Point, Point3};
|
||||||
use ray::Ray3;
|
use ray::Ray3;
|
||||||
|
@ -45,7 +46,8 @@ pub struct Plane<S> {
|
||||||
d: S,
|
d: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Plane<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Plane<S> {
|
||||||
/// Construct a plane from a normal vector and a scalar distance
|
/// Construct a plane from a normal vector and a scalar distance
|
||||||
pub fn new(n: Vec3<S>, d: S) -> Plane<S> {
|
pub fn new(n: Vec3<S>, d: S) -> Plane<S> {
|
||||||
Plane { n: n, d: d }
|
Plane { n: n, d: d }
|
||||||
|
@ -110,23 +112,12 @@ impl<S: Float> Intersect<Option<Point3<S>>> for (Plane<S>, Plane<S>, Plane<S>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> ApproxEq<S> for Plane<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ApproxEq<S> for Plane<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> S {
|
fn approx_eq_eps(&self, other: &Plane<S>, epsilon: &S) -> bool {
|
||||||
// TODO: fix this after static methods are fixed in rustc
|
self.n.approx_eq_eps(&other.n, epsilon) &&
|
||||||
fail!(~"Doesn't work!");
|
self.d.approx_eq_eps(&other.d, epsilon)
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, other: &Plane<S>) -> bool {
|
|
||||||
self.n.approx_eq(&other.n) &&
|
|
||||||
self.d.approx_eq(&other.d)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_eps(&self, other: &Plane<S>, approx_epsilon: &S) -> bool {
|
|
||||||
self.n.approx_eq_eps(&other.n, approx_epsilon) &&
|
|
||||||
self.d.approx_eq_eps(&other.d, approx_epsilon)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@ pub struct Point2<S> { x: S, y: S }
|
||||||
#[deriving(Eq, Zero, Clone)]
|
#[deriving(Eq, Zero, Clone)]
|
||||||
pub struct Point3<S> { x: S, y: S, z: S }
|
pub struct Point3<S> { x: S, y: S, z: S }
|
||||||
|
|
||||||
approx_eq!(impl<S> Point2<S>)
|
|
||||||
approx_eq!(impl<S> Point3<S>)
|
|
||||||
|
|
||||||
impl<S: Num> Point2<S> {
|
impl<S: Num> Point2<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
use std::num::{zero, one, cast};
|
use std::num::{zero, one, cast};
|
||||||
|
|
||||||
use angle::{Angle, tan, cot};
|
use angle::{Angle, tan, cot};
|
||||||
|
use approx::ApproxEq;
|
||||||
use frustum::Frustum;
|
use frustum::Frustum;
|
||||||
use matrix::{Mat4, ToMat4};
|
use matrix::{Mat4, ToMat4};
|
||||||
use plane::Plane;
|
use plane::Plane;
|
||||||
|
@ -93,7 +94,8 @@ impl<S: Float, A: Angle<S>> PerspectiveFov<S, A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float, A: Angle<S>> Projection<S> for PerspectiveFov<S, A> {
|
impl<S: Float + ApproxEq<S>, A: Angle<S>>
|
||||||
|
Projection<S> for PerspectiveFov<S, A> {
|
||||||
fn to_frustum(&self) -> Frustum<S> {
|
fn to_frustum(&self) -> Frustum<S> {
|
||||||
// TODO: Could this be faster?
|
// TODO: Could this be faster?
|
||||||
Frustum::from_mat4(self.to_mat4())
|
Frustum::from_mat4(self.to_mat4())
|
||||||
|
@ -149,7 +151,8 @@ pub struct Perspective<S> {
|
||||||
near: S, far: S,
|
near: S, far: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Projection<S> for Perspective<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Projection<S> for Perspective<S> {
|
||||||
fn to_frustum(&self) -> Frustum<S> {
|
fn to_frustum(&self) -> Frustum<S> {
|
||||||
// TODO: Could this be faster?
|
// TODO: Could this be faster?
|
||||||
Frustum::from_mat4(self.to_mat4())
|
Frustum::from_mat4(self.to_mat4())
|
||||||
|
@ -199,7 +202,8 @@ pub struct Ortho<S> {
|
||||||
near: S, far: S,
|
near: S, far: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Projection<S> for Ortho<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Projection<S> for Ortho<S> {
|
||||||
fn to_frustum(&self) -> Frustum<S> {
|
fn to_frustum(&self) -> Frustum<S> {
|
||||||
Frustum {
|
Frustum {
|
||||||
left: Plane::from_abcd( one::<S>(), zero::<S>(), zero::<S>(), self.left.clone()),
|
left: Plane::from_abcd( one::<S>(), zero::<S>(), zero::<S>(), self.left.clone()),
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::fmt;
|
||||||
use std::num::{zero, one, cast, sqrt};
|
use std::num::{zero, one, cast, sqrt};
|
||||||
|
|
||||||
use angle::{Angle, Rad, acos, cos, sin, sin_cos};
|
use angle::{Angle, Rad, acos, cos, sin, sin_cos};
|
||||||
|
use approx::ApproxEq;
|
||||||
use array::{Array, build};
|
use array::{Array, build};
|
||||||
use matrix::{Mat3, ToMat3};
|
use matrix::{Mat3, ToMat3};
|
||||||
use vector::{Vec3, Vector, EuclideanVector};
|
use vector::{Vec3, Vector, EuclideanVector};
|
||||||
|
@ -26,13 +27,13 @@ use vector::{Vec3, Vector, EuclideanVector};
|
||||||
pub struct Quat<S> { s: S, v: Vec3<S> }
|
pub struct Quat<S> { s: S, v: Vec3<S> }
|
||||||
|
|
||||||
array!(impl<S> Quat<S> -> [S, ..4] _4)
|
array!(impl<S> Quat<S> -> [S, ..4] _4)
|
||||||
approx_eq!(impl<S> Quat<S>)
|
|
||||||
|
|
||||||
pub trait ToQuat<S: Float> {
|
pub trait ToQuat<S: Float> {
|
||||||
fn to_quat(&self) -> Quat<S>;
|
fn to_quat(&self) -> Quat<S>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Quat<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Quat<S> {
|
||||||
/// Construct a new quaternion from one scalar component and three
|
/// Construct a new quaternion from one scalar component and three
|
||||||
/// imaginary components
|
/// imaginary components
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -220,7 +221,8 @@ impl<S: Float> Quat<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Quat<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Quat<S> {
|
||||||
/// Spherical Linear Intoperlation
|
/// Spherical Linear Intoperlation
|
||||||
///
|
///
|
||||||
/// Perform a spherical linear interpolation between the quaternion and
|
/// Perform a spherical linear interpolation between the quaternion and
|
||||||
|
@ -265,7 +267,8 @@ impl<S: Float> Quat<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> ToMat3<S> for Quat<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ToMat3<S> for Quat<S> {
|
||||||
/// Convert the quaternion to a 3 x 3 rotation matrix
|
/// Convert the quaternion to a 3 x 3 rotation matrix
|
||||||
fn to_mat3(&self) -> Mat3<S> {
|
fn to_mat3(&self) -> Mat3<S> {
|
||||||
let x2 = self.v.x + self.v.x;
|
let x2 = self.v.x + self.v.x;
|
||||||
|
@ -290,7 +293,8 @@ impl<S: Float> ToMat3<S> for Quat<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Neg<Quat<S>> for Quat<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Neg<Quat<S>> for Quat<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg(&self) -> Quat<S> {
|
fn neg(&self) -> Quat<S> {
|
||||||
Quat::from_sv(-self.s, -self.v)
|
Quat::from_sv(-self.s, -self.v)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use angle::Rad;
|
use angle::Rad;
|
||||||
|
use approx::ApproxEq;
|
||||||
use array::Array;
|
use array::Array;
|
||||||
use matrix::Matrix;
|
use matrix::Matrix;
|
||||||
use matrix::{Mat2, ToMat2};
|
use matrix::{Mat2, ToMat2};
|
||||||
|
@ -115,7 +116,8 @@ impl<S: Float> ToMat2<S> for Basis2<S> {
|
||||||
fn to_mat2(&self) -> Mat2<S> { self.mat.clone() }
|
fn to_mat2(&self) -> Mat2<S> { self.mat.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity() -> Basis2<S> { Basis2{ mat: Mat2::identity() } }
|
fn identity() -> Basis2<S> { Basis2{ mat: Mat2::identity() } }
|
||||||
|
|
||||||
|
@ -139,25 +141,16 @@ impl<S: Float> Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
|
||||||
fn invert_self(&mut self) { self.mat.invert_self(); }
|
fn invert_self(&mut self) { self.mat.invert_self(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> ApproxEq<S> for Basis2<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ApproxEq<S> for Basis2<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> S {
|
fn approx_eq_eps(&self, other: &Basis2<S>, epsilon: &S) -> bool {
|
||||||
// TODO: fix this after static methods are fixed in rustc
|
self.mat.approx_eq_eps(&other.mat, epsilon)
|
||||||
fail!(~"Doesn't work!");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, other: &Basis2<S>) -> bool {
|
|
||||||
self.mat.approx_eq(&other.mat)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_eps(&self, other: &Basis2<S>, approx_epsilon: &S) -> bool {
|
|
||||||
self.mat.approx_eq_eps(&other.mat, approx_epsilon)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Rotation2<S> for Basis2<S> {}
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Rotation2<S> for Basis2<S> {}
|
||||||
|
|
||||||
/// A three-dimensional rotation matrix.
|
/// A three-dimensional rotation matrix.
|
||||||
///
|
///
|
||||||
|
@ -170,7 +163,8 @@ pub struct Basis3<S> {
|
||||||
priv mat: Mat3<S>
|
priv mat: Mat3<S>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Basis3<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Basis3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Basis3<S> {
|
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Basis3<S> {
|
||||||
Basis3 { mat: Mat3::look_at(dir, up) }
|
Basis3 { mat: Mat3::look_at(dir, up) }
|
||||||
|
@ -225,12 +219,14 @@ impl<S: Float> ToMat3<S> for Basis3<S> {
|
||||||
fn to_mat3(&self) -> Mat3<S> { self.mat.clone() }
|
fn to_mat3(&self) -> Mat3<S> { self.mat.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> ToQuat<S> for Basis3<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ToQuat<S> for Basis3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_quat(&self) -> Quat<S> { self.mat.to_quat() }
|
fn to_quat(&self) -> Quat<S> { self.mat.to_quat() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Basis3<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Basis3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity() -> Basis3<S> { Basis3{ mat: Mat3::identity() } }
|
fn identity() -> Basis3<S> { Basis3{ mat: Mat3::identity() } }
|
||||||
|
|
||||||
|
@ -254,29 +250,21 @@ impl<S: Float> Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Basis3<S> {
|
||||||
fn invert_self(&mut self) { self.mat.invert_self(); }
|
fn invert_self(&mut self) { self.mat.invert_self(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> ApproxEq<S> for Basis3<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ApproxEq<S> for Basis3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> S {
|
fn approx_eq_eps(&self, other: &Basis3<S>, epsilon: &S) -> bool {
|
||||||
// TODO: fix this after static methods are fixed in rustc
|
self.mat.approx_eq_eps(&other.mat, epsilon)
|
||||||
fail!(~"Doesn't work!");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, other: &Basis3<S>) -> bool {
|
|
||||||
self.mat.approx_eq(&other.mat)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_eps(&self, other: &Basis3<S>, approx_epsilon: &S) -> bool {
|
|
||||||
self.mat.approx_eq_eps(&other.mat, approx_epsilon)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Rotation3<S> for Basis3<S> {}
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Rotation3<S> for Basis3<S> {}
|
||||||
|
|
||||||
// Quaternion Rotation impls
|
// Quaternion Rotation impls
|
||||||
|
|
||||||
impl<S: Float> ToBasis3<S> for Quat<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
ToBasis3<S> for Quat<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_rot3(&self) -> Basis3<S> { Basis3 { mat: self.to_mat3() } }
|
fn to_rot3(&self) -> Basis3<S> { Basis3 { mat: self.to_mat3() } }
|
||||||
}
|
}
|
||||||
|
@ -286,7 +274,8 @@ impl<S: Float> ToQuat<S> for Quat<S> {
|
||||||
fn to_quat(&self) -> Quat<S> { self.clone() }
|
fn to_quat(&self) -> Quat<S> { self.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity() -> Quat<S> { Quat::identity() }
|
fn identity() -> Quat<S> { Quat::identity() }
|
||||||
|
|
||||||
|
@ -306,4 +295,5 @@ impl<S: Float> Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> {
|
||||||
fn invert_self(&mut self) { *self = self.invert() }
|
fn invert_self(&mut self) { *self = self.invert() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Rotation3<S> for Quat<S> {}
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
Rotation3<S> for Quat<S> {}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
use std::{fmt,num};
|
use std::{fmt,num};
|
||||||
|
|
||||||
|
use approx::ApproxEq;
|
||||||
use matrix::{Matrix, Mat4, ToMat4};
|
use matrix::{Matrix, Mat4, ToMat4};
|
||||||
use point::{Point, Point3};
|
use point::{Point, Point3};
|
||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
|
@ -73,7 +74,7 @@ pub struct Decomposed<S,V,R> {
|
||||||
|
|
||||||
impl
|
impl
|
||||||
<
|
<
|
||||||
S: Float,
|
S: Float + ApproxEq<S>,
|
||||||
Slice,
|
Slice,
|
||||||
V: Vector<S, Slice>,
|
V: Vector<S, Slice>,
|
||||||
P: Point<S, V, Slice>,
|
P: Point<S, V, Slice>,
|
||||||
|
@ -129,7 +130,7 @@ pub trait Transform3<S>
|
||||||
+ ToMat4<S>
|
+ ToMat4<S>
|
||||||
{}
|
{}
|
||||||
|
|
||||||
impl<S: Float + Clone, R: Rotation3<S>>
|
impl<S: Float + Clone + ApproxEq<S>, R: Rotation3<S>>
|
||||||
ToMat4<S> for Decomposed<S, Vec3<S>, R> {
|
ToMat4<S> for Decomposed<S, Vec3<S>, R> {
|
||||||
fn to_mat4(&self) -> Mat4<S> {
|
fn to_mat4(&self) -> Mat4<S> {
|
||||||
let mut m = self.rot.to_mat3().mul_s( self.scale.clone() ).to_mat4();
|
let mut m = self.rot.to_mat3().mul_s( self.scale.clone() ).to_mat4();
|
||||||
|
@ -138,7 +139,7 @@ ToMat4<S> for Decomposed<S, Vec3<S>, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float, R: Rotation3<S>>
|
impl<S: Float + ApproxEq<S>, R: Rotation3<S>>
|
||||||
Transform3<S> for Decomposed<S,Vec3<S>,R> {}
|
Transform3<S> for Decomposed<S,Vec3<S>,R> {}
|
||||||
|
|
||||||
impl<S: fmt::Default + Float, R: ToStr + Rotation3<S>>
|
impl<S: fmt::Default + Float, R: ToStr + Rotation3<S>>
|
||||||
|
@ -155,7 +156,7 @@ pub struct AffineMatrix3<S> {
|
||||||
mat: Mat4<S>,
|
mat: Mat4<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S : Clone + Float>
|
impl<S : Clone + Float + ApproxEq<S>>
|
||||||
Transform<S, [S, ..3], Vec3<S>, Point3<S>> for AffineMatrix3<S> {
|
Transform<S, [S, ..3], Vec3<S>, Point3<S>> for AffineMatrix3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity() -> AffineMatrix3<S> {
|
fn identity() -> AffineMatrix3<S> {
|
||||||
|
@ -188,7 +189,7 @@ ToMat4<S> for AffineMatrix3<S> {
|
||||||
#[inline] fn to_mat4(&self) -> Mat4<S> { self.mat.clone() }
|
#[inline] fn to_mat4(&self) -> Mat4<S> { self.mat.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float>
|
impl<S: Float + ApproxEq<S>>
|
||||||
Transform3<S> for AffineMatrix3<S> {}
|
Transform3<S> for AffineMatrix3<S> {}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::fmt;
|
||||||
use std::num::{Zero, zero, One, one, sqrt};
|
use std::num::{Zero, zero, One, one, sqrt};
|
||||||
|
|
||||||
use angle::{Rad, atan2, acos};
|
use angle::{Rad, atan2, acos};
|
||||||
|
use approx::ApproxEq;
|
||||||
use array::{Array, build};
|
use array::{Array, build};
|
||||||
|
|
||||||
/// A 2-dimensional vector.
|
/// A 2-dimensional vector.
|
||||||
|
@ -112,10 +113,6 @@ array!(impl<S> Vec2<S> -> [S, ..2] _2)
|
||||||
array!(impl<S> Vec3<S> -> [S, ..3] _3)
|
array!(impl<S> Vec3<S> -> [S, ..3] _3)
|
||||||
array!(impl<S> Vec4<S> -> [S, ..4] _4)
|
array!(impl<S> Vec4<S> -> [S, ..4] _4)
|
||||||
|
|
||||||
approx_eq!(impl<S> Vec2<S>)
|
|
||||||
approx_eq!(impl<S> Vec3<S>)
|
|
||||||
approx_eq!(impl<S> Vec4<S>)
|
|
||||||
|
|
||||||
/// A trait that specifies a range of numeric operations for vectors. Not all
|
/// 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
|
/// of these make sense from a linear algebra point of view, but are included
|
||||||
/// for pragmatic reasons.
|
/// for pragmatic reasons.
|
||||||
|
@ -215,7 +212,7 @@ impl<S: Primitive> Vec3<S> {
|
||||||
/// 2-dimensional and 3-dimensional vectors.
|
/// 2-dimensional and 3-dimensional vectors.
|
||||||
pub trait EuclideanVector
|
pub trait EuclideanVector
|
||||||
<
|
<
|
||||||
S: Float,
|
S: Float + ApproxEq<S>,
|
||||||
Slice
|
Slice
|
||||||
>
|
>
|
||||||
: Vector<S, Slice>
|
: Vector<S, Slice>
|
||||||
|
@ -286,21 +283,24 @@ pub trait EuclideanVector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> EuclideanVector<S, [S, ..2]> for Vec2<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
EuclideanVector<S, [S, ..2]> for Vec2<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn angle(&self, other: &Vec2<S>) -> Rad<S> {
|
fn angle(&self, other: &Vec2<S>) -> Rad<S> {
|
||||||
atan2(self.perp_dot(other), self.dot(other))
|
atan2(self.perp_dot(other), self.dot(other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> EuclideanVector<S, [S, ..3]> for Vec3<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
EuclideanVector<S, [S, ..3]> for Vec3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn angle(&self, other: &Vec3<S>) -> Rad<S> {
|
fn angle(&self, other: &Vec3<S>) -> Rad<S> {
|
||||||
atan2(self.cross(other).length(), self.dot(other))
|
atan2(self.cross(other).length(), self.dot(other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> EuclideanVector<S, [S, ..4]> for Vec4<S> {
|
impl<S: Float + ApproxEq<S>>
|
||||||
|
EuclideanVector<S, [S, ..4]> for Vec4<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn angle(&self, other: &Vec4<S>) -> Rad<S> {
|
fn angle(&self, other: &Vec4<S>) -> Rad<S> {
|
||||||
acos(self.dot(other) / (self.length() * other.length()))
|
acos(self.dot(other) / (self.length() * other.length()))
|
||||||
|
|
Loading…
Reference in a new issue