cgmath/src/vec.rs

1424 lines
39 KiB
Rust
Raw Normal View History

// Copyright 2013 The Lmath 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::cast::transmute;
use std::cmp::ApproxEq;
use std::num::{Zero, One};
use num::NumAssign;
2012-12-13 13:01:42 +00:00
2013-06-01 02:57:29 +00:00
/// The base generic vector trait.
///
/// # Type parameters
///
/// - `T`: The type of the components. This is intended to support boolean,
/// integer, unsigned integer, and floating point types.
pub trait BaseVec<T>: Eq {
2013-06-01 02:57:29 +00:00
/// The component of the vector at the index `i`
fn index<'a>(&'a self, i: uint) -> &'a T;
2013-06-01 02:57:29 +00:00
/// Construct the vector from a single value, copying it to each component
2013-03-28 10:37:25 +00:00
fn from_value(value: T) -> Self;
2013-06-01 02:57:29 +00:00
/// A pointer to the first component of the vector
2013-03-28 10:35:51 +00:00
fn to_ptr(&self) -> *T;
2013-05-07 15:00:06 +00:00
2013-06-01 02:57:29 +00:00
/// Get a mutable reference to the component at `i`
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T;
2013-06-01 02:57:29 +00:00
/// Swap two components of the vector in place
2012-12-04 07:58:03 +00:00
fn swap(&mut self, a: uint, b: uint);
}
2013-06-01 02:57:29 +00:00
/// A generic 2-dimensional vector
2013-04-02 05:12:13 +00:00
pub trait BaseVec2<T>: BaseVec<T> {
2013-03-28 10:37:25 +00:00
fn new(x: T, y: T) -> Self;
2012-11-21 04:08:36 +00:00
}
2013-06-01 02:57:29 +00:00
/// A generic 3-dimensional vector
2013-04-02 05:12:13 +00:00
pub trait BaseVec3<T>: BaseVec<T> {
2013-03-28 10:37:25 +00:00
fn new(x: T, y: T, z: T) -> Self;
2012-11-21 04:08:36 +00:00
}
2013-06-01 02:57:29 +00:00
/// A generic 4-dimensional vector
2013-04-02 05:12:13 +00:00
pub trait BaseVec4<T>: BaseVec<T> {
2013-03-28 10:37:25 +00:00
fn new(x: T, y: T, z: T, w: T) -> Self;
2012-11-21 04:08:36 +00:00
}
2013-06-01 02:57:29 +00:00
/// A vector with numeric components
2013-04-02 05:12:13 +00:00
pub trait NumVec<T>: BaseVec<T> + Neg<Self> {
2013-06-01 02:57:29 +00:00
/// The standard basis vector
///
/// # Return value
///
/// A vector with each component set to one
2013-03-28 10:37:25 +00:00
fn identity() -> Self;
2013-06-01 02:57:29 +00:00
/// The null vector
///
/// # Return value
///
/// A vector with each component set to zero
2013-03-28 10:37:25 +00:00
fn zero() -> Self;
2013-06-01 02:57:29 +00:00
/// True if the vector is equal to zero
2013-03-28 10:35:51 +00:00
fn is_zero(&self) -> bool;
2013-06-01 02:57:29 +00:00
/// The scalar multiplication of the vector and `value`
2013-03-28 10:35:51 +00:00
fn mul_t(&self, value: T) -> Self;
2013-06-01 02:57:29 +00:00
/// The scalar division of the vector and `value`
2013-03-28 10:35:51 +00:00
fn div_t(&self, value: T) -> Self;
2013-06-01 02:57:29 +00:00
/// Component-wise vector addition
2013-03-28 10:35:51 +00:00
fn add_v(&self, other: &Self) -> Self;
2013-06-01 02:57:29 +00:00
/// Component-wise vector subtraction
2013-03-28 10:35:51 +00:00
fn sub_v(&self, other: &Self) -> Self;
2013-06-01 02:57:29 +00:00
/// Component-wise vector multiplication
2013-03-28 10:35:51 +00:00
fn mul_v(&self, other: &Self) -> Self;
2013-06-01 02:57:29 +00:00
/// Component-wise vector division
2013-03-28 10:35:51 +00:00
fn div_v(&self, other: &Self) -> Self;
2013-06-01 02:57:29 +00:00
/// The dot product of the vector and `other`
2013-03-28 10:35:51 +00:00
fn dot(&self, other: &Self) -> T;
2013-05-07 15:00:06 +00:00
2013-06-01 02:57:29 +00:00
/// Negate the vector
fn neg_self(&mut self);
2013-06-01 02:57:29 +00:00
/// Multiply the vector by a scalar
fn mul_self_t(&mut self, value: T);
2013-06-01 02:57:29 +00:00
/// Divide the vector by a scalar
fn div_self_t(&mut self, value: T);
2013-06-01 02:57:29 +00:00
/// Set the vector to the component-wise vector sum
2013-01-29 10:23:22 +00:00
fn add_self_v(&mut self, other: &Self);
2013-06-01 02:57:29 +00:00
/// Set the vector to the component-wise vector difference
2013-01-29 10:23:22 +00:00
fn sub_self_v(&mut self, other: &Self);
2013-06-01 02:57:29 +00:00
/// Set the vector to the component-wise vector product
2013-01-29 10:23:22 +00:00
fn mul_self_v(&mut self, other: &Self);
2013-06-01 02:57:29 +00:00
/// Set the vector to the component-wise vector quotient
2013-01-29 10:23:22 +00:00
fn div_self_v(&mut self, other: &Self);
}
2013-06-01 02:57:29 +00:00
/// A 2-dimensional vector with numeric components
2013-04-02 05:12:13 +00:00
pub trait NumVec2<T>: NumVec<T> {
fn unit_x() -> Self;
fn unit_y() -> Self;
2013-06-01 02:57:29 +00:00
/// The perp dot product of the vector and `other`
fn perp_dot(&self, other: &Self) -> T;
}
2013-06-01 02:57:29 +00:00
/// A 3-dimensional vector with numeric components
2013-04-02 05:12:13 +00:00
pub trait NumVec3<T>: NumVec<T> {
fn unit_x() -> Self;
fn unit_y() -> Self;
fn unit_z() -> Self;
2013-06-01 02:57:29 +00:00
/// The cross product of the vector and `other`
fn cross(&self, other: &Self) -> Self;
2013-05-07 15:00:06 +00:00
2013-06-01 02:57:29 +00:00
/// Set to the cross product of the vector and `other`
2013-01-29 10:23:22 +00:00
fn cross_self(&mut self, other: &Self);
2012-12-04 15:34:41 +00:00
}
2013-06-01 02:57:29 +00:00
/// A 4-dimensional vector with numeric components
2013-04-02 05:12:13 +00:00
pub trait NumVec4<T>: NumVec<T> {
fn unit_x() -> Self;
fn unit_y() -> Self;
fn unit_z() -> Self;
fn unit_w() -> Self;
}
2013-01-02 06:59:24 +00:00
pub trait ToHomogeneous<H> {
2013-06-01 02:57:29 +00:00
/// Convert to a homogenous coordinate
2013-03-28 10:35:51 +00:00
fn to_homogeneous(&self) -> H;
2013-01-02 06:59:24 +00:00
}
2013-06-01 02:57:29 +00:00
/// A Euclidean (or Affine) vector
///
/// # Type parameters
///
/// - `T`: The type of the components. This should be a floating point type.
2013-04-02 05:12:13 +00:00
pub trait AffineVec<T>: NumVec<T> {
2013-06-01 02:57:29 +00:00
/// The squared length of the vector. This is useful for comparisons where
/// the exact length does not need to be calculated.
2013-03-28 10:35:51 +00:00
fn length2(&self) -> T;
2013-06-01 02:57:29 +00:00
/// The length of the vector
///
/// # Performance notes
///
/// For instances where the exact length of the vector does not need to be
/// known, for example for quaternion-quaternion length comparisons,
/// it is advisable to use the `length2` method instead.
2013-03-28 10:35:51 +00:00
fn length(&self) -> T;
2013-06-01 02:57:29 +00:00
/// The squared distance between the vector and `other`.
2013-03-28 10:35:51 +00:00
fn distance2(&self, other: &Self) -> T;
2013-06-01 02:57:29 +00:00
/// The distance between the vector and `other`
2013-03-28 10:35:51 +00:00
fn distance(&self, other: &Self) -> T;
2013-06-01 02:57:29 +00:00
/// The angle between the vector and `other` in radians
2013-03-28 10:35:51 +00:00
fn angle(&self, other: &Self) -> T;
2013-06-01 02:57:29 +00:00
/// The normalized vector
2013-03-28 10:35:51 +00:00
fn normalize(&self) -> Self;
2013-06-01 02:57:29 +00:00
/// Set the length of the vector whilst preserving the direction
2013-03-28 10:35:51 +00:00
fn normalize_to(&self, length: T) -> Self;
2013-06-01 02:57:29 +00:00
/// Linearly intoperlate between the vector and `other`
///
/// # Return value
///
/// The intoperlated vector
2013-03-28 10:35:51 +00:00
fn lerp(&self, other: &Self, amount: T) -> Self;
2013-05-07 15:00:06 +00:00
2013-06-01 02:57:29 +00:00
/// Normalize the vector
fn normalize_self(&mut self);
2013-06-01 02:57:29 +00:00
/// Set the vector to a specified length whilst preserving the direction
fn normalize_self_to(&mut self, length: T);
2013-06-01 02:57:29 +00:00
/// Linearly intoperlate the vector towards `other`
2013-01-29 10:23:22 +00:00
fn lerp_self(&mut self, other: &Self, amount: T);
}
2013-06-01 02:57:29 +00:00
/// Component-wise vector comparison methods
///
/// The methods contained in this trait correspond to the relational functions
/// mentioned in Section 8.7 of the [GLSL 4.30.6 specification]
/// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
2013-04-02 05:12:13 +00:00
pub trait OrdVec<T, BoolVec>: BaseVec<T> {
2013-06-01 02:57:29 +00:00
/// Component-wise compare of `self < other`
2013-03-28 10:35:51 +00:00
fn less_than(&self, other: &Self) -> BoolVec;
2013-06-01 02:57:29 +00:00
/// Component-wise compare of `self <= other`
2013-03-28 10:35:51 +00:00
fn less_than_equal(&self, other: &Self) -> BoolVec;
2013-06-01 02:57:29 +00:00
/// Component-wise compare of `self > other`
2013-03-28 10:35:51 +00:00
fn greater_than(&self, other: &Self) -> BoolVec;
2013-06-01 02:57:29 +00:00
/// Component-wise compare of `self >= other`
2013-03-28 10:35:51 +00:00
fn greater_than_equal(&self, other: &Self) -> BoolVec;
}
2013-06-01 02:57:29 +00:00
/// Component-wise equality comparison methods
///
/// The methods contained in this trait correspond to the relational functions
/// mentioned in Section 8.7 of the [GLSL 4.30.6 specification]
/// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
2013-04-02 05:12:13 +00:00
pub trait EqVec<T, BoolVec>: BaseVec<T> {
2013-06-01 02:57:29 +00:00
/// Component-wise compare of `self == other`
2013-03-28 10:35:51 +00:00
fn equal(&self, other: &Self) -> BoolVec;
2013-06-01 02:57:29 +00:00
/// Component-wise compare of `self != other`
2013-03-28 10:35:51 +00:00
fn not_equal(&self, other: &Self) -> BoolVec;
}
2013-06-01 02:57:29 +00:00
/// A vector with boolean components
///
/// The methods contained in this trait correspond to the relational functions
/// mentioned in Section 8.7 of the [GLSL 4.30.6 specification]
/// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
2013-04-02 05:12:13 +00:00
pub trait BoolVec: BaseVec<bool> {
2013-06-01 02:57:29 +00:00
/// `true` if of any component is `true`
2013-03-28 10:35:51 +00:00
fn any(&self) -> bool;
2013-06-01 02:57:29 +00:00
/// `true` only if all components are `true`
2013-03-28 10:35:51 +00:00
fn all(&self) -> bool;
2013-06-01 02:57:29 +00:00
/// the component-wise logical complement
2013-03-28 10:35:51 +00:00
fn not(&self) -> Self;
2013-02-09 22:42:06 +00:00
}
2013-04-02 05:12:13 +00:00
pub trait TrigVec<T>: BaseVec<T> {
2013-03-28 10:35:51 +00:00
fn radians(&self) -> Self;
fn degrees(&self) -> Self;
2013-02-09 22:42:06 +00:00
// Triganometric functions
2013-03-28 10:35:51 +00:00
fn sin(&self) -> Self;
fn cos(&self) -> Self;
fn tan(&self) -> Self;
2013-02-09 22:42:06 +00:00
// Inverse triganometric functions
2013-03-28 10:35:51 +00:00
fn asin(&self) -> Self;
fn acos(&self) -> Self;
fn atan(&self) -> Self;
fn atan2(&self, other: Self) -> Self;
2013-02-09 22:42:06 +00:00
// Hyperbolic triganometric functions
2013-03-28 10:35:51 +00:00
fn sinh(&self) -> Self;
fn cosh(&self) -> Self;
fn tanh(&self) -> Self;
// fn asinh() -> Self;
// fn acosh() -> Self;
// fn atanh() -> Self;
2013-02-09 22:42:06 +00:00
}
2013-04-02 05:12:13 +00:00
pub trait ExpVec<T>: BaseVec<T> {
2013-02-09 22:42:06 +00:00
// Exponential functions
2013-03-28 10:35:51 +00:00
fn pow_t(&self, n: Self) -> Self;
fn pow_v(&self, n: T) -> Self;
fn exp(&self) -> Self;
fn exp2(&self) -> Self;
fn ln(&self) -> Self;
fn ln2(&self) -> Self;
fn sqrt(&self) -> Self;
fn inv_sqrt(&self) -> Self;
2013-02-09 22:42:06 +00:00
}
2013-04-02 05:12:13 +00:00
pub trait ApproxVec<T>: BaseVec<T> {
2013-02-09 22:42:06 +00:00
// Whole-number approximation functions
2013-03-28 10:35:51 +00:00
fn floor(&self) -> Self;
fn trunc(&self) -> Self;
fn round(&self) -> Self;
// fn round_even(&self) -> Self;
fn ceil(&self) -> Self;
fn fract(&self) -> Self;
2013-02-09 22:42:06 +00:00
}
2013-04-02 05:12:13 +00:00
pub trait SignedVec<T,BV>: BaseVec<T> {
2013-03-28 10:35:51 +00:00
fn is_positive(&self) -> BV;
fn is_negative(&self) -> BV;
fn is_nonpositive(&self) -> BV;
fn is_nonnegative(&self) -> BV;
fn abs(&self) -> Self;
fn sign(&self) -> Self;
fn copysign(&self, other: Self) -> Self;
2013-02-09 22:42:06 +00:00
}
2013-04-02 05:12:13 +00:00
pub trait ExtentVec<T>: BaseVec<T> {
2013-03-28 10:35:51 +00:00
fn min_v(&self, other: &Self) -> Self;
fn max_v(&self, other: &Self) -> Self;
fn clamp_v(&self, mn: &Self, mx: &Self) -> Self;
2013-03-28 10:35:51 +00:00
fn min_t(&self, other: T) -> Self;
fn max_t(&self, other: T) -> Self;
fn clamp_t(&self, mn: T, mx: T) -> Self;
2013-02-09 22:42:06 +00:00
}
2013-04-02 05:12:13 +00:00
pub trait MixVec<T>: BaseVec<T> {
2013-02-09 22:42:06 +00:00
// Functions for blending numbers together
2013-03-28 10:35:51 +00:00
fn mix(&self, other: Self, value: Self) -> Self;
fn smooth_step(&self, edge0: Self, edge1: Self) -> Self;
fn step(&self, edge: Self) -> Self;
}
// Utility macros
macro_rules! zip_vec2(
($a:ident[] $method:ident $b:ident[]) => (
BaseVec2::new($a.index(0).$method($b.index(0)),
$a.index(1).$method($b.index(1)))
);
($a:ident[] $method:ident $b:ident) => (
BaseVec2::new($a.index(0).$method(&$b),
$a.index(1).$method(&$b))
);
)
macro_rules! zip_vec3(
($a:ident[] $method:ident $b:ident[]) => (
BaseVec3::new($a.index(0).$method($b.index(0)),
$a.index(1).$method($b.index(1)),
$a.index(2).$method($b.index(2)))
);
($a:ident[] $method:ident $b:ident) => (
BaseVec3::new($a.index(0).$method(&$b),
$a.index(1).$method(&$b),
$a.index(2).$method(&$b))
);
)
macro_rules! zip_vec4(
($a:ident[] $method:ident $b:ident[]) => (
BaseVec4::new($a.index(0).$method($b.index(0)),
$a.index(1).$method($b.index(1)),
$a.index(2).$method($b.index(2)),
$a.index(3).$method($b.index(3)))
);
($a:ident[] $method:ident $b:ident) => (
BaseVec4::new($a.index(0).$method(&$b),
$a.index(1).$method(&$b),
$a.index(2).$method(&$b),
$a.index(3).$method(&$b))
);
)
macro_rules! zip_assign(
($a:ident[] $method:ident $b:ident[] ..2) => ({ $a.index_mut(0).$method($b.index(0)); $a.index_mut(1).$method($b.index(1)); });
($a:ident[] $method:ident $b:ident[] ..3) => ({ zip_assign!($a[] $method $b[] ..2); $a.index_mut(2).$method($b.index(2)); });
($a:ident[] $method:ident $b:ident[] ..4) => ({ zip_assign!($a[] $method $b[] ..3); $a.index_mut(3).$method($b.index(3)); });
2013-05-07 15:00:06 +00:00
($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); });
)
2013-06-01 02:57:29 +00:00
/// A 2-dimensional vector
///
/// # Type parameters
///
/// - `T`: The type of the components. This is intended to support boolean,
/// integer, unsigned integer, and floating point types.
///
/// # Fields
///
/// - `x`: the first component of the vector
/// - `y`: the second component of the vector
#[deriving(Eq)]
pub struct Vec2<T> { x: T, y: T }
2013-04-02 05:12:13 +00:00
impl<T:Copy + Eq> BaseVec<T> for Vec2<T> {
#[inline(always)]
fn index<'a>(&'a self, i: uint) -> &'a T {
unsafe { &'a transmute::<&'a Vec2<T>, &'a [T,..2]>(self)[i] }
}
#[inline(always)]
fn from_value(value: T) -> Vec2<T> {
2013-04-02 05:12:13 +00:00
BaseVec2::new(value, value)
}
#[inline(always)]
fn to_ptr(&self) -> *T {
2013-06-06 02:38:23 +00:00
unsafe { transmute(self) }
}
2013-05-07 15:00:06 +00:00
#[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe { &'a mut transmute::<&'a mut Vec2<T>, &'a mut [T,..2]>(self)[i] }
}
#[inline(always)]
fn swap(&mut self, a: uint, b: uint) {
let tmp = *self.index(a);
*self.index_mut(a) = *self.index(b);
2013-05-23 21:55:23 +00:00
*self.index_mut(b) = tmp;
}
}
2013-04-02 05:12:13 +00:00
impl<T> BaseVec2<T> for Vec2<T> {
#[inline(always)]
fn new(x: T, y: T ) -> Vec2<T> {
Vec2 { x: x, y: y }
}
}
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec2<T> {
#[inline(always)]
fn identity() -> Vec2<T> {
BaseVec2::new(One::one::<T>(),
One::one::<T>())
}
#[inline(always)]
fn zero() -> Vec2<T> {
BaseVec2::new(Zero::zero::<T>(),
Zero::zero::<T>())
}
#[inline(always)]
fn is_zero(&self) -> bool {
*self.index(0) == Zero::zero() &&
*self.index(1) == Zero::zero()
}
#[inline(always)]
fn mul_t(&self, value: T) -> Vec2<T> {
zip_vec2!(self[] mul value)
}
#[inline(always)]
fn div_t(&self, value: T) -> Vec2<T> {
zip_vec2!(self[] div value)
}
#[inline(always)]
fn add_v(&self, other: &Vec2<T>) -> Vec2<T> {
zip_vec2!(self[] add other[])
}
#[inline(always)]
fn sub_v(&self, other: &Vec2<T>) -> Vec2<T> {
zip_vec2!(self[] sub other[])
}
#[inline(always)]
fn mul_v(&self, other: &Vec2<T>) -> Vec2<T> {
zip_vec2!(self[] mul other[])
}
#[inline(always)]
fn div_v(&self, other: &Vec2<T>) -> Vec2<T> {
zip_vec2!(self[] div other[])
}
#[inline(always)]
fn dot(&self, other: &Vec2<T>) -> T {
(*self.index(0)) * (*other.index(0)) +
(*self.index(1)) * (*other.index(1))
}
2013-05-07 15:00:06 +00:00
#[inline(always)]
fn neg_self(&mut self) {
*self.index_mut(0) = -self.index(0);
*self.index_mut(1) = -self.index(1);
}
#[inline(always)]
fn mul_self_t(&mut self, value: T) {
zip_assign!(self[] mul_assign value ..2);
}
#[inline(always)]
fn div_self_t(&mut self, value: T) {
zip_assign!(self[] div_assign value ..2);
}
#[inline(always)]
fn add_self_v(&mut self, other: &Vec2<T>) {
zip_assign!(self[] add_assign other[] ..2);
}
#[inline(always)]
fn sub_self_v(&mut self, other: &Vec2<T>) {
zip_assign!(self[] sub_assign other[] ..2);
}
#[inline(always)]
fn mul_self_v(&mut self, other: &Vec2<T>) {
zip_assign!(self[] mul_assign other[] ..2);
}
#[inline(always)]
fn div_self_v(&mut self, other: &Vec2<T>) {
zip_assign!(self[] div_assign other[] ..2);
}
}
impl<T:Copy + Num> Neg<Vec2<T>> for Vec2<T> {
#[inline(always)]
fn neg(&self) -> Vec2<T> {
BaseVec2::new(-self.index(0), -self.index(1))
}
}
impl<T:Copy + Num> NumVec2<T> for Vec2<T> {
#[inline(always)]
fn unit_x() -> Vec2<T> {
BaseVec2::new(One::one::<T>(),
Zero::zero::<T>())
}
#[inline(always)]
fn unit_y() -> Vec2<T> {
BaseVec2::new(Zero::zero::<T>(),
One::one::<T>())
}
#[inline(always)]
fn perp_dot(&self, other: &Vec2<T>) ->T {
(*self.index(0) * *other.index(1)) - (*self.index(1) * *other.index(0))
}
}
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::zero())
}
}
impl<T:Copy + Real + NumAssign> AffineVec<T> for Vec2<T> {
#[inline(always)]
fn length2(&self) -> T {
self.dot(self)
}
#[inline(always)]
fn length(&self) -> T {
self.length2().sqrt()
}
#[inline(always)]
fn distance2(&self, other: &Vec2<T>) -> T {
other.sub_v(self).length2()
}
#[inline(always)]
fn distance(&self, other: &Vec2<T>) -> T {
other.distance2(self).sqrt()
}
#[inline(always)]
fn angle(&self, other: &Vec2<T>) -> T {
self.perp_dot(other).atan2(self.dot(other))
}
#[inline(always)]
fn normalize(&self) -> Vec2<T> {
self.mul_t(One::one::<T>()/self.length())
}
#[inline(always)]
fn normalize_to(&self, length: T) -> Vec2<T> {
self.mul_t(length / self.length())
}
#[inline(always)]
fn lerp(&self, other: &Vec2<T>, amount: T) -> Vec2<T> {
self.add_v(&other.sub_v(self).mul_t(amount))
}
2013-05-07 15:00:06 +00:00
#[inline(always)]
fn normalize_self(&mut self) {
let n = One::one::<T>() / self.length();
self.mul_self_t(n);
}
#[inline(always)]
fn normalize_self_to(&mut self, length: T) {
let n = length / self.length();
self.mul_self_t(n);
}
fn lerp_self(&mut self, other: &Vec2<T>, amount: T) {
let v = other.sub_v(self).mul_t(amount);
self.add_self_v(&v);
}
}
2013-05-07 15:00:06 +00:00
impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Vec2<T> {
#[inline(always)]
fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>()
}
#[inline(always)]
2013-05-07 15:00:06 +00:00
fn approx_eq(&self, other: &Vec2<T>) -> bool {
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
}
#[inline(always)]
2013-05-07 15:00:06 +00:00
fn approx_eq_eps(&self, other: &Vec2<T>, epsilon: &T) -> bool {
self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self.index(1).approx_eq_eps(other.index(1), epsilon)
}
}
2013-04-02 05:12:13 +00:00
impl<T:Copy + Ord + Eq> OrdVec<T, Vec2<bool>> for Vec2<T> {
#[inline(always)]
fn less_than(&self, other: &Vec2<T>) -> Vec2<bool> {
zip_vec2!(self[] lt other[])
}
#[inline(always)]
fn less_than_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
zip_vec2!(self[] le other[])
}
#[inline(always)]
fn greater_than(&self, other: &Vec2<T>) -> Vec2<bool> {
zip_vec2!(self[] gt other[])
}
#[inline(always)]
fn greater_than_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
zip_vec2!(self[] ge other[])
}
}
2013-04-02 05:12:13 +00:00
impl<T:Copy + Eq> EqVec<T, Vec2<bool>> for Vec2<T> {
#[inline(always)]
fn equal(&self, other: &Vec2<T>) -> Vec2<bool> {
zip_vec2!(self[] eq other[])
}
#[inline(always)]
fn not_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
zip_vec2!(self[] ne other[])
}
}
2013-04-02 05:12:13 +00:00
impl BoolVec for Vec2<bool> {
#[inline(always)]
fn any(&self) -> bool {
*self.index(0) || *self.index(1)
}
#[inline(always)]
fn all(&self) -> bool {
*self.index(0) && *self.index(1)
}
#[inline(always)]
fn not(&self) -> Vec2<bool> {
BaseVec2::new(!*self.index(0), !*self.index(1))
}
}
// 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>;
// 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>;
2013-06-01 02:57:29 +00:00
/// A 3-dimensional vector
///
/// # Type parameters
///
/// - `T`: The type of the components. This is intended to support boolean,
/// integer, unsigned integer, and floating point types.
///
/// # Fields
///
/// - `x`: the first component of the vector
/// - `y`: the second component of the vector
/// - `z`: the third component of the vector
#[deriving(Eq)]
pub struct Vec3<T> { x: T, y: T, z: T }
2013-04-02 05:12:13 +00:00
impl<T:Copy + Eq> BaseVec<T> for Vec3<T> {
#[inline(always)]
fn index<'a>(&'a self, i: uint) -> &'a T {
unsafe { &'a transmute::<&'a Vec3<T>, &'a [T,..3]>(self)[i] }
}
#[inline(always)]
fn from_value(value: T) -> Vec3<T> {
2013-04-02 05:12:13 +00:00
BaseVec3::new(value, value, value)
}
#[inline(always)]
fn to_ptr(&self) -> *T {
2013-06-06 02:38:23 +00:00
unsafe { transmute(self) }
}
2013-05-07 15:00:06 +00:00
#[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe { &mut transmute::<&'a mut Vec3<T>, &'a mut [T,..3]>(self)[i] }
}
#[inline(always)]
fn swap(&mut self, a: uint, b: uint) {
let tmp = *self.index(a);
*self.index_mut(a) = *self.index(b);
2013-05-23 21:55:23 +00:00
*self.index_mut(b) = tmp;
}
}
2013-04-02 05:12:13 +00:00
impl<T> BaseVec3<T> for Vec3<T> {
#[inline(always)]
fn new(x: T, y: T, z: T) -> Vec3<T> {
Vec3 { x: x, y: y, z: z }
}
}
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec3<T> {
#[inline(always)]
fn identity() -> Vec3<T> {
BaseVec3::new(One::one::<T>(),
One::one::<T>(),
One::one::<T>())
}
#[inline(always)]
fn zero() -> Vec3<T> {
BaseVec3::new(Zero::zero::<T>(),
Zero::zero::<T>(),
Zero::zero::<T>())
}
#[inline(always)]
fn is_zero(&self) -> bool {
*self.index(0) == Zero::zero() &&
*self.index(1) == Zero::zero() &&
*self.index(2) == Zero::zero()
}
#[inline(always)]
fn mul_t(&self, value: T) -> Vec3<T> {
zip_vec3!(self[] mul value)
}
#[inline(always)]
fn div_t(&self, value: T) -> Vec3<T> {
zip_vec3!(self[] div value)
}
#[inline(always)]
fn add_v(&self, other: &Vec3<T>) -> Vec3<T> {
zip_vec3!(self[] add other[])
}
#[inline(always)]
fn sub_v(&self, other: &Vec3<T>) -> Vec3<T> {
zip_vec3!(self[] sub other[])
}
#[inline(always)]
fn mul_v(&self, other: &Vec3<T>) -> Vec3<T> {
zip_vec3!(self[] mul other[])
}
#[inline(always)]
fn div_v(&self, other: &Vec3<T>) -> Vec3<T> {
zip_vec3!(self[] div other[])
}
#[inline(always)]
fn dot(&self, other: &Vec3<T>) -> T {
(*self.index(0)) * (*other.index(0)) +
(*self.index(1)) * (*other.index(1)) +
(*self.index(2)) * (*other.index(2))
}
2013-05-07 15:00:06 +00:00
#[inline(always)]
fn neg_self(&mut self) {
*self.index_mut(0) = -self.index(0);
*self.index_mut(1) = -self.index(1);
*self.index_mut(2) = -self.index(2);
}
#[inline(always)]
fn mul_self_t(&mut self, value: T) {
zip_assign!(self[] mul_assign value ..3);
}
#[inline(always)]
fn div_self_t(&mut self, value: T) {
zip_assign!(self[] div_assign value ..3);
}
#[inline(always)]
fn add_self_v(&mut self, other: &Vec3<T>) {
zip_assign!(self[] add_assign other[] ..3);
}
#[inline(always)]
fn sub_self_v(&mut self, other: &Vec3<T>) {
zip_assign!(self[] sub_assign other[] ..3);
}
#[inline(always)]
fn mul_self_v(&mut self, other: &Vec3<T>) {
zip_assign!(self[] mul_assign other[] ..3);
}
#[inline(always)]
fn div_self_v(&mut self, other: &Vec3<T>) {
zip_assign!(self[] div_assign other[] ..3);
}
}
impl<T:Copy + Num> Neg<Vec3<T>> for Vec3<T> {
#[inline(always)]
fn neg(&self) -> Vec3<T> {
BaseVec3::new(-self.index(0), -self.index(1), -self.index(2))
}
}
impl<T:Copy + Num> NumVec3<T> for Vec3<T> {
#[inline(always)]
fn unit_x() -> Vec3<T> {
BaseVec3::new(One::one::<T>(),
Zero::zero::<T>(),
Zero::zero::<T>())
}
#[inline(always)]
fn unit_y() -> Vec3<T> {
BaseVec3::new(Zero::zero::<T>(),
One::one::<T>(),
Zero::zero::<T>())
}
#[inline(always)]
fn unit_z() -> Vec3<T> {
BaseVec3::new(Zero::zero::<T>(),
Zero::zero::<T>(),
One::one::<T>())
}
#[inline(always)]
fn cross(&self, other: &Vec3<T>) -> Vec3<T> {
BaseVec3::new((*self.index(1) * *other.index(2)) - (*self.index(2) * *other.index(1)),
(*self.index(2) * *other.index(0)) - (*self.index(0) * *other.index(2)),
(*self.index(0) * *other.index(1)) - (*self.index(1) * *other.index(0)))
}
2013-05-07 15:00:06 +00:00
#[inline(always)]
fn cross_self(&mut self, other: &Vec3<T>) {
*self = self.cross(other);
}
}
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::zero())
}
}
impl<T:Copy + Real + NumAssign> AffineVec<T> for Vec3<T> {
#[inline(always)]
fn length2(&self) -> T {
self.dot(self)
}
#[inline(always)]
fn length(&self) -> T {
self.length2().sqrt()
}
#[inline(always)]
fn distance2(&self, other: &Vec3<T>) -> T {
other.sub_v(self).length2()
}
#[inline(always)]
fn distance(&self, other: &Vec3<T>) -> T {
other.distance2(self).sqrt()
}
#[inline(always)]
fn angle(&self, other: &Vec3<T>) -> T {
self.cross(other).length().atan2(self.dot(other))
}
#[inline(always)]
fn normalize(&self) -> Vec3<T> {
self.mul_t(One::one::<T>()/self.length())
}
#[inline(always)]
fn normalize_to(&self, length: T) -> Vec3<T> {
self.mul_t(length / self.length())
}
#[inline(always)]
fn lerp(&self, other: &Vec3<T>, amount: T) -> Vec3<T> {
self.add_v(&other.sub_v(self).mul_t(amount))
}
2013-05-07 15:00:06 +00:00
#[inline(always)]
fn normalize_self(&mut self) {
let n = One::one::<T>() / self.length();
self.mul_self_t(n);
}
#[inline(always)]
fn normalize_self_to(&mut self, length: T) {
let n = length / self.length();
self.mul_self_t(n);
}
fn lerp_self(&mut self, other: &Vec3<T>, amount: T) {
let v = other.sub_v(self).mul_t(amount);
self.add_self_v(&v);
}
}
2013-05-07 15:00:06 +00:00
impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Vec3<T> {
#[inline(always)]
fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>()
}
#[inline(always)]
2013-05-07 15:00:06 +00:00
fn approx_eq(&self, other: &Vec3<T>) -> bool {
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
}
#[inline(always)]
2013-05-07 15:00:06 +00:00
fn approx_eq_eps(&self, other: &Vec3<T>, epsilon: &T) -> bool {
self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self.index(1).approx_eq_eps(other.index(1), epsilon) &&
self.index(2).approx_eq_eps(other.index(2), epsilon)
}
}
2013-04-02 05:12:13 +00:00
impl<T:Copy + Ord + Eq> OrdVec<T, Vec3<bool>> for Vec3<T> {
#[inline(always)]
fn less_than(&self, other: &Vec3<T>) -> Vec3<bool> {
zip_vec3!(self[] lt other[])
}
#[inline(always)]
fn less_than_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
zip_vec3!(self[] le other[])
}
#[inline(always)]
fn greater_than(&self, other: &Vec3<T>) -> Vec3<bool> {
zip_vec3!(self[] gt other[])
}
#[inline(always)]
fn greater_than_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
zip_vec3!(self[] ge other[])
}
}
2013-04-02 05:12:13 +00:00
impl<T:Copy + Eq> EqVec<T, Vec3<bool>> for Vec3<T> {
#[inline(always)]
fn equal(&self, other: &Vec3<T>) -> Vec3<bool> {
zip_vec3!(self[] eq other[])
}
#[inline(always)]
fn not_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
zip_vec3!(self[] ne other[])
}
}
2013-04-02 05:12:13 +00:00
impl BoolVec for Vec3<bool> {
#[inline(always)]
fn any(&self) -> bool {
*self.index(0) || *self.index(1) || *self.index(2)
}
#[inline(always)]
fn all(&self) -> bool {
*self.index(0) && *self.index(1) && *self.index(2)
}
#[inline(always)]
fn not(&self) -> Vec3<bool> {
BaseVec3::new(!*self.index(0), !*self.index(1), !*self.index(2))
}
}
// 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>;
// 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>;
2013-06-01 02:57:29 +00:00
/// A 4-dimensional vector
///
/// # Type parameters
///
/// - `T`: The type of the components. This is intended to support boolean,
/// integer, unsigned integer, and floating point types.
///
/// # Fields
///
/// - `x`: the first component of the vector
/// - `y`: the second component of the vector
/// - `z`: the third component of the vector
/// - `w`: the fourth component of the vector
#[deriving(Eq)]
pub struct Vec4<T> { x: T, y: T, z: T, w: T }
2013-04-02 05:12:13 +00:00
impl<T:Copy + Eq> BaseVec<T> for Vec4<T> {
#[inline(always)]
fn index<'a>(&'a self, i: uint) -> &'a T {
unsafe { &'a transmute::<&'a Vec4<T>, &'a [T,..4]>(self)[i] }
}
#[inline(always)]
fn from_value(value: T) -> Vec4<T> {
2013-04-02 05:12:13 +00:00
BaseVec4::new(value, value, value, value)
}
#[inline(always)]
fn to_ptr(&self) -> *T {
2013-06-06 02:38:23 +00:00
unsafe { transmute(self) }
}
2013-05-07 15:00:06 +00:00
#[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe { &'a mut transmute::< &'a mut Vec4<T>, &'a mut [T,..4]>(self)[i] }
}
#[inline(always)]
fn swap(&mut self, a: uint, b: uint) {
let tmp = *self.index(a);
*self.index_mut(a) = *self.index(b);
2013-05-23 21:55:23 +00:00
*self.index_mut(b) = tmp;
}
}
2013-04-02 05:12:13 +00:00
impl<T> BaseVec4<T> for Vec4<T> {
#[inline(always)]
fn new(x: T, y: T, z: T, w: T) -> Vec4<T> {
Vec4 { x: x, y: y, z: z, w: w }
}
}
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec4<T> {
#[inline(always)]
fn identity() -> Vec4<T> {
BaseVec4::new(One::one::<T>(),
One::one::<T>(),
One::one::<T>(),
One::one::<T>())
}
#[inline(always)]
fn zero() -> Vec4<T> {
BaseVec4::new(Zero::zero::<T>(),
Zero::zero::<T>(),
Zero::zero::<T>(),
Zero::zero::<T>())
}
#[inline(always)]
fn is_zero(&self) -> bool {
*self.index(0) == Zero::zero() &&
*self.index(1) == Zero::zero() &&
*self.index(2) == Zero::zero() &&
*self.index(3) == Zero::zero()
}
#[inline(always)]
fn mul_t(&self, value: T) -> Vec4<T> {
zip_vec4!(self[] mul value)
}
#[inline(always)]
fn div_t(&self, value: T) -> Vec4<T> {
zip_vec4!(self[] div value)
}
#[inline(always)]
fn add_v(&self, other: &Vec4<T>) -> Vec4<T> {
zip_vec4!(self[] add other[])
}
#[inline(always)]
fn sub_v(&self, other: &Vec4<T>) -> Vec4<T> {
zip_vec4!(self[] sub other[])
}
#[inline(always)]
fn mul_v(&self, other: &Vec4<T>) -> Vec4<T> {
zip_vec4!(self[] mul other[])
}
#[inline(always)]
fn div_v(&self, other: &Vec4<T>) -> Vec4<T> {
zip_vec4!(self[] div other[])
}
#[inline(always)]
fn dot(&self, other: &Vec4<T>) -> T {
(*self.index(0)) * (*other.index(0)) +
(*self.index(1)) * (*other.index(1)) +
(*self.index(2)) * (*other.index(2)) +
(*self.index(3)) * (*other.index(3))
}
2013-05-07 15:00:06 +00:00
#[inline(always)]
fn neg_self(&mut self) {
*self.index_mut(0) = -self.index(0);
*self.index_mut(1) = -self.index(1);
*self.index_mut(2) = -self.index(2);
*self.index_mut(3) = -self.index(3);
}
#[inline(always)]
fn mul_self_t(&mut self, value: T) {
zip_assign!(self[] mul_assign value ..4);
}
#[inline(always)]
fn div_self_t(&mut self, value: T) {
zip_assign!(self[] div_assign value ..4);
}
#[inline(always)]
fn add_self_v(&mut self, other: &Vec4<T>) {
zip_assign!(self[] add_assign other[] ..4);
}
#[inline(always)]
fn sub_self_v(&mut self, other: &Vec4<T>) {
zip_assign!(self[] sub_assign other[] ..4);
}
#[inline(always)]
fn mul_self_v(&mut self, other: &Vec4<T>) {
zip_assign!(self[] mul_assign other[] ..4);
}
#[inline(always)]
fn div_self_v(&mut self, other: &Vec4<T>) {
zip_assign!(self[] div_assign other[] ..4);
}
}
impl<T:Copy + Num> Neg<Vec4<T>> for Vec4<T> {
#[inline(always)]
fn neg(&self) -> Vec4<T> {
BaseVec4::new(-self.index(0), -self.index(1), -self.index(2), -self.index(3))
}
}
impl<T:Copy + Num> NumVec4<T> for Vec4<T> {
#[inline(always)]
fn unit_x() -> Vec4<T> {
BaseVec4::new(One::one::<T>(),
Zero::zero::<T>(),
Zero::zero::<T>(),
Zero::zero::<T>())
}
#[inline(always)]
fn unit_y() -> Vec4<T> {
BaseVec4::new(Zero::zero::<T>(),
One::one::<T>(),
Zero::zero::<T>(),
Zero::zero::<T>())
}
#[inline(always)]
fn unit_z() -> Vec4<T> {
BaseVec4::new(Zero::zero::<T>(),
Zero::zero::<T>(),
One::one::<T>(),
Zero::zero::<T>())
}
#[inline(always)]
fn unit_w() -> Vec4<T> {
BaseVec4::new(Zero::zero::<T>(),
Zero::zero::<T>(),
Zero::zero::<T>(),
One::one::<T>())
}
}
impl<T:Copy + Real + NumAssign> AffineVec<T> for Vec4<T> {
#[inline(always)]
fn length2(&self) -> T {
self.dot(self)
}
#[inline(always)]
fn length(&self) -> T {
self.length2().sqrt()
}
#[inline(always)]
fn distance2(&self, other: &Vec4<T>) -> T {
other.sub_v(self).length2()
}
#[inline(always)]
fn distance(&self, other: &Vec4<T>) -> T {
other.distance2(self).sqrt()
}
#[inline(always)]
fn angle(&self, other: &Vec4<T>) -> T {
(self.dot(other) / (self.length() * other.length())).acos()
}
#[inline(always)]
fn normalize(&self) -> Vec4<T> {
self.mul_t(One::one::<T>()/self.length())
}
#[inline(always)]
fn normalize_to(&self, length: T) -> Vec4<T> {
self.mul_t(length / self.length())
}
#[inline(always)]
fn lerp(&self, other: &Vec4<T>, amount: T) -> Vec4<T> {
self.add_v(&other.sub_v(self).mul_t(amount))
}
2013-05-07 15:00:06 +00:00
#[inline(always)]
fn normalize_self(&mut self) {
let n = One::one::<T>() / self.length();
self.mul_self_t(n);
}
#[inline(always)]
fn normalize_self_to(&mut self, length: T) {
let n = length / self.length();
self.mul_self_t(n);
}
fn lerp_self(&mut self, other: &Vec4<T>, amount: T) {
let v = other.sub_v(self).mul_t(amount);
self.add_self_v(&v);
}
}
2013-05-07 15:00:06 +00:00
impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Vec4<T> {
#[inline(always)]
fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>()
}
#[inline(always)]
2013-05-07 15:00:06 +00:00
fn approx_eq(&self, other: &Vec4<T>) -> bool {
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
}
#[inline(always)]
2013-05-07 15:00:06 +00:00
fn approx_eq_eps(&self, other: &Vec4<T>, epsilon: &T) -> bool {
self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self.index(1).approx_eq_eps(other.index(1), epsilon) &&
self.index(2).approx_eq_eps(other.index(2), epsilon) &&
self.index(3).approx_eq_eps(other.index(3), epsilon)
}
}
2013-04-02 05:12:13 +00:00
impl<T:Copy + Ord + Eq> OrdVec<T, Vec4<bool>> for Vec4<T> {
#[inline(always)]
fn less_than(&self, other: &Vec4<T>) -> Vec4<bool> {
zip_vec4!(self[] lt other[])
}
#[inline(always)]
fn less_than_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
zip_vec4!(self[] le other[])
}
#[inline(always)]
fn greater_than(&self, other: &Vec4<T>) -> Vec4<bool> {
zip_vec4!(self[] gt other[])
}
#[inline(always)]
fn greater_than_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
zip_vec4!(self[] ge other[])
}
}
2013-04-02 05:12:13 +00:00
impl<T:Copy + Eq> EqVec<T, Vec4<bool>> for Vec4<T> {
#[inline(always)]
fn equal(&self, other: &Vec4<T>) -> Vec4<bool> {
zip_vec4!(self[] eq other[])
}
#[inline(always)]
fn not_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
zip_vec4!(self[] ne other[])
}
}
2013-04-02 05:12:13 +00:00
impl BoolVec for Vec4<bool> {
#[inline(always)]
fn any(&self) -> bool {
*self.index(0) || *self.index(1) || *self.index(2) || *self.index(3)
}
#[inline(always)]
fn all(&self) -> bool {
*self.index(0) && *self.index(1) && *self.index(2) && *self.index(3)
}
#[inline(always)]
fn not(&self) -> Vec4<bool> {
BaseVec4::new(!*self.index(0), !*self.index(1), !*self.index(2), !*self.index(3))
}
}
// 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>;
// 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>;