Use the new core::num traits and remove numeric dependency
This commit is contained in:
parent
a6acab93c3
commit
0cb3314bf8
9 changed files with 139 additions and 508 deletions
4
Makefile
4
Makefile
|
@ -15,7 +15,7 @@ TEST_BUILD_DIR = $(ROOT_DIR)/test
|
|||
$(TARGET):
|
||||
@echo "Building $(TARGET)..."
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
@rustc $(SRC_DIR)/$(SRC_CRATE) -L $(EXTERN_DIR) --out-dir=$(BUILD_DIR)
|
||||
@rustc $(SRC_DIR)/$(SRC_CRATE) --out-dir=$(BUILD_DIR)
|
||||
@echo "Success"
|
||||
|
||||
all: $(TARGET)
|
||||
|
@ -23,7 +23,7 @@ all: $(TARGET)
|
|||
test:
|
||||
@echo "Building unit tests for $(TARGET)..."
|
||||
@mkdir -p $(TEST_BUILD_DIR)
|
||||
@rustc $(SRC_DIR)/$(SRC_CRATE) --test -L $(EXTERN_DIR) --out-dir=$(TEST_BUILD_DIR)
|
||||
@rustc $(SRC_DIR)/$(SRC_CRATE) --test --out-dir=$(TEST_BUILD_DIR)
|
||||
@echo "Success"
|
||||
@$(TEST_BUILD_DIR)/$(TARGET)
|
||||
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
A linear algebra library for Rust, targeted at computer graphics.
|
||||
|
||||
## Dependencies
|
||||
|
||||
[numeric-rs](https://github.com/bjz/numeric-rs/) (drop the library binary into lmath/extern)
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
0
extern/.gitkeep
vendored
0
extern/.gitkeep
vendored
|
@ -9,7 +9,8 @@
|
|||
#[crate_type = "lib"];
|
||||
|
||||
extern mod std;
|
||||
extern mod numeric;
|
||||
|
||||
pub mod num;
|
||||
|
||||
pub mod mat;
|
||||
pub mod quat;
|
||||
|
|
190
src/mat.rs
190
src/mat.rs
|
@ -1,11 +1,12 @@
|
|||
use core::num::Zero::zero;
|
||||
use core::num::One::one;
|
||||
use std::cmp::{FuzzyEq, FUZZY_EPSILON};
|
||||
use numeric::*;
|
||||
|
||||
use vec::*;
|
||||
use quat::Quat;
|
||||
|
||||
use num::NumAssign;
|
||||
|
||||
/**
|
||||
* The base square matrix trait
|
||||
*
|
||||
|
@ -312,7 +313,7 @@ pub trait BaseMat4<T,V>: BaseMat<T,V> {
|
|||
#[deriving(Eq)]
|
||||
pub struct Mat2<T> { x: Vec2<T>, y: Vec2<T> }
|
||||
|
||||
impl<T:Copy + Float> BaseMat<T, Vec2<T>> for Mat2<T> {
|
||||
impl<T:Copy + Float + NumAssign + FuzzyEq<T>> BaseMat<T, Vec2<T>> for Mat2<T> {
|
||||
#[inline(always)]
|
||||
fn col(&self, i: uint) -> Vec2<T> { self[i] }
|
||||
|
||||
|
@ -537,7 +538,7 @@ impl<T:Copy + Float> BaseMat<T, Vec2<T>> for Mat2<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> BaseMat2<T, Vec2<T>> for Mat2<T> {
|
||||
impl<T:Copy + Float + NumAssign + FuzzyEq<T>> BaseMat2<T, Vec2<T>> for Mat2<T> {
|
||||
/**
|
||||
* Construct a 2 x 2 matrix
|
||||
*
|
||||
|
@ -586,8 +587,8 @@ impl<T:Copy + Float> BaseMat2<T, Vec2<T>> for Mat2<T> {
|
|||
|
||||
#[inline(always)]
|
||||
fn from_angle(radians: T) -> Mat2<T> {
|
||||
let cos_theta = cos(radians);
|
||||
let sin_theta = sin(radians);
|
||||
let cos_theta = radians.cos();
|
||||
let sin_theta = radians.sin();
|
||||
|
||||
BaseMat2::new(cos_theta, -sin_theta,
|
||||
sin_theta, cos_theta)
|
||||
|
@ -644,14 +645,14 @@ impl<T:Copy> Index<uint, Vec2<T>> for Mat2<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> Neg<Mat2<T>> for Mat2<T> {
|
||||
impl<T:Copy + Float + NumAssign + FuzzyEq<T>> Neg<Mat2<T>> for Mat2<T> {
|
||||
#[inline(always)]
|
||||
fn neg(&self) -> Mat2<T> {
|
||||
BaseMat2::from_cols(-self[0], -self[1])
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> FuzzyEq<T> for Mat2<T> {
|
||||
impl<T:Copy + Float + FuzzyEq<T>> FuzzyEq<T> for Mat2<T> {
|
||||
#[inline(always)]
|
||||
fn fuzzy_eq(&self, other: &Mat2<T>) -> bool {
|
||||
self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON))
|
||||
|
@ -664,48 +665,6 @@ impl<T:Copy + Float> FuzzyEq<T> for Mat2<T> {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! mat2_type(
|
||||
($name:ident <$T:ty, $V:ty>) => (
|
||||
pub impl $name {
|
||||
#[inline(always)] fn new(c0r0: $T, c0r1: $T, c1r0: $T, c1r1: $T)
|
||||
-> $name { BaseMat2::new(c0r0, c0r1, c1r0, c1r1) }
|
||||
#[inline(always)] fn from_cols(c0: $V, c1: $V)
|
||||
-> $name { BaseMat2::from_cols(c0, c1) }
|
||||
#[inline(always)] fn from_value(v: $T) -> $name { BaseMat::from_value(v) }
|
||||
|
||||
#[inline(always)] fn identity() -> $name { BaseMat::identity() }
|
||||
#[inline(always)] fn zero() -> $name { BaseMat::zero() }
|
||||
|
||||
#[inline(always)] fn from_angle(radians: $T) -> $name { BaseMat2::from_angle(radians) }
|
||||
|
||||
#[inline(always)] fn dim() -> uint { 2 }
|
||||
#[inline(always)] fn rows() -> uint { 2 }
|
||||
#[inline(always)] fn cols() -> uint { 2 }
|
||||
#[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
// GLSL-style type aliases, corresponding to Section 4.1.6 of the [GLSL 4.30.6 specification]
|
||||
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
||||
|
||||
// a 2×2 single-precision floating-point matrix
|
||||
pub type mat2 = Mat2<f32>;
|
||||
// a 2×2 double-precision floating-point matrix
|
||||
pub type dmat2 = Mat2<f64>;
|
||||
|
||||
mat2_type!(mat2<f32,vec2>)
|
||||
mat2_type!(dmat2<f64,dvec2>)
|
||||
|
||||
// Rust-style type aliases
|
||||
pub type Mat2f = Mat2<float>;
|
||||
pub type Mat2f32 = Mat2<f32>;
|
||||
pub type Mat2f64 = Mat2<f64>;
|
||||
|
||||
mat2_type!(Mat2f<float,Vec2f>)
|
||||
mat2_type!(Mat2f32<f32,Vec2f32>)
|
||||
mat2_type!(Mat2f64<f64,Vec2f64>)
|
||||
|
||||
/**
|
||||
* A 3 x 3 column major matrix
|
||||
*
|
||||
|
@ -722,7 +681,7 @@ mat2_type!(Mat2f64<f64,Vec2f64>)
|
|||
#[deriving(Eq)]
|
||||
pub struct Mat3<T> { x: Vec3<T>, y: Vec3<T>, z: Vec3<T> }
|
||||
|
||||
impl<T:Copy + Float> BaseMat<T, Vec3<T>> for Mat3<T> {
|
||||
impl<T:Copy + Float + NumAssign + FuzzyEq<T>> BaseMat<T, Vec3<T>> for Mat3<T> {
|
||||
#[inline(always)]
|
||||
fn col(&self, i: uint) -> Vec3<T> { self[i] }
|
||||
|
||||
|
@ -996,7 +955,7 @@ impl<T:Copy + Float> BaseMat<T, Vec3<T>> for Mat3<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> BaseMat3<T, Vec3<T>> for Mat3<T> {
|
||||
impl<T:Copy + Float + NumAssign + FuzzyEq<T>> BaseMat3<T, Vec3<T>> for Mat3<T> {
|
||||
/**
|
||||
* Construct a 3 x 3 matrix
|
||||
*
|
||||
|
@ -1057,8 +1016,8 @@ impl<T:Copy + Float> BaseMat3<T, Vec3<T>> for Mat3<T> {
|
|||
#[inline(always)]
|
||||
fn from_angle_x(radians: T) -> Mat3<T> {
|
||||
// http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
|
||||
let cos_theta = cos(radians);
|
||||
let sin_theta = sin(radians);
|
||||
let cos_theta = radians.cos();
|
||||
let sin_theta = radians.sin();
|
||||
|
||||
BaseMat3::new( one(), zero(), zero(),
|
||||
zero(), cos_theta, sin_theta,
|
||||
|
@ -1071,8 +1030,8 @@ impl<T:Copy + Float> BaseMat3<T, Vec3<T>> for Mat3<T> {
|
|||
#[inline(always)]
|
||||
fn from_angle_y(radians: T) -> Mat3<T> {
|
||||
// http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
|
||||
let cos_theta = cos(radians);
|
||||
let sin_theta = sin(radians);
|
||||
let cos_theta = radians.cos();
|
||||
let sin_theta = radians.sin();
|
||||
|
||||
BaseMat3::new(cos_theta, zero(), -sin_theta,
|
||||
zero(), one(), zero(),
|
||||
|
@ -1085,8 +1044,8 @@ impl<T:Copy + Float> BaseMat3<T, Vec3<T>> for Mat3<T> {
|
|||
#[inline(always)]
|
||||
fn from_angle_z(radians: T) -> Mat3<T> {
|
||||
// http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
|
||||
let cos_theta = cos(radians);
|
||||
let sin_theta = sin(radians);
|
||||
let cos_theta = radians.cos();
|
||||
let sin_theta = radians.sin();
|
||||
|
||||
BaseMat3::new( cos_theta, sin_theta, zero(),
|
||||
-sin_theta, cos_theta, zero(),
|
||||
|
@ -1105,12 +1064,12 @@ impl<T:Copy + Float> BaseMat3<T, Vec3<T>> for Mat3<T> {
|
|||
#[inline(always)]
|
||||
fn from_angle_xyz(radians_x: T, radians_y: T, radians_z: T) -> Mat3<T> {
|
||||
// http://en.wikipedia.org/wiki/Rotation_matrix#General_rotations
|
||||
let cx = cos(radians_x);
|
||||
let sx = sin(radians_x);
|
||||
let cy = cos(radians_y);
|
||||
let sy = sin(radians_y);
|
||||
let cz = cos(radians_z);
|
||||
let sz = sin(radians_z);
|
||||
let cx = radians_x.cos();
|
||||
let sx = radians_x.sin();
|
||||
let cy = radians_y.cos();
|
||||
let sy = radians_y.sin();
|
||||
let cz = radians_z.cos();
|
||||
let sz = radians_z.sin();
|
||||
|
||||
BaseMat3::new( cy*cz, cy*sz, -sy,
|
||||
-cx*sz + sx*sy*cz, cx*cz + sx*sy*sz, sx*cy,
|
||||
|
@ -1122,8 +1081,8 @@ impl<T:Copy + Float> BaseMat3<T, Vec3<T>> for Mat3<T> {
|
|||
*/
|
||||
#[inline(always)]
|
||||
fn from_angle_axis(radians: T, axis: &Vec3<T>) -> Mat3<T> {
|
||||
let c = cos(radians);
|
||||
let s = sin(radians);
|
||||
let c = radians.cos();
|
||||
let s = radians.sin();
|
||||
let _1_c = one::<T>() - c;
|
||||
|
||||
let x = axis.x;
|
||||
|
@ -1228,14 +1187,14 @@ impl<T:Copy> Index<uint, Vec3<T>> for Mat3<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> Neg<Mat3<T>> for Mat3<T> {
|
||||
impl<T:Copy + Float + NumAssign + FuzzyEq<T>> Neg<Mat3<T>> for Mat3<T> {
|
||||
#[inline(always)]
|
||||
fn neg(&self) -> Mat3<T> {
|
||||
BaseMat3::from_cols(-self[0], -self[1], -self[2])
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> FuzzyEq<T> for Mat3<T> {
|
||||
impl<T:Copy + Float + FuzzyEq<T>> FuzzyEq<T> for Mat3<T> {
|
||||
#[inline(always)]
|
||||
fn fuzzy_eq(&self, other: &Mat3<T>) -> bool {
|
||||
self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON))
|
||||
|
@ -1249,51 +1208,6 @@ impl<T:Copy + Float> FuzzyEq<T> for Mat3<T> {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! mat3_type(
|
||||
($name:ident <$T:ty, $V:ty>) => (
|
||||
pub impl $name {
|
||||
#[inline(always)] fn new(c0r0: $T, c0r1: $T, c0r2: $T, c1r0: $T, c1r1: $T, c1r2: $T, c2r0: $T, c2r1: $T, c2r2: $T)
|
||||
-> $name { BaseMat3::new(c0r0, c0r1, c0r2, c1r0, c1r1, c1r2, c2r0, c2r1, c2r2) }
|
||||
#[inline(always)] fn from_cols(c0: $V, c1: $V, c2: $V)
|
||||
-> $name { BaseMat3::from_cols(c0, c1, c2) }
|
||||
#[inline(always)] fn from_value(v: $T) -> $name { BaseMat::from_value(v) }
|
||||
|
||||
#[inline(always)] fn identity() -> $name { BaseMat::identity() }
|
||||
#[inline(always)] fn zero() -> $name { BaseMat::zero() }
|
||||
|
||||
#[inline(always)] fn from_angle_x(radians: $T) -> $name { BaseMat3::from_angle_x(radians) }
|
||||
#[inline(always)] fn from_angle_y(radians: $T) -> $name { BaseMat3::from_angle_y(radians) }
|
||||
#[inline(always)] fn from_angle_z(radians: $T) -> $name { BaseMat3::from_angle_z(radians) }
|
||||
#[inline(always)] fn from_angle_xyz(radians_x: $T, radians_y: $T, radians_z: $T) -> $name { BaseMat3::from_angle_xyz(radians_x, radians_y, radians_z) }
|
||||
#[inline(always)] fn from_angle_axis(radians: $T, axis: &$V) -> $name { BaseMat3::from_angle_axis(radians, axis) }
|
||||
#[inline(always)] fn from_axes(x: $V, y: $V, z: $V) -> $name { BaseMat3::from_axes(x, y, z) }
|
||||
#[inline(always)] fn look_at(dir: &$V, up: &$V) -> $name { BaseMat3::look_at(dir, up) }
|
||||
|
||||
#[inline(always)] fn dim() -> uint { 3 }
|
||||
#[inline(always)] fn rows() -> uint { 3 }
|
||||
#[inline(always)] fn cols() -> uint { 3 }
|
||||
#[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
// a 3×3 single-precision floating-point matrix
|
||||
pub type mat3 = Mat3<f32>;
|
||||
// a 3×3 double-precision floating-point matrix
|
||||
pub type dmat3 = Mat3<f64>;
|
||||
|
||||
mat3_type!(mat3<f32,vec3>)
|
||||
mat3_type!(dmat3<f64,dvec3>)
|
||||
|
||||
// Rust-style type aliases
|
||||
pub type Mat3f = Mat3<float>;
|
||||
pub type Mat3f32 = Mat3<f32>;
|
||||
pub type Mat3f64 = Mat3<f64>;
|
||||
|
||||
mat3_type!(Mat3f<float,Vec3f>)
|
||||
mat3_type!(Mat3f32<f32,Vec3f32>)
|
||||
mat3_type!(Mat3f64<f64,Vec3f64>)
|
||||
|
||||
/**
|
||||
* A 4 x 4 column major matrix
|
||||
*
|
||||
|
@ -1311,7 +1225,7 @@ mat3_type!(Mat3f64<f64,Vec3f64>)
|
|||
#[deriving(Eq)]
|
||||
pub struct Mat4<T> { x: Vec4<T>, y: Vec4<T>, z: Vec4<T>, w: Vec4<T> }
|
||||
|
||||
impl<T:Copy + Float> BaseMat<T, Vec4<T>> for Mat4<T> {
|
||||
impl<T:Copy + Float + NumAssign + FuzzyEq<T>> BaseMat<T, Vec4<T>> for Mat4<T> {
|
||||
#[inline(always)]
|
||||
fn col(&self, i: uint) -> Vec4<T> { self[i] }
|
||||
|
||||
|
@ -1498,12 +1412,11 @@ impl<T:Copy + Float> BaseMat<T, Vec4<T>> for Mat4<T> {
|
|||
// Find largest element in col j
|
||||
let mut i1 = j;
|
||||
for uint::range(j + 1, 4) |i| {
|
||||
if abs(A[j][i]) > abs(A[j][i1]) {
|
||||
if A[j][i].abs() > A[j][i1].abs() {
|
||||
i1 = i;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
// Swap columns i1 and j in A and I to
|
||||
// put pivot on diagonal
|
||||
A.swap_cols(i1, j);
|
||||
|
@ -1522,7 +1435,6 @@ impl<T:Copy + Float> BaseMat<T, Vec4<T>> for Mat4<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(I)
|
||||
}
|
||||
}
|
||||
|
@ -1684,7 +1596,7 @@ impl<T:Copy + Float> BaseMat<T, Vec4<T>> for Mat4<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> BaseMat4<T, Vec4<T>> for Mat4<T> {
|
||||
impl<T:Copy + Float + NumAssign + FuzzyEq<T>> BaseMat4<T, Vec4<T>> for Mat4<T> {
|
||||
/**
|
||||
* Construct a 4 x 4 matrix
|
||||
*
|
||||
|
@ -1748,7 +1660,7 @@ impl<T:Copy + Float> BaseMat4<T, Vec4<T>> for Mat4<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> Neg<Mat4<T>> for Mat4<T> {
|
||||
impl<T:Copy + Float + NumAssign + FuzzyEq<T>> Neg<Mat4<T>> for Mat4<T> {
|
||||
#[inline(always)]
|
||||
fn neg(&self) -> Mat4<T> {
|
||||
BaseMat4::from_cols(-self[0], -self[1], -self[2], -self[3])
|
||||
|
@ -1762,7 +1674,7 @@ impl<T:Copy> Index<uint, Vec4<T>> for Mat4<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> FuzzyEq<T> for Mat4<T> {
|
||||
impl<T:Copy + Float + FuzzyEq<T>> FuzzyEq<T> for Mat4<T> {
|
||||
#[inline(always)]
|
||||
fn fuzzy_eq(&self, other: &Mat4<T>) -> bool {
|
||||
self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON))
|
||||
|
@ -1776,43 +1688,3 @@ impl<T:Copy + Float> FuzzyEq<T> for Mat4<T> {
|
|||
self[3].fuzzy_eq_eps(&other[3], epsilon)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! mat4_type(
|
||||
($name:ident <$T:ty, $V:ty>) => (
|
||||
pub impl $name {
|
||||
#[inline(always)] fn new(c0r0: $T, c0r1: $T, c0r2: $T, c0r3: $T, c1r0: $T, c1r1: $T, c1r2: $T, c1r3: $T, c2r0: $T, c2r1: $T, c2r2: $T, c2r3: $T, c3r0: $T, c3r1: $T, c3r2: $T, c3r3: $T)
|
||||
-> $name { BaseMat4::new(c0r0, c0r1, c0r2, c0r3, c1r0, c1r1, c1r2, c1r3, c2r0, c2r1, c2r2, c2r3, c3r0, c3r1, c3r2, c3r3) }
|
||||
#[inline(always)] fn from_cols(c0: $V, c1: $V, c2: $V, c3: $V)
|
||||
-> $name { BaseMat4::from_cols(c0, c1, c2, c3) }
|
||||
#[inline(always)] fn from_value(v: $T) -> $name { BaseMat::from_value(v) }
|
||||
|
||||
#[inline(always)] fn identity() -> $name { BaseMat::identity() }
|
||||
#[inline(always)] fn zero() -> $name { BaseMat::zero() }
|
||||
|
||||
#[inline(always)] fn dim() -> uint { 4 }
|
||||
#[inline(always)] fn rows() -> uint { 4 }
|
||||
#[inline(always)] fn cols() -> uint { 4 }
|
||||
#[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
// GLSL-style type aliases, corresponding to Section 4.1.6 of the [GLSL 4.30.6 specification]
|
||||
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
||||
|
||||
// a 4×4 single-precision floating-point matrix
|
||||
pub type mat4 = Mat4<f32>;
|
||||
// a 4×4 double-precision floating-point matrix
|
||||
pub type dmat4 = Mat4<f64>;
|
||||
|
||||
mat4_type!(mat4<f32,vec4>)
|
||||
mat4_type!(dmat4<f64,dvec4>)
|
||||
|
||||
// Rust-style type aliases
|
||||
pub type Mat4f = Mat4<float>;
|
||||
pub type Mat4f32 = Mat4<f32>;
|
||||
pub type Mat4f64 = Mat4<f64>;
|
||||
|
||||
mat4_type!(Mat4f<float,Vec4f>)
|
||||
mat4_type!(Mat4f32<f32,Vec4f32>)
|
||||
mat4_type!(Mat4f64<f64,Vec4f64>)
|
35
src/num.rs
Normal file
35
src/num.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
pub trait NumAssign {
|
||||
fn add_assign(&mut self, other: &Self);
|
||||
fn sub_assign(&mut self, other: &Self);
|
||||
fn mul_assign(&mut self, other: &Self);
|
||||
fn div_assign(&mut self, other: &Self);
|
||||
fn rem_assign(&mut self, other: &Self);
|
||||
}
|
||||
|
||||
macro_rules! impl_NumAssign(
|
||||
($T:ty) => (
|
||||
impl NumAssign for $T {
|
||||
#[inline(always)] fn add_assign(&mut self, other: &$T) { *self += *other }
|
||||
#[inline(always)] fn sub_assign(&mut self, other: &$T) { *self -= *other }
|
||||
#[inline(always)] fn mul_assign(&mut self, other: &$T) { *self *= *other }
|
||||
#[inline(always)] fn div_assign(&mut self, other: &$T) { *self /= *other }
|
||||
#[inline(always)] fn rem_assign(&mut self, other: &$T) { *self %= *other }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
impl_NumAssign!(float)
|
||||
impl_NumAssign!(f32)
|
||||
impl_NumAssign!(f64)
|
||||
|
||||
impl_NumAssign!(int)
|
||||
impl_NumAssign!(i8)
|
||||
impl_NumAssign!(i16)
|
||||
impl_NumAssign!(i32)
|
||||
impl_NumAssign!(i64)
|
||||
|
||||
impl_NumAssign!(uint)
|
||||
impl_NumAssign!(u8)
|
||||
impl_NumAssign!(u16)
|
||||
impl_NumAssign!(u32)
|
||||
impl_NumAssign!(u64)
|
|
@ -1,7 +1,9 @@
|
|||
use numeric::*;
|
||||
use std::cmp::FuzzyEq;
|
||||
|
||||
use mat::{Mat4, BaseMat4};
|
||||
|
||||
use num::NumAssign;
|
||||
|
||||
/**
|
||||
* Create a perspective projection matrix
|
||||
*
|
||||
|
@ -11,10 +13,10 @@ use mat::{Mat4, BaseMat4};
|
|||
* can be found [here](http://www.opengl.org/wiki/GluPerspective_code).
|
||||
*/
|
||||
#[inline(always)]
|
||||
pub fn perspective<T:Copy + Float>(fovy: T, aspectRatio: T, near: T, far: T) -> Mat4<T> {
|
||||
pub fn perspective<T:Copy + Float + NumAssign + FuzzyEq<T>>(fovy: T, aspectRatio: T, near: T, far: T) -> Mat4<T> {
|
||||
let _2: T = num::cast(2);
|
||||
|
||||
let ymax = near * tan(radians(fovy / _2));
|
||||
let ymax = near * (fovy / _2).to_radians().tan();
|
||||
let xmax = ymax * aspectRatio;
|
||||
|
||||
frustum(-xmax, xmax, -ymax, ymax, near, far)
|
||||
|
@ -27,7 +29,7 @@ pub fn perspective<T:Copy + Float>(fovy: T, aspectRatio: T, near: T, far: T) ->
|
|||
* (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml) function.
|
||||
*/
|
||||
#[inline(always)]
|
||||
pub fn frustum<T:Copy + Float>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
|
||||
pub fn frustum<T:Copy + Float + NumAssign + FuzzyEq<T>>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
|
||||
let _0: T = num::cast(0);
|
||||
let _1: T = num::cast(1);
|
||||
let _2: T = num::cast(2);
|
||||
|
@ -65,7 +67,7 @@ pub fn frustum<T:Copy + Float>(left: T, right: T, bottom: T, top: T, near: T, fa
|
|||
* (http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml) function.
|
||||
*/
|
||||
#[inline(always)]
|
||||
pub fn ortho<T:Copy + Float>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
|
||||
pub fn ortho<T:Copy + Float + NumAssign + FuzzyEq<T>>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
|
||||
let _0: T = num::cast(0);
|
||||
let _1: T = num::cast(1);
|
||||
let _2: T = num::cast(2);
|
||||
|
|
76
src/quat.rs
76
src/quat.rs
|
@ -10,11 +10,11 @@
|
|||
use core::num::Zero::zero;
|
||||
use core::num::One::one;
|
||||
use std::cmp::{FuzzyEq, FUZZY_EPSILON};
|
||||
use numeric::*;
|
||||
|
||||
use mat::{Mat3, BaseMat3};
|
||||
use vec::{Vec3, BaseVec3, AffineVec, NumVec, NumVec3};
|
||||
use vec::{vec3, dvec3, Vec3f, Vec3f32, Vec3f64};
|
||||
|
||||
use num::NumAssign;
|
||||
|
||||
/**
|
||||
* A quaternion in scalar/vector form
|
||||
|
@ -31,7 +31,7 @@ use vec::{vec3, dvec3, Vec3f, Vec3f32, Vec3f64};
|
|||
#[deriving(Eq)]
|
||||
pub struct Quat<T> { s: T, v: Vec3<T> }
|
||||
|
||||
pub impl<T:Copy + Float> Quat<T> {
|
||||
pub impl<T:Copy + Float + NumAssign + FuzzyEq<T>> Quat<T> {
|
||||
/**
|
||||
* Construct the quaternion from one scalar component and three
|
||||
* imaginary components
|
||||
|
@ -84,19 +84,19 @@ pub impl<T:Copy + Float> Quat<T> {
|
|||
#[inline(always)]
|
||||
fn from_angle_x(radians: T) -> Quat<T> {
|
||||
let _2 = num::cast(2);
|
||||
Quat::new(cos(radians / _2), sin(radians), zero(), zero())
|
||||
Quat::new((radians / _2).cos(), radians.sin(), zero(), zero())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn from_angle_y(radians: T) -> Quat<T> {
|
||||
let _2 = num::cast(2);
|
||||
Quat::new(cos(radians / _2), zero(), sin(radians), zero())
|
||||
Quat::new((radians / _2).cos(), zero(), radians.sin(), zero())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn from_angle_z(radians: T) -> Quat<T> {
|
||||
let _2 = num::cast(2);
|
||||
Quat::new(cos(radians / _2), zero(), zero(), sin(radians))
|
||||
Quat::new((radians / _2).cos(), zero(), zero(), radians.sin())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -106,16 +106,16 @@ pub impl<T:Copy + Float> Quat<T> {
|
|||
let xdiv2 = radians_x / _2;
|
||||
let ydiv2 = radians_y / _2;
|
||||
let zdiv2 = radians_z / _2;
|
||||
Quat::new(cos(zdiv2) * cos(xdiv2) * cos(ydiv2) + sin(zdiv2) * sin(xdiv2) * sin(ydiv2),
|
||||
sin(zdiv2) * cos(xdiv2) * cos(ydiv2) - cos(zdiv2) * sin(xdiv2) * sin(ydiv2),
|
||||
cos(zdiv2) * sin(xdiv2) * cos(ydiv2) + sin(zdiv2) * cos(xdiv2) * sin(ydiv2),
|
||||
cos(zdiv2) * cos(xdiv2) * sin(ydiv2) - sin(zdiv2) * sin(xdiv2) * cos(ydiv2))
|
||||
Quat::new(zdiv2.cos() * xdiv2.cos() * ydiv2.cos() + zdiv2.sin() * xdiv2.sin() * ydiv2.sin(),
|
||||
zdiv2.sin() * xdiv2.cos() * ydiv2.cos() - zdiv2.cos() * xdiv2.sin() * ydiv2.sin(),
|
||||
zdiv2.cos() * xdiv2.sin() * ydiv2.cos() + zdiv2.sin() * xdiv2.cos() * ydiv2.sin(),
|
||||
zdiv2.cos() * xdiv2.cos() * ydiv2.sin() - zdiv2.sin() * xdiv2.sin() * ydiv2.cos())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn from_angle_axis(radians: T, axis: &Vec3<T>) -> Quat<T> {
|
||||
let half = radians / num::cast(2);
|
||||
Quat::from_sv(cos(half), axis.mul_t(sin(half)))
|
||||
Quat::from_sv(half.cos(), axis.mul_t(half.sin()))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -318,15 +318,16 @@ pub impl<T:Copy + Float> Quat<T> {
|
|||
if dot > dot_threshold {
|
||||
return self.nlerp(other, amount); // if quaternions are close together use `nlerp`
|
||||
} else {
|
||||
let robust_dot = dot.clamp(-one::<T>(), one()); // stay within the domain of acos()
|
||||
let robust_dot = dot.clamp(&-one::<T>(), &one()); // stay within the domain of acos()
|
||||
|
||||
let theta_0 = acos(robust_dot); // the angle between the quaternions
|
||||
let theta_0 = robust_dot.acos(); // the angle between the quaternions
|
||||
let theta = theta_0 * amount; // the fraction of theta specified by `amount`
|
||||
|
||||
let q = other.sub_q(&self.mul_t(robust_dot))
|
||||
.normalize();
|
||||
|
||||
return self.mul_t(cos(theta)).add_q(&q.mul_t(sin(theta)));
|
||||
return self.mul_t(theta.cos())
|
||||
.add_q(&q.mul_t(theta.sin()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,14 +377,14 @@ impl<T:Copy> Index<uint, T> for Quat<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> Neg<Quat<T>> for Quat<T> {
|
||||
impl<T:Copy + Float + NumAssign + FuzzyEq<T>> Neg<Quat<T>> for Quat<T> {
|
||||
#[inline(always)]
|
||||
fn neg(&self) -> Quat<T> {
|
||||
Quat::new(-self[0], -self[1], -self[2], -self[3])
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> FuzzyEq<T> for Quat<T> {
|
||||
impl<T:Copy + Float + FuzzyEq<T>> FuzzyEq<T> for Quat<T> {
|
||||
#[inline(always)]
|
||||
fn fuzzy_eq(&self, other: &Quat<T>) -> bool {
|
||||
self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON))
|
||||
|
@ -397,46 +398,3 @@ impl<T:Copy + Float> FuzzyEq<T> for Quat<T> {
|
|||
self[3].fuzzy_eq_eps(&other[3], epsilon)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! quat_type(
|
||||
($name:ident <$T:ty, $V:ty>) => (
|
||||
pub impl $name {
|
||||
#[inline(always)] fn new(w: $T, xi: $T, yj: $T, zk: $T) -> $name { Quat::new(w, xi, yj, zk) }
|
||||
#[inline(always)] fn from_sv(s: $T, v: $V) -> $name { Quat::from_sv(s, v) }
|
||||
#[inline(always)] fn identity() -> $name { Quat::identity() }
|
||||
#[inline(always)] fn zero() -> $name { Quat::zero() }
|
||||
|
||||
#[inline(always)] fn from_angle_x(radians: $T) -> $name { Quat::from_angle_x(radians) }
|
||||
#[inline(always)] fn from_angle_y(radians: $T) -> $name { Quat::from_angle_y(radians) }
|
||||
#[inline(always)] fn from_angle_z(radians: $T) -> $name { Quat::from_angle_z(radians) }
|
||||
#[inline(always)] fn from_angle_xyz(radians_x: $T, radians_y: $T, radians_z: $T)
|
||||
-> $name { Quat::from_angle_xyz(radians_x, radians_y, radians_z) }
|
||||
#[inline(always)] fn from_angle_axis(radians: $T, axis: &$V) -> $name { Quat::from_angle_axis(radians, axis) }
|
||||
#[inline(always)] fn from_axes(x: $V, y: $V, z: $V) -> $name { Quat::from_axes(x, y, z) }
|
||||
#[inline(always)] fn look_at(dir: &$V, up: &$V) -> $name { Quat::look_at(dir, up) }
|
||||
|
||||
#[inline(always)] fn dim() -> uint { 4 }
|
||||
#[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() }
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
// GLSL-style type aliases for quaternions. These are not present in the GLSL
|
||||
// specification, but they roughly follow the same nomenclature.
|
||||
|
||||
/// a single-precision floating-point quaternion
|
||||
type quat = Quat<f32>;
|
||||
/// a double-precision floating-point quaternion
|
||||
type dquat = Quat<f64>;
|
||||
|
||||
quat_type!(quat<f32,vec3>)
|
||||
quat_type!(dquat<f64,dvec3>)
|
||||
|
||||
// Rust-style type aliases
|
||||
type Quatf = Quat<float>;
|
||||
type Quatf32 = Quat<f32>;
|
||||
type Quatf64 = Quat<f64>;
|
||||
|
||||
quat_type!(Quatf<float,Vec3f>)
|
||||
quat_type!(Quatf32<f32,Vec3f32>)
|
||||
quat_type!(Quatf64<f64,Vec3f64>)
|
289
src/vec.rs
289
src/vec.rs
|
@ -1,7 +1,8 @@
|
|||
use core::num::Zero::zero;
|
||||
use core::num::One::one;
|
||||
use std::cmp::{FuzzyEq, FUZZY_EPSILON};
|
||||
use numeric::*;
|
||||
|
||||
use num::NumAssign;
|
||||
|
||||
/**
|
||||
* The base generic vector trait.
|
||||
|
@ -496,13 +497,13 @@ macro_rules! zip_vec4(
|
|||
)
|
||||
|
||||
macro_rules! zip_assign(
|
||||
($a:ident[] $method:ident $b:ident[] ..2) => ({ $a.index_mut(0).$method($b[0]); $a.index_mut(1).$method($b[1]); });
|
||||
($a:ident[] $method:ident $b:ident[] ..3) => ({ zip_assign!($a[] $method $b[] ..2); $a.index_mut(2).$method($b[2]); });
|
||||
($a:ident[] $method:ident $b:ident[] ..4) => ({ zip_assign!($a[] $method $b[] ..3); $a.index_mut(3).$method($b[3]); });
|
||||
($a:ident[] $method:ident $b:ident[] ..2) => ({ $a.index_mut(0).$method(&$b[0]); $a.index_mut(1).$method(&$b[1]); });
|
||||
($a:ident[] $method:ident $b:ident[] ..3) => ({ zip_assign!($a[] $method $b[] ..2); $a.index_mut(2).$method(&$b[2]); });
|
||||
($a:ident[] $method:ident $b:ident[] ..4) => ({ zip_assign!($a[] $method $b[] ..3); $a.index_mut(3).$method(&$b[3]); });
|
||||
|
||||
($a:ident[] $method:ident $b:ident ..2) => ({ $a.index_mut(0).$method($b); $a.index_mut(1).$method($b); });
|
||||
($a:ident[] $method:ident $b:ident ..3) => ({ zip_assign!($a[] $method $b ..2); $a.index_mut(2).$method($b); });
|
||||
($a:ident[] $method:ident $b:ident ..4) => ({ zip_assign!($a[] $method $b ..3); $a.index_mut(3).$method($b); });
|
||||
($a:ident[] $method:ident $b:ident ..2) => ({ $a.index_mut(0).$method(&$b); $a.index_mut(1).$method(&$b); });
|
||||
($a:ident[] $method:ident $b:ident ..3) => ({ zip_assign!($a[] $method $b ..2); $a.index_mut(2).$method(&$b); });
|
||||
($a:ident[] $method:ident $b:ident ..4) => ({ zip_assign!($a[] $method $b ..3); $a.index_mut(3).$method(&$b); });
|
||||
)
|
||||
|
||||
/**
|
||||
|
@ -561,7 +562,7 @@ impl<T:Copy + Eq> Index<uint, T> for Vec2<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> NumVec<T> for Vec2<T> {
|
||||
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec2<T> {
|
||||
#[inline(always)]
|
||||
fn identity() -> Vec2<T> {
|
||||
BaseVec2::new(one::<T>(), one::<T>())
|
||||
|
@ -651,14 +652,14 @@ impl<T:Copy + Number> NumVec<T> for Vec2<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> Neg<Vec2<T>> for Vec2<T> {
|
||||
impl<T:Copy + Num> Neg<Vec2<T>> for Vec2<T> {
|
||||
#[inline(always)]
|
||||
fn neg(&self) -> Vec2<T> {
|
||||
BaseVec2::new(-self[0], -self[1])
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> NumVec2<T> for Vec2<T> {
|
||||
impl<T:Copy + Num> NumVec2<T> for Vec2<T> {
|
||||
#[inline(always)]
|
||||
fn unit_x() -> Vec2<T> {
|
||||
BaseVec2::new(one::<T>(), zero::<T>())
|
||||
|
@ -675,14 +676,14 @@ impl<T:Copy + Number> NumVec2<T> for Vec2<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> ToHomogeneous<Vec3<T>> for Vec2<T> {
|
||||
impl<T:Copy + Num> ToHomogeneous<Vec3<T>> for Vec2<T> {
|
||||
#[inline(always)]
|
||||
fn to_homogeneous(&self) -> Vec3<T> {
|
||||
BaseVec3::new(self.x, self.y, zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> AffineVec<T> for Vec2<T> {
|
||||
impl<T:Copy + Real + NumAssign> AffineVec<T> for Vec2<T> {
|
||||
#[inline(always)]
|
||||
fn length2(&self) -> T {
|
||||
self.dot(self)
|
||||
|
@ -705,7 +706,7 @@ impl<T:Copy + Float> AffineVec<T> for Vec2<T> {
|
|||
|
||||
#[inline(always)]
|
||||
fn angle(&self, other: &Vec2<T>) -> T {
|
||||
atan2(self.perp_dot(other), self.dot(other))
|
||||
self.perp_dot(other).atan2(self.dot(other))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -741,7 +742,7 @@ impl<T:Copy + Float> AffineVec<T> for Vec2<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float + FuzzyEq<T>> FuzzyEq<T> for Vec2<T> {
|
||||
impl<T:Copy + NumCast + Eq + FuzzyEq<T>> FuzzyEq<T> for Vec2<T> {
|
||||
#[inline(always)]
|
||||
fn fuzzy_eq(&self, other: &Vec2<T>) -> bool {
|
||||
self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON))
|
||||
|
@ -805,83 +806,6 @@ impl BoolVec for Vec2<bool> {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! vec2_type(
|
||||
($name:ident <bool>) => (
|
||||
pub impl $name {
|
||||
#[inline(always)] fn new(x: bool, y: bool) -> $name { BaseVec2::new(x, y) }
|
||||
#[inline(always)] fn from_value(v: bool) -> $name { BaseVec::from_value(v) }
|
||||
|
||||
#[inline(always)] fn dim() -> uint { 2 }
|
||||
#[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() }
|
||||
}
|
||||
);
|
||||
($name:ident <$T:ty>) => (
|
||||
pub impl $name {
|
||||
#[inline(always)] fn new(x: $T, y: $T) -> $name { BaseVec2::new(x, y) }
|
||||
#[inline(always)] fn from_value(v: $T) -> $name { BaseVec::from_value(v) }
|
||||
#[inline(always)] fn identity() -> $name { NumVec::identity() }
|
||||
#[inline(always)] fn zero() -> $name { NumVec::zero() }
|
||||
|
||||
#[inline(always)] fn unit_x() -> $name { NumVec2::unit_x() }
|
||||
#[inline(always)] fn unit_y() -> $name { NumVec2::unit_y() }
|
||||
|
||||
#[inline(always)] fn dim() -> uint { 2 }
|
||||
#[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() }
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
// GLSL-style type aliases, corresponding to Section 4.1.5 of the [GLSL 4.30.6 specification]
|
||||
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
||||
|
||||
// a two-component single-precision floating-point vector
|
||||
pub type vec2 = Vec2<f32>;
|
||||
// a two-component double-precision floating-point vector
|
||||
pub type dvec2 = Vec2<f64>;
|
||||
// a two-component Boolean vector
|
||||
pub type bvec2 = Vec2<bool>;
|
||||
// a two-component signed integer vector
|
||||
pub type ivec2 = Vec2<i32>;
|
||||
// a two-component unsigned integer vector
|
||||
pub type uvec2 = Vec2<u32>;
|
||||
|
||||
vec2_type!(vec2<f32>)
|
||||
vec2_type!(dvec2<f64>)
|
||||
vec2_type!(bvec2<bool>)
|
||||
vec2_type!(ivec2<i32>)
|
||||
vec2_type!(uvec2<u32>)
|
||||
|
||||
// Rust-style type aliases
|
||||
pub type Vec2f = Vec2<float>;
|
||||
pub type Vec2f32 = Vec2<f32>;
|
||||
pub type Vec2f64 = Vec2<f64>;
|
||||
pub type Vec2i = Vec2<int>;
|
||||
pub type Vec2i8 = Vec2<i8>;
|
||||
pub type Vec2i16 = Vec2<i16>;
|
||||
pub type Vec2i32 = Vec2<i32>;
|
||||
pub type Vec2i64 = Vec2<i64>;
|
||||
pub type Vec2u = Vec2<uint>;
|
||||
pub type Vec2u8 = Vec2<u8>;
|
||||
pub type Vec2u16 = Vec2<u16>;
|
||||
pub type Vec2u32 = Vec2<u32>;
|
||||
pub type Vec2u64 = Vec2<u64>;
|
||||
pub type Vec2b = Vec2<bool>;
|
||||
|
||||
vec2_type!(Vec2f<float>)
|
||||
vec2_type!(Vec2f32<f32>)
|
||||
vec2_type!(Vec2f64<f64>)
|
||||
vec2_type!(Vec2i<int>)
|
||||
vec2_type!(Vec2i8<i8>)
|
||||
vec2_type!(Vec2i16<i16>)
|
||||
vec2_type!(Vec2i32<i32>)
|
||||
vec2_type!(Vec2i64<i64>)
|
||||
vec2_type!(Vec2u<uint>)
|
||||
vec2_type!(Vec2u8<u8>)
|
||||
vec2_type!(Vec2u16<u16>)
|
||||
vec2_type!(Vec2u32<u32>)
|
||||
vec2_type!(Vec2u64<u64>)
|
||||
vec2_type!(Vec2b<bool>)
|
||||
|
||||
/**
|
||||
* A 3-dimensional vector
|
||||
*
|
||||
|
@ -940,7 +864,7 @@ impl<T:Copy + Eq> Index<uint, T> for Vec3<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> NumVec<T> for Vec3<T> {
|
||||
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec3<T> {
|
||||
#[inline(always)]
|
||||
fn identity() -> Vec3<T> {
|
||||
BaseVec3::new(one::<T>(), one::<T>(), one::<T>())
|
||||
|
@ -1033,14 +957,14 @@ impl<T:Copy + Number> NumVec<T> for Vec3<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> Neg<Vec3<T>> for Vec3<T> {
|
||||
impl<T:Copy + Num> Neg<Vec3<T>> for Vec3<T> {
|
||||
#[inline(always)]
|
||||
fn neg(&self) -> Vec3<T> {
|
||||
BaseVec3::new(-self[0], -self[1], -self[2])
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> NumVec3<T> for Vec3<T> {
|
||||
impl<T:Copy + Num> NumVec3<T> for Vec3<T> {
|
||||
#[inline(always)]
|
||||
fn unit_x() -> Vec3<T> {
|
||||
BaseVec3::new(one::<T>(), zero::<T>(), zero::<T>())
|
||||
|
@ -1069,14 +993,14 @@ impl<T:Copy + Number> NumVec3<T> for Vec3<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> ToHomogeneous<Vec4<T>> for Vec3<T> {
|
||||
impl<T:Copy + Num> ToHomogeneous<Vec4<T>> for Vec3<T> {
|
||||
#[inline(always)]
|
||||
fn to_homogeneous(&self) -> Vec4<T> {
|
||||
BaseVec4::new(self.x, self.y, self.z, zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> AffineVec<T> for Vec3<T> {
|
||||
impl<T:Copy + Real + NumAssign> AffineVec<T> for Vec3<T> {
|
||||
#[inline(always)]
|
||||
fn length2(&self) -> T {
|
||||
self.dot(self)
|
||||
|
@ -1099,7 +1023,7 @@ impl<T:Copy + Float> AffineVec<T> for Vec3<T> {
|
|||
|
||||
#[inline(always)]
|
||||
fn angle(&self, other: &Vec3<T>) -> T {
|
||||
atan2(self.cross(other).length(), self.dot(other))
|
||||
self.cross(other).length().atan2(self.dot(other))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -1135,7 +1059,7 @@ impl<T:Copy + Float> AffineVec<T> for Vec3<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float + FuzzyEq<T>> FuzzyEq<T> for Vec3<T> {
|
||||
impl<T:Copy + NumCast + Eq + FuzzyEq<T>> FuzzyEq<T> for Vec3<T> {
|
||||
#[inline(always)]
|
||||
fn fuzzy_eq(&self, other: &Vec3<T>) -> bool {
|
||||
self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON))
|
||||
|
@ -1200,84 +1124,6 @@ impl BoolVec for Vec3<bool> {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! vec3_type(
|
||||
($name:ident <bool>) => (
|
||||
pub impl $name {
|
||||
#[inline(always)] fn new(x: bool, y: bool, z: bool) -> $name { BaseVec3::new(x, y, z) }
|
||||
#[inline(always)] fn from_value(v: bool) -> $name { BaseVec::from_value(v) }
|
||||
|
||||
#[inline(always)] fn dim() -> uint { 3 }
|
||||
#[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() }
|
||||
}
|
||||
);
|
||||
($name:ident <$T:ty>) => (
|
||||
pub impl $name {
|
||||
#[inline(always)] fn new(x: $T, y: $T, z: $T) -> $name { BaseVec3::new(x, y, z) }
|
||||
#[inline(always)] fn from_value(v: $T) -> $name { BaseVec::from_value(v) }
|
||||
#[inline(always)] fn identity() -> $name { NumVec::identity() }
|
||||
#[inline(always)] fn zero() -> $name { NumVec::zero() }
|
||||
|
||||
#[inline(always)] fn unit_x() -> $name { NumVec3::unit_x() }
|
||||
#[inline(always)] fn unit_y() -> $name { NumVec3::unit_y() }
|
||||
#[inline(always)] fn unit_z() -> $name { NumVec3::unit_z() }
|
||||
|
||||
#[inline(always)] fn dim() -> uint { 3 }
|
||||
#[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() }
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
// GLSL-style type aliases, corresponding to Section 4.1.5 of the [GLSL 4.30.6 specification]
|
||||
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
||||
|
||||
// a three-component single-precision floating-point vector
|
||||
pub type vec3 = Vec3<f32>;
|
||||
// a three-component double-precision floating-point vector
|
||||
pub type dvec3 = Vec3<f64>;
|
||||
// a three-component Boolean vector
|
||||
pub type bvec3 = Vec3<bool>;
|
||||
// a three-component signed integer vector
|
||||
pub type ivec3 = Vec3<i32>;
|
||||
// a three-component unsigned integer vector
|
||||
pub type uvec3 = Vec3<u32>;
|
||||
|
||||
vec3_type!(vec3<f32>)
|
||||
vec3_type!(dvec3<f64>)
|
||||
vec3_type!(bvec3<bool>)
|
||||
vec3_type!(ivec3<i32>)
|
||||
vec3_type!(uvec3<u32>)
|
||||
|
||||
// Rust-style type aliases
|
||||
pub type Vec3f = Vec3<float>;
|
||||
pub type Vec3f32 = Vec3<f32>;
|
||||
pub type Vec3f64 = Vec3<f64>;
|
||||
pub type Vec3i = Vec3<int>;
|
||||
pub type Vec3i8 = Vec3<i8>;
|
||||
pub type Vec3i16 = Vec3<i16>;
|
||||
pub type Vec3i32 = Vec3<i32>;
|
||||
pub type Vec3i64 = Vec3<i64>;
|
||||
pub type Vec3u = Vec3<uint>;
|
||||
pub type Vec3u8 = Vec3<u8>;
|
||||
pub type Vec3u16 = Vec3<u16>;
|
||||
pub type Vec3u32 = Vec3<u32>;
|
||||
pub type Vec3u64 = Vec3<u64>;
|
||||
pub type Vec3b = Vec3<bool>;
|
||||
|
||||
vec3_type!(Vec3f<float>)
|
||||
vec3_type!(Vec3f32<f32>)
|
||||
vec3_type!(Vec3f64<f64>)
|
||||
vec3_type!(Vec3i<int>)
|
||||
vec3_type!(Vec3i8<i8>)
|
||||
vec3_type!(Vec3i16<i16>)
|
||||
vec3_type!(Vec3i32<i32>)
|
||||
vec3_type!(Vec3i64<i64>)
|
||||
vec3_type!(Vec3u<uint>)
|
||||
vec3_type!(Vec3u8<u8>)
|
||||
vec3_type!(Vec3u16<u16>)
|
||||
vec3_type!(Vec3u32<u32>)
|
||||
vec3_type!(Vec3u64<u64>)
|
||||
vec3_type!(Vec3b<bool>)
|
||||
|
||||
/**
|
||||
* A 4-dimensional vector
|
||||
*
|
||||
|
@ -1338,7 +1184,7 @@ impl<T:Copy + Eq> Index<uint, T> for Vec4<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> NumVec<T> for Vec4<T> {
|
||||
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec4<T> {
|
||||
#[inline(always)]
|
||||
fn identity() -> Vec4<T> {
|
||||
BaseVec4::new(one::<T>(), one::<T>(), one::<T>(), one::<T>())
|
||||
|
@ -1434,14 +1280,14 @@ impl<T:Copy + Number> NumVec<T> for Vec4<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> Neg<Vec4<T>> for Vec4<T> {
|
||||
impl<T:Copy + Num> Neg<Vec4<T>> for Vec4<T> {
|
||||
#[inline(always)]
|
||||
fn neg(&self) -> Vec4<T> {
|
||||
BaseVec4::new(-self[0], -self[1], -self[2], -self[3])
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Number> NumVec4<T> for Vec4<T> {
|
||||
impl<T:Copy + Num> NumVec4<T> for Vec4<T> {
|
||||
#[inline(always)]
|
||||
fn unit_x() -> Vec4<T> {
|
||||
BaseVec4::new(one::<T>(), zero::<T>(), zero::<T>(), zero::<T>())
|
||||
|
@ -1463,7 +1309,7 @@ impl<T:Copy + Number> NumVec4<T> for Vec4<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float> AffineVec<T> for Vec4<T> {
|
||||
impl<T:Copy + Real + NumAssign> AffineVec<T> for Vec4<T> {
|
||||
#[inline(always)]
|
||||
fn length2(&self) -> T {
|
||||
self.dot(self)
|
||||
|
@ -1486,7 +1332,7 @@ impl<T:Copy + Float> AffineVec<T> for Vec4<T> {
|
|||
|
||||
#[inline(always)]
|
||||
fn angle(&self, other: &Vec4<T>) -> T {
|
||||
acos(self.dot(other) / (self.length() * other.length()))
|
||||
(self.dot(other) / (self.length() * other.length())).acos()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -1522,7 +1368,7 @@ impl<T:Copy + Float> AffineVec<T> for Vec4<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Float + FuzzyEq<T>> FuzzyEq<T> for Vec4<T> {
|
||||
impl<T:Copy + NumCast + Eq + FuzzyEq<T>> FuzzyEq<T> for Vec4<T> {
|
||||
#[inline(always)]
|
||||
fn fuzzy_eq(&self, other: &Vec4<T>) -> bool {
|
||||
self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON))
|
||||
|
@ -1587,82 +1433,3 @@ impl BoolVec for Vec4<bool> {
|
|||
BaseVec4::new(!self[0], !self[1], !self[2], !self[3])
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! vec4_type(
|
||||
($name:ident <bool>) => (
|
||||
pub impl $name {
|
||||
#[inline(always)] fn new(x: bool, y: bool, z: bool, w: bool) -> $name { BaseVec4::new(x, y, z, w) }
|
||||
#[inline(always)] fn from_value(v: bool) -> $name { BaseVec::from_value(v) }
|
||||
|
||||
#[inline(always)] fn dim() -> uint { 4 }
|
||||
#[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() }
|
||||
}
|
||||
);
|
||||
($name:ident <$T:ty>) => (
|
||||
pub impl $name {
|
||||
#[inline(always)] fn new(x: $T, y: $T, z: $T, w: $T) -> $name { BaseVec4::new(x, y, z, w) }
|
||||
#[inline(always)] fn from_value(v: $T) -> $name { BaseVec::from_value(v) }
|
||||
#[inline(always)] fn identity() -> $name { NumVec::identity() }
|
||||
#[inline(always)] fn zero() -> $name { NumVec::zero() }
|
||||
|
||||
#[inline(always)] fn unit_x() -> $name { NumVec4::unit_x() }
|
||||
#[inline(always)] fn unit_y() -> $name { NumVec4::unit_y() }
|
||||
#[inline(always)] fn unit_z() -> $name { NumVec4::unit_z() }
|
||||
#[inline(always)] fn unit_w() -> $name { NumVec4::unit_w() }
|
||||
|
||||
#[inline(always)] fn dim() -> uint { 4 }
|
||||
#[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() }
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
// GLSL-style type aliases, corresponding to Section 4.1.5 of the [GLSL 4.30.6 specification]
|
||||
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
||||
|
||||
// a four-component single-precision floating-point vector
|
||||
pub type vec4 = Vec4<f32>;
|
||||
// a four-component double-precision floating-point vector
|
||||
pub type dvec4 = Vec4<f64>;
|
||||
// a four-component Boolean vector
|
||||
pub type bvec4 = Vec4<bool>;
|
||||
// a four-component signed integer vector
|
||||
pub type ivec4 = Vec4<i32>;
|
||||
// a four-component unsigned integer vector
|
||||
pub type uvec4 = Vec4<u32>;
|
||||
|
||||
vec4_type!(vec4<f32>)
|
||||
vec4_type!(dvec4<f64>)
|
||||
vec4_type!(bvec4<bool>)
|
||||
vec4_type!(ivec4<i32>)
|
||||
vec4_type!(uvec4<u32>)
|
||||
|
||||
// Rust-style type aliases
|
||||
pub type Vec4f = Vec4<float>;
|
||||
pub type Vec4f32 = Vec4<f32>;
|
||||
pub type Vec4f64 = Vec4<f64>;
|
||||
pub type Vec4i = Vec4<int>;
|
||||
pub type Vec4i8 = Vec4<i8>;
|
||||
pub type Vec4i16 = Vec4<i16>;
|
||||
pub type Vec4i32 = Vec4<i32>;
|
||||
pub type Vec4i64 = Vec4<i64>;
|
||||
pub type Vec4u = Vec4<uint>;
|
||||
pub type Vec4u8 = Vec4<u8>;
|
||||
pub type Vec4u16 = Vec4<u16>;
|
||||
pub type Vec4u32 = Vec4<u32>;
|
||||
pub type Vec4u64 = Vec4<u64>;
|
||||
pub type Vec4b = Vec4<bool>;
|
||||
|
||||
vec4_type!(Vec4f<float>)
|
||||
vec4_type!(Vec4f32<f32>)
|
||||
vec4_type!(Vec4f64<f64>)
|
||||
vec4_type!(Vec4i<int>)
|
||||
vec4_type!(Vec4i8<i8>)
|
||||
vec4_type!(Vec4i16<i16>)
|
||||
vec4_type!(Vec4i32<i32>)
|
||||
vec4_type!(Vec4i64<i64>)
|
||||
vec4_type!(Vec4u<uint>)
|
||||
vec4_type!(Vec4u8<u8>)
|
||||
vec4_type!(Vec4u16<u16>)
|
||||
vec4_type!(Vec4u32<u32>)
|
||||
vec4_type!(Vec4u64<u64>)
|
||||
vec4_type!(Vec4b<bool>)
|
Loading…
Reference in a new issue