Use the new core::num traits and remove numeric dependency

This commit is contained in:
Brendan Zabarauskas 2013-05-06 13:52:22 +10:00
parent a6acab93c3
commit 0cb3314bf8
9 changed files with 139 additions and 508 deletions

View file

@ -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)

View file

@ -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
View file

View file

@ -9,7 +9,8 @@
#[crate_type = "lib"];
extern mod std;
extern mod numeric;
pub mod num;
pub mod mat;
pub mod quat;

View file

@ -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,15 +681,15 @@ 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] }
#[inline(always)]
fn row(&self, i: uint) -> Vec3<T> {
BaseVec3::new(self[0][i],
self[1][i],
self[2][i])
self[1][i],
self[2][i])
}
/**
@ -808,8 +767,8 @@ impl<T:Copy + Float> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)]
fn mul_v(&self, vec: &Vec3<T>) -> Vec3<T> {
BaseVec3::new(self.row(0).dot(vec),
self.row(1).dot(vec),
self.row(2).dot(vec))
self.row(1).dot(vec),
self.row(2).dot(vec))
}
#[inline(always)]
@ -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,28 +1412,26 @@ 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);
I.swap_cols(i1, j);
// Swap columns i1 and j in A and I to
// put pivot on diagonal
A.swap_cols(i1, j);
I.swap_cols(i1, j);
// Scale col j to have a unit diagonal
I.col_mut(j).div_self_t(A[j][j]);
A.col_mut(j).div_self_t(A[j][j]);
// Scale col j to have a unit diagonal
I.col_mut(j).div_self_t(A[j][j]);
A.col_mut(j).div_self_t(A[j][j]);
// Eliminate off-diagonal elems in col j of A,
// doing identical ops to I
for uint::range(0, 4) |i| {
if i != j {
I.col_mut(i).sub_self_v(&I[j].mul_t(A[i][j]));
A.col_mut(i).sub_self_v(&A[j].mul_t(A[i][j]));
}
// Eliminate off-diagonal elems in col j of A,
// doing identical ops to I
for uint::range(0, 4) |i| {
if i != j {
I.col_mut(i).sub_self_v(&I[j].mul_t(A[i][j]));
A.col_mut(i).sub_self_v(&A[j].mul_t(A[i][j]));
}
}
}
@ -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
View 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)

View file

@ -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);

View file

@ -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>)

View file

@ -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>)