diff --git a/nalgebra-glm/README b/nalgebra-glm/README index 4d04221a..6ef3ed83 100644 --- a/nalgebra-glm/README +++ b/nalgebra-glm/README @@ -6,4 +6,5 @@ * tweaked_infinite_perspective(fovy, aspect, near, ep) -> tweaked_infinite_perspective_ep * Function overload: the vec version is suffixed by _vec * Function overload: the methods taking an epsilon as suffixed by _eps -* L1Norm and L2Norm between two vectors have been renamed: l1_distance, l2_distance \ No newline at end of file +* L1Norm and L2Norm between two vectors have been renamed: l1_distance, l2_distance +* Matrix columnwise comparisons suffixed by _columns, e.g., `equal` -> `equal_columns` \ No newline at end of file diff --git a/nalgebra-glm/src/aliases.rs b/nalgebra-glm/src/aliases.rs index 1c7a8ff7..e21c0e60 100644 --- a/nalgebra-glm/src/aliases.rs +++ b/nalgebra-glm/src/aliases.rs @@ -4,92 +4,173 @@ use na::{MatrixMN, VectorN, Vector1, Vector2, Vector3, Vector4, Matrix2x4, Matrix3x4, Matrix4x3, Quaternion}; +/// A matrix with components of type `N`. It has `R` rows, and `C` columns. pub type Mat = MatrixMN; +/// A column vector with components of type `N`. It has `D` rows (and one column). pub type Vec = VectorN; +/// A quaternion with components of type `N`. pub type Qua = Quaternion; +/// A 1D vector with boolean components. pub type BVec1 = Vector1; +/// A 2D vector with boolean components. pub type BVec2 = Vector2; +/// A 3D vector with boolean components. pub type BVec3 = Vector3; +/// A 4D vector with boolean components. pub type BVec4 = Vector4; +/// A 1D vector with `f64` components. pub type DVec1 = Vector1; +/// A 2D vector with `f64` components. pub type DVec2 = Vector2; +/// A 3D vector with `f64` components. pub type DVec3 = Vector3; +/// A 4D vector with `f64` components. pub type DVec4 = Vector4; +/// A 1D vector with `i32` components. pub type IVec1 = Vector1; +/// A 2D vector with `i32` components. pub type IVec2 = Vector2; +/// A 3D vector with `i32` components. pub type IVec3 = Vector3; +/// A 4D vector with `i32` components. pub type IVec4 = Vector4; +/// A 1D vector with `u32` components. pub type UVec1 = Vector1; +/// A 2D vector with `u32` components. pub type UVec2 = Vector2; +/// A 3D vector with `u32` components. pub type UVec3 = Vector3; +/// A 4D vector with `u32` components. pub type UVec4 = Vector4; +/// A 1D vector with `f32` components. pub type Vec1 = Vector1; +/// A 2D vector with `f32` components. pub type Vec2 = Vector2; +/// A 3D vector with `f32` components. pub type Vec3 = Vector3; +/// A 4D vector with `f32` components. pub type Vec4 = Vector4; +/// A 1D vector with `u64` components. pub type U64Vec1 = Vector1; +/// A 2D vector with `u64` components. pub type U64Vec2 = Vector2; +/// A 3D vector with `u64` components. pub type U64Vec3 = Vector3; +/// A 4D vector with `u64` components. pub type U64Vec4 = Vector4; +/// A 1D vector with `i64` components. pub type I64Vec1 = Vector1; +/// A 2D vector with `i64` components. pub type I64Vec2 = Vector2; +/// A 3D vector with `i64` components. pub type I64Vec3 = Vector3; +/// A 4D vector with `i64` components. pub type I64Vec4 = Vector4; +/// A 1D vector with `u32` components. pub type U32Vec1 = Vector1; +/// A 2D vector with `u32` components. pub type U32Vec2 = Vector2; +/// A 3D vector with `u32` components. pub type U32Vec3 = Vector3; +/// A 4D vector with `u32` components. pub type U32Vec4 = Vector4; +/// A 1D vector with `i32` components. pub type I32Vec1 = Vector1; +/// A 2D vector with `i32` components. pub type I32Vec2 = Vector2; +/// A 3D vector with `i32` components. pub type I32Vec3 = Vector3; +/// A 4D vector with `i32` components. pub type I32Vec4 = Vector4; +/// A 1D vector with `u16` components. pub type U16Vec1 = Vector1; +/// A 2D vector with `u16` components. pub type U16Vec2 = Vector2; +/// A 3D vector with `u16` components. pub type U16Vec3 = Vector3; +/// A 4D vector with `u16` components. pub type U16Vec4 = Vector4; +/// A 1D vector with `i16` components. pub type I16Vec1 = Vector1; +/// A 2D vector with `i16` components. pub type I16Vec2 = Vector2; +/// A 3D vector with `i16` components. pub type I16Vec3 = Vector3; +/// A 4D vector with `i16` components. pub type I16Vec4 = Vector4; +/// A 1D vector with `u8` components. pub type U8Vec1 = Vector1; +/// A 2D vector with `u8` components. pub type U8Vec2 = Vector2; +/// A 3D vector with `u8` components. pub type U8Vec3 = Vector3; +/// A 4D vector with `u8` components. pub type U8Vec4 = Vector4; +/// A 1D vector with `i8` components. pub type I8Vec1 = Vector1; +/// A 2D vector with `i8` components. pub type I8Vec2 = Vector2; +/// A 3D vector with `i8` components. pub type I8Vec3 = Vector3; +/// A 4D vector with `i8` components. pub type I8Vec4 = Vector4; +/// A 2x2 matrix with `f64` components. pub type DMat2 = Matrix2; +/// A 2x2 matrix with `f64` components. pub type DMat2x2 = Matrix2; +/// A 2x3 matrix with `f64` components. pub type DMat2x3 = Matrix2x3; +/// A 2x4 matrix with `f64` components. pub type DMat2x4 = Matrix2x4; +/// A 3x3 matrix with `f64` components. pub type DMat3 = Matrix3; +/// A 3x2 matrix with `f64` components. pub type DMat3x2 = Matrix3x2; +/// A 3x3 matrix with `f64` components. pub type DMat3x3 = Matrix3; +/// A 3x4 matrix with `f64` components. pub type DMat3x4 = Matrix3x4; +/// A 4x4 matrix with `f64` components. pub type DMat4 = Matrix4; +/// A 4x2 matrix with `f64` components. pub type DMat4x2 = Matrix4x2; +/// A 4x3 matrix with `f64` components. pub type DMat4x3 = Matrix4x3; +/// A 4x4 matrix with `f64` components. pub type DMat4x4 = Matrix4; +/// A 2x2 matrix with `f32` components. pub type Mat2 = Matrix2; +/// A 2x2 matrix with `f32` components. pub type Mat2x2 = Matrix2; +/// A 2x2 matrix with `f32` components. pub type Mat2x3 = Matrix2x3; +/// A 2x4 matrix with `f32` components. pub type Mat2x4 = Matrix2x4; +/// A 3x3 matrix with `f32` components. pub type Mat3 = Matrix3; +/// A 3x2 matrix with `f32` components. pub type Mat3x2 = Matrix3x2; +/// A 3x3 matrix with `f32` components. pub type Mat3x3 = Matrix3; +/// A 3x4 matrix with `f32` components. pub type Mat3x4 = Matrix3x4; +/// A 4x2 matrix with `f32` components. pub type Mat4x2 = Matrix4x2; +/// A 4x3 matrix with `f32` components. pub type Mat4x3 = Matrix4x3; +/// A 4x4 matrix with `f32` components. pub type Mat4x4 = Matrix4; +/// A 4x3 matrix with `f32` components. pub type Mat4 = Matrix4; +/// A quaternion with f32 components. pub type Quat = Quaternion; +/// A quaternion with f64 components. pub type DQuat = Quaternion; diff --git a/nalgebra-glm/src/common.rs b/nalgebra-glm/src/common.rs index 88deed62..83f9f33a 100644 --- a/nalgebra-glm/src/common.rs +++ b/nalgebra-glm/src/common.rs @@ -1,68 +1,88 @@ use std::mem; use num::FromPrimitive; -use na::{self, Scalar, Real, DefaultAllocator}; +use na::{self, Real, DefaultAllocator}; use aliases::{Vec, Mat}; use traits::{Number, Dimension, Alloc}; - +/// For each matrix or vector component `x` if `x >= 0`; otherwise, it returns `-x`. pub fn abs(x: &Mat) -> Mat where DefaultAllocator: Alloc { x.abs() } +/// For each matrix or vector component returns a value equal to the nearest integer that is greater than or equal to `x`. pub fn ceil(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|x| x.ceil()) } -pub fn clamp(x: N, minVal: N, maxVal: N) -> N { - na::clamp(x, minVal, maxVal) + +/// Returns `min(max(x, min_val), max_val)`. +pub fn clamp(x: N, min_val: N, max_val: N) -> N { + na::clamp(x, min_val, max_val) } -pub fn clamp2(x: &Vec,minVal: N, maxVal: N) -> Vec +/// Returns `min(max(x, min_val), max_val)` for each component in `x` using the floating-point values `min_val and `max_val`. +pub fn clamp2(x: &Vec, min_val: N, max_val: N) -> Vec where DefaultAllocator: Alloc { - x.map(|x| na::clamp(x, minVal, maxVal)) + x.map(|x| na::clamp(x, min_val, max_val)) } -pub fn clamp3(x: &Vec, minVal: &Vec, maxVal: &Vec) -> Vec +/// Returns `min(max(x, min_val), max_val)` for each component in `x` using the components of `min_val` and `max_val` as bounds. +pub fn clamp3(x: &Vec, min_val: &Vec, max_val: &Vec) -> Vec where DefaultAllocator: Alloc { - na::clamp(x.clone(), minVal.clone(), maxVal.clone()) + na::clamp(x.clone(), min_val.clone(), max_val.clone()) } +/// Returns a signed integer value representing the encoding of a floating-point value. +/// +/// The floating-point value's bit-level representation is preserved. pub fn float_bits_to_int(v: f32) -> i32 { unsafe { mem::transmute(v) } } -pub fn float_bits_to_int_vec(v: Vec) -> Vec +/// Returns a signed integer value representing the encoding of each component of `v`. +/// +/// The floating point value's bit-level representation is preserved. +pub fn float_bits_to_int_vec(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|v| float_bits_to_int(v)) } +/// Returns an unsigned integer value representing the encoding of a floating-point value. +/// +/// The floating-point value's bit-level representation is preserved. pub fn float_bits_to_uint(v: f32) -> u32 { unsafe { mem::transmute(v) } } +/// Returns an unsigned integer value representing the encoding of each component of `v`. +/// +/// The floating point value's bit-level representation is preserved. pub fn float_bits_to_uint_vec(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|v| float_bits_to_uint(v)) } +/// Returns componentwise a value equal to the nearest integer that is less then or equal to `x`. pub fn floor(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|x| x.floor()) } -// FIXME: should be implemented for Vec/Mat? -pub fn fma(a: N, b: N, c: N) -> N { - // FIXME: use an actual FMA - a * b + c -} +//// FIXME: should be implemented for Vec/Mat? +//pub fn fma(a: N, b: N, c: N) -> N { +// // FIXME: use an actual FMA +// a * b + c +//} +/// Returns the fractional part of `x`. pub fn fract(x: N) -> N { x.fract() } +/// Returns the fractional part of each component of `x`. pub fn fract2(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|x| x.fract()) @@ -76,11 +96,17 @@ pub fn fract2(x: &Vec) -> Vec // (x * (-e).exp2(), e) //} +/// Returns a floating-point value corresponding to a signed integer encoding of a floating-point value. +/// +/// If an inf or NaN is passed in, it will not signal, and the resulting floating point value is unspecified. Otherwise, the bit-level representation is preserved. pub fn int_bits_to_float(v: i32) -> f32 { unsafe { mem::transmute(v) } } +/// For each components of `v`, returns a floating-point value corresponding to a signed integer encoding of a floating-point value. +/// +/// If an inf or NaN is passed in, it will not signal, and the resulting floating point value is unspecified. Otherwise, the bit-level representation is preserved. pub fn int_bits_to_float_vec(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|v| int_bits_to_float(v)) @@ -104,47 +130,63 @@ pub fn int_bits_to_float_vec(v: &Vec) -> Vec // x * (exp).exp2() //} +/// The maximum between two numbers. pub fn max(x: N, y: N) -> N { na::sup(&x, &y) } +/// The maximum between each component of `x` and `y`. pub fn max2(x: &Vec, y: N) -> Vec where DefaultAllocator: Alloc { x.map(|x| na::sup(&x, &y)) } +/// Componentwise maximum between `x` and `y`. pub fn max3(x: &Vec, y: &Vec) -> Vec where DefaultAllocator: Alloc { na::sup(x, y) } +/// The minimum between two numbers. pub fn min(x: N, y: N) -> N { na::inf(&x, &y) } +/// The minimum between each component of `x` and `y`. pub fn min2(x: &Vec,y: N) -> Vec where DefaultAllocator: Alloc { x.map(|x| na::inf(&x, &y)) } +/// Componentwise minimum between `x` and `y`. pub fn min3(x: &Vec, y: &Vec) -> Vec where DefaultAllocator: Alloc { na::inf(x, y) } +/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of x and y using the floating-point value a. +/// +/// The value for a is not restricted to the range `[0, 1]`. pub fn mix(x: N, y: N, a: N) -> N { x * (N::one() - a) + y * a } +/// Componentwise modulus. +/// +/// Returns `x - y * floor(x / y)` for each component in `x` using the corresponding component of `y`. pub fn mod_(x: &Vec, y: &Vec) -> Vec where DefaultAllocator: Alloc { x.zip_map(y, |x, y| x % y) } +/// Modulus between two values. pub fn modf(x: N, i: N) -> N { x % i } +/// Componentwise rounding. +/// +/// Values equal to `0.5` are rounded away from `0.0`. pub fn round(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|x| x.round()) @@ -156,11 +198,16 @@ pub fn round(x: &Vec) -> Vec // unimplemented!() //} +/// Returns 1 if `x > 0`, 0 if `x == 0`, or -1 if `x < 0`. pub fn sign(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|x| x.signum()) } +/// Returns 0.0 if `x <= edge0` and `1.0 if x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`. +/// +/// This is useful in cases where you would want a threshold function with a smooth transition. +/// This is equivalent to: `let result = clamp((x - edge0) / (edge1 - edge0), 0, 1); return t * t * (3 - 2 * t);` Results are undefined if `edge0 >= edge1`. pub fn smoothstep(edge0: N, edge1: N, x: N) -> N { let _3: N = FromPrimitive::from_f64(3.0).unwrap(); let _2: N = FromPrimitive::from_f64(2.0).unwrap(); @@ -168,6 +215,7 @@ pub fn smoothstep(edge0: N, edge1: N, x: N) -> N { t * t * (_3 - t * _2) } +/// Returns 0.0 if `x < edge`, otherwise it returns 1.0. pub fn step(edge: N, x: N) -> N { if edge > x { N::zero() @@ -175,27 +223,35 @@ pub fn step(edge: N, x: N) -> N { N::one() } } - +/// Returns 0.0 if `x[i] < edge`, otherwise it returns 1.0. pub fn step2(edge: N, x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|x| step(edge, x)) } +/// Returns 0.0 if `x[i] < edge[i]`, otherwise it returns 1.0. pub fn step3(edge: &Vec, x: &Vec) -> Vec where DefaultAllocator: Alloc { edge.zip_map(x, |edge, x| step(edge, x)) } +/// Returns a value equal to the nearest integer to `x` whose absolute value is not larger than the absolute value of `x`. pub fn trunc(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|x| x.trunc()) } +/// Returns a floating-point value corresponding to a unsigned integer encoding of a floating-point value. +/// +/// If an `inf` or `NaN` is passed in, it will not signal, and the resulting floating point value is unspecified. Otherwise, the bit-level representation is preserved. pub fn uint_bits_to_float(v: u32) -> f32 { unsafe { mem::transmute(v) } } +/// For each component of `v`, returns a floating-point value corresponding to a unsigned integer encoding of a floating-point value. +/// +/// If an inf or NaN is passed in, it will not signal, and the resulting floating point value is unspecified. Otherwise, the bit-level representation is preserved. pub fn uint_bits_to_float_vec(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|v| uint_bits_to_float(v)) diff --git a/nalgebra-glm/src/constructors.rs b/nalgebra-glm/src/constructors.rs index 7dfb9e33..aa40eb9d 100644 --- a/nalgebra-glm/src/constructors.rs +++ b/nalgebra-glm/src/constructors.rs @@ -1,23 +1,29 @@ use na::{Scalar, Real, U1, U2, U3, U4}; use aliases::{Vec, Mat, Qua}; + +/// Creates a new 1D vector. pub fn vec1(x: N) -> Vec { Vec::::new(x) } +/// Creates a new 2D vector. pub fn vec2(x: N, y: N) -> Vec { Vec::::new(x, y) } +/// Creates a new 3D vector. pub fn vec3(x: N, y: N, z: N) -> Vec { Vec::::new(x, y, z) } +/// Creates a new 4D vector. pub fn vec4(x: N, y: N, z: N, w: N) -> Vec { Vec::::new(x, y, z, w) } +/// Create a new 2x2 matrix. pub fn mat2(m11: N, m12: N, m21: N, m22: N) -> Mat { Mat::::new( m11, m12, @@ -25,6 +31,7 @@ pub fn mat2(m11: N, m12: N, m21: N, m22: N) -> Mat { ) } +/// Create a new 2x2 matrix. pub fn mat2x2(m11: N, m12: N, m21: N, m22: N) -> Mat { Mat::::new( m11, m12, @@ -32,6 +39,7 @@ pub fn mat2x2(m11: N, m12: N, m21: N, m22: N) -> Mat { ) } +/// Create a new 2x3 matrix. pub fn mat2x3(m11: N, m12: N, m13: N, m21: N, m22: N, m23: N) -> Mat { Mat::::new( m11, m12, m13, @@ -39,6 +47,7 @@ pub fn mat2x3(m11: N, m12: N, m13: N, m21: N, m22: N, m23: N) -> Mat< ) } +/// Create a new 2x4 matrix. pub fn mat2x4(m11: N, m12: N, m13: N, m14: N, m21: N, m22: N, m23: N, m24: N) -> Mat { Mat::::new( m11, m12, m13, m14, @@ -46,6 +55,7 @@ pub fn mat2x4(m11: N, m12: N, m13: N, m14: N, m21: N, m22: N, m23: N, ) } +/// Create a new 3x3 matrix. pub fn mat3(m11: N, m12: N, m13: N, m21: N, m22: N, m23: N, m31: N, m32: N, m33: N) -> Mat { Mat::::new( m11, m12, m13, @@ -54,6 +64,7 @@ pub fn mat3(m11: N, m12: N, m13: N, m21: N, m22: N, m23: N, m31: N, m ) } +/// Create a new 3x2 matrix. pub fn mat3x2(m11: N, m12: N, m21: N, m22: N, m31: N, m32: N) -> Mat { Mat::::new( m11, m12, @@ -62,6 +73,7 @@ pub fn mat3x2(m11: N, m12: N, m21: N, m22: N, m31: N, m32: N) -> Mat< ) } +/// Create a new 3x3 matrix. pub fn mat3x3(m11: N, m12: N, m13: N, m21: N, m22: N, m23: N, m31: N, m32: N, m33: N) -> Mat { Mat::::new( m11, m12, m13, @@ -70,6 +82,7 @@ pub fn mat3x3(m11: N, m12: N, m13: N, m21: N, m22: N, m23: N, m31: N, ) } +/// Create a new 3x4 matrix. pub fn mat3x4(m11: N, m12: N, m13: N, m14: N, m21: N, m22: N, m23: N, m24: N, m31: N, m32: N, m33: N, m34: N) -> Mat { Mat::::new( m11, m12, m13, m14, @@ -78,6 +91,7 @@ pub fn mat3x4(m11: N, m12: N, m13: N, m14: N, m21: N, m22: N, m23: N, ) } +/// Create a new 4x2 matrix. pub fn mat4x2(m11: N, m12: N, m21: N, m22: N, m31: N, m32: N, m41: N, m42: N) -> Mat { Mat::::new( m11, m12, @@ -87,6 +101,7 @@ pub fn mat4x2(m11: N, m12: N, m21: N, m22: N, m31: N, m32: N, m41: N, ) } +/// Create a new 4x3 matrix. pub fn mat4x3(m11: N, m12: N, m13: N, m21: N, m22: N, m23: N, m31: N, m32: N, m33: N, m41: N, m42: N, m43: N) -> Mat { Mat::::new( m11, m12, m13, @@ -96,6 +111,7 @@ pub fn mat4x3(m11: N, m12: N, m13: N, m21: N, m22: N, m23: N, m31: N, ) } +/// Create a new 4x4 matrix. pub fn mat4x4(m11: N, m12: N, m13: N, m14: N, m21: N, m22: N, m23: N, m24: N, m31: N, m32: N, m33: N, m34: N, m41: N, m42: N, m43: N, m44: N) -> Mat { Mat::::new( m11, m12, m13, m14, @@ -105,6 +121,7 @@ pub fn mat4x4(m11: N, m12: N, m13: N, m14: N, m21: N, m22: N, m23: N, ) } +/// Create a new 4x4 matrix. pub fn mat4(m11: N, m12: N, m13: N, m14: N, m21: N, m22: N, m23: N, m24: N, m31: N, m32: N, m33: N, m34: N, m41: N, m42: N, m43: N, m44: N) -> Mat { Mat::::new( m11, m12, m13, m14, @@ -114,6 +131,7 @@ pub fn mat4(m11: N, m12: N, m13: N, m14: N, m21: N, m22: N, m23: N, m ) } +/// Creates a new quaternion. pub fn quat(x: N, y: N, z: N, w: N) -> Qua { Qua::new(x, y, z, w) } diff --git a/nalgebra-glm/src/exponential.rs b/nalgebra-glm/src/exponential.rs index 08fe8f32..67d0f1dc 100644 --- a/nalgebra-glm/src/exponential.rs +++ b/nalgebra-glm/src/exponential.rs @@ -2,38 +2,44 @@ use na::{Real, DefaultAllocator}; use aliases::Vec; use traits::{Alloc, Dimension}; - +/// Componentwise exponential. pub fn exp(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|x| x.exp()) } +/// Componentwise base-2 exponential. pub fn exp2(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|x| x.exp2()) } +/// Compute the inverse of the square root of each component of `v`. pub fn inversesqrt(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|x| N::one() / x.sqrt()) } +/// Componentwise logarithm. pub fn log(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|x| x.ln()) } +/// Componentwise base-2 logarithm. pub fn log2(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|x| x.log2()) } +/// Componentwise power. pub fn pow(base: &Vec, exponent: &Vec) -> Vec where DefaultAllocator: Alloc { base.zip_map(exponent, |b, e| b.powf(e)) } +/// Componentwise square root. pub fn sqrt(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|x| x.sqrt()) diff --git a/nalgebra-glm/src/ext/matrix_clip_space.rs b/nalgebra-glm/src/ext/matrix_clip_space.rs new file mode 100644 index 00000000..87bea38b --- /dev/null +++ b/nalgebra-glm/src/ext/matrix_clip_space.rs @@ -0,0 +1,172 @@ +use na::{Real, U4, Orthographic3, Perspective3}; +use aliases::Mat; + +//pub fn frustum(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { +// unimplemented!() +//} + +//pub fn frustum_lh(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn frustum_lr_no(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn frustum_lh_zo(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn frustum_no(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn frustum_rh(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn frustum_rh_no(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn frustum_rh_zo(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn frustum_zo(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { +// unimplemented!() +//} + +//pub fn infinite_perspective(fovy: N, aspect: N, near: N) -> Mat { +// unimplemented!() +//} +// +//pub fn infinite_perspective_lh(fovy: N, aspect: N, near: N) -> Mat { +// unimplemented!() +//} +// +//pub fn infinite_perspective_rh(fovy: N, aspect: N, near: N) -> Mat { +// unimplemented!() +//} +// +//pub fn infinite_ortho(left: N, right: N, bottom: N, top: N) -> Mat { +// unimplemented!() +//} + +/// Creates a matrix for an orthographic parallel viewing volume, using the right handedness and OpenGL near and far clip planes definition. +pub fn ortho(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Mat { + Orthographic3::new(left, right, bottom, top, znear, zfar).unwrap() +} + +//pub fn ortho_lh(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Mat { +// unimplemented!() +//} +// +//pub fn ortho_lh_no(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Mat { +// unimplemented!() +//} +// +//pub fn ortho_lh_zo(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Mat { +// unimplemented!() +//} +// +//pub fn ortho_no(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Mat { +// unimplemented!() +//} +// +//pub fn ortho_rh(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Mat { +// unimplemented!() +//} +// +//pub fn ortho_rh_no(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Mat { +// unimplemented!() +//} +// +//pub fn ortho_rh_zo(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Mat { +// unimplemented!() +//} +// +//pub fn ortho_zo(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Mat { +// unimplemented!() +//} + +/// Creates a matrix for a symetric perspective-view frustum based on the right handedness and OpenGL near and far clip planes definition. +pub fn perspective(fovy: N, aspect: N, near: N, far: N) -> Mat { + Perspective3::new(fovy, aspect, near, far).unwrap() +} + +//pub fn perspective_fov(fov: N, width: N, height: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_fov_lh(fov: N, width: N, height: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_fov_lh_no(fov: N, width: N, height: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_fov_lh_zo(fov: N, width: N, height: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_fov_no(fov: N, width: N, height: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_fov_rh(fov: N, width: N, height: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_fov_rh_no(fov: N, width: N, height: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_fov_rh_zo(fov: N, width: N, height: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_fov_zo(fov: N, width: N, height: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_lh(fovy: N, aspect: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_lh_no(fovy: N, aspect: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_lh_zo(fovy: N, aspect: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_no(fovy: N, aspect: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_rh(fovy: N, aspect: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_rh_no(fovy: N, aspect: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_rh_zo(fovy: N, aspect: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn perspective_zo(fovy: N, aspect: N, near: N, far: N) -> Mat { +// unimplemented!() +//} +// +//pub fn tweaked_infinite_perspective(fovy: N, aspect: N, near: N) -> Mat { +// unimplemented!() +//} +// +//pub fn tweaked_infinite_perspective_ep(fovy: N, aspect: N, near: N, ep: N) -> Mat { +// unimplemented!() +//} diff --git a/nalgebra-glm/src/ext/matrix_projection.rs b/nalgebra-glm/src/ext/matrix_projection.rs new file mode 100644 index 00000000..c791e643 --- /dev/null +++ b/nalgebra-glm/src/ext/matrix_projection.rs @@ -0,0 +1,122 @@ +use na::{self, Real, U2, U3, U4, Vector3, Vector4, Matrix4}; + +use aliases::{Mat, Vec}; + +/// Define a picking region. +/// +/// # Parameters +/// * `center`: Specify the center of a picking region in window coordinates. +// * `delta`: Specify the width and height, respectively, of the picking region in window coordinates. +// * `viewport`: Rendering viewport +pub fn pick_matrix(center: &Vec, delta: &Vec, viewport: &Vec) -> Mat { + let shift = Vector3::new( + (viewport.z - (center.x - viewport.x) * na::convert(2.0)) / delta.x, + (viewport.w - (center.y - viewport.y) * na::convert(2.0)) / delta.y, + N::zero() + ); + + let result = Matrix4::new_translation(&shift); + result.prepend_nonuniform_scaling(&Vector3::new(viewport.z / delta.x, viewport.w / delta.y, N::one())) +} + +/// Map the specified object coordinates `(obj.x, obj.y, obj.z)` into window coordinates using OpenGL near and far clip planes definition. +/// +/// # Parameters +/// * `obj`: Specify the object coordinates. +/// * `model`: Specifies the current modelview matrix. +/// * `proj`: Specifies the current projection matrix. +/// * `viewport`: Specifies the current viewport. +pub fn project(obj: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { + project_no(obj, model, proj, viewport) +} + +/// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates. +/// +/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) +/// +/// # Parameters +/// * `obj`: Specify the object coordinates. +/// * `model`: Specifies the current modelview matrix. +/// * `proj`: Specifies the current projection matrix. +/// * `viewport`: Specifies the current viewport. +pub fn project_no(obj: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { + let proj = project_zo(obj, model, proj, viewport); + Vector3::new(proj.x, proj.y, proj.z * na::convert(0.5) + na::convert(0.5)) +} + +/// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates. +/// +/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) +/// +/// # Parameters +/// * `obj`: Specify the object coordinates. +/// * `model`: Specifies the current modelview matrix. +/// * `proj`: Specifies the current projection matrix. +/// * `viewport`: Specifies the current viewport. +pub fn project_zo(obj: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { + let normalized = proj * model * Vector4::new(obj.x, obj.y, obj.z, N::one()); + let scale = N::one() / normalized.w; + + Vector3::new( + viewport.x + (viewport.z * (normalized.x * scale + N::one()) * na::convert(0.5)), + viewport.y + (viewport.w * (normalized.y * scale + N::one()) * na::convert(0.5)), + normalized.z * scale, + ) +} + +/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates using OpengGL near and far clip planes definition. +/// +/// # Parameters +/// * `obj`: Specify the window coordinates to be mapped. +/// * `model`: Specifies the current modelview matrix. +/// * `proj`: Specifies the current projection matrix. +/// * `viewport`: Specifies the current viewport. +pub fn unproject(win: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { + unproject_no(win, model, proj, viewport) +} + +/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. +/// +/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) +/// +/// # Parameters +/// * `obj`: Specify the window coordinates to be mapped. +/// * `model`: Specifies the current modelview matrix. +/// * `proj`: Specifies the current projection matrix. +/// * `viewport`: Specifies the current viewport. +pub fn unproject_no(win: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { + let _2: N = na::convert(2.0); + let transform = (proj * model).try_inverse().unwrap_or(Matrix4::zeros()); + let pt = Vector4::new( + _2 * (win.x - viewport.x) / viewport.z - N::one(), + _2 * (win.y - viewport.y) / viewport.w - N::one(), + _2 * win.z - N::one(), + N::one(), + ); + + let result = transform * pt; + result.fixed_rows::(0) / result.w +} + +/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. +/// +/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) +/// +/// # Parameters +/// * `obj`: Specify the window coordinates to be mapped. +/// * `model`: Specifies the current modelview matrix. +/// * `proj`: Specifies the current projection matrix. +/// * `viewport`: Specifies the current viewport. +pub fn unproject_zo(win: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { + let _2: N = na::convert(2.0); + let transform = (proj * model).try_inverse().unwrap_or(Matrix4::zeros()); + let pt = Vector4::new( + _2 * (win.x - viewport.x) / viewport.z - N::one(), + _2 * (win.y - viewport.y) / viewport.w - N::one(), + win.z, + N::one(), + ); + + let result = transform * pt; + result.fixed_rows::(0) / result.w +} \ No newline at end of file diff --git a/nalgebra-glm/src/ext/matrix_relationnal.rs b/nalgebra-glm/src/ext/matrix_relationnal.rs new file mode 100644 index 00000000..41da0612 --- /dev/null +++ b/nalgebra-glm/src/ext/matrix_relationnal.rs @@ -0,0 +1,76 @@ +use na::DefaultAllocator; + +use aliases::{Vec, Mat}; +use traits::{Alloc, Number, Dimension}; + +/// Perform a component-wise equal-to comparison of two matrices. +/// +/// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices. +pub fn equal_columns(x: &Mat, y: &Mat) -> Vec + where DefaultAllocator: Alloc { + let mut res = Vec::<_, C>::repeat(false); + + for i in 0..C::dim() { + res[i] = x.column(i) == y.column(i) + } + + res +} + +/// Returns the component-wise comparison of `|x - y| < epsilon`. +/// +/// True if this expression is satisfied. +pub fn equal_columns_eps(x: &Mat, y: &Mat, epsilon: N) -> Vec + where DefaultAllocator: Alloc { + equal_columns_eps_vec(x, y, &Vec::<_, C>::repeat(epsilon)) +} + +/// Returns the component-wise comparison of `|x - y| < epsilon`. +/// +/// True if this expression is satisfied. +pub fn equal_columns_eps_vec(x: &Mat, y: &Mat, epsilon: &Vec) -> Vec + where DefaultAllocator: Alloc { + let mut res = Vec::<_, C>::repeat(false); + + for i in 0..C::dim() { + res[i] = (x.column(i) - y.column(i)).abs() < Vec::<_, R>::repeat(epsilon[i]) + } + + res +} + +/// Perform a component-wise not-equal-to comparison of two matrices. +/// +/// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices. +pub fn not_equal_columns(x: &Mat, y: &Mat) -> Vec + where DefaultAllocator: Alloc { + let mut res = Vec::<_, C>::repeat(false); + + for i in 0..C::dim() { + res[i] = x.column(i) != y.column(i) + } + + res +} + +/// Returns the component-wise comparison of `|x - y| < epsilon`. +/// +/// True if this expression is not satisfied. +pub fn not_equal_columns_eps(x: &Mat, y: &Mat, epsilon: N) -> Vec + where DefaultAllocator: Alloc { + not_equal_columns_eps_vec(x, y, &Vec::<_, C>::repeat(epsilon)) +} + +/// Returns the component-wise comparison of `|x - y| >= epsilon`. +/// +/// True if this expression is not satisfied. +pub fn not_equal_columns_eps_vec(x: &Mat, y: &Mat, epsilon: &Vec) -> Vec + where DefaultAllocator: Alloc { + let mut res = Vec::<_, C>::repeat(false); + + for i in 0..C::dim() { + res[i] = (x.column(i) - y.column(i)).abs() >= Vec::<_, R>::repeat(epsilon[i]) + } + + res +} diff --git a/nalgebra-glm/src/ext/matrix_transform.rs b/nalgebra-glm/src/ext/matrix_transform.rs new file mode 100644 index 00000000..9929e54d --- /dev/null +++ b/nalgebra-glm/src/ext/matrix_transform.rs @@ -0,0 +1,68 @@ +use na::{DefaultAllocator, Real, U3, U4, Unit, Rotation3, Point3}; + +use traits::{Dimension, Number, Alloc}; +use aliases::{Mat, Vec}; + +/// The identity matrix. +pub fn identity() -> Mat + where DefaultAllocator: Alloc { + Mat::::identity() +} + +/// Build a look at view matrix based on the right handedness. +/// +/// # Parameters +/// * `eye` − Position of the camera +/// * `center` − Position where the camera is looking at +/// * `u` − Normalized up vector, how the camera is oriented. Typically `(0, 1, 0)` +pub fn look_at(eye: &Vec, center: &Vec, up: &Vec) -> Mat { + look_at_rh(eye, center, up) +} + +/// Build a left handed look at view matrix. +/// +/// # Parameters +/// * `eye` − Position of the camera +/// * `center` − Position where the camera is looking at +/// * `u` − Normalized up vector, how the camera is oriented. Typically `(0, 1, 0)` +pub fn look_at_lh(eye: &Vec, center: &Vec, up: &Vec) -> Mat { + Mat::look_at_lh(&Point3::from_coordinates(*eye), &Point3::from_coordinates(*center), up) +} + +/// Build a right handed look at view matrix. +/// +/// # Parameters +/// * `eye` − Position of the camera +/// * `center` − Position where the camera is looking at +/// * `u` − Normalized up vector, how the camera is oriented. Typically `(0, 1, 0)` +pub fn look_at_rh(eye: &Vec, center: &Vec, up: &Vec) -> Mat { + Mat::look_at_rh(&Point3::from_coordinates(*eye), &Point3::from_coordinates(*center), up) +} + +/// Builds a rotation 4 * 4 matrix created from an axis vector and an angle. +/// +/// # Parameters +/// * m − Input matrix multiplied by this rotation matrix. +/// * angle − Rotation angle expressed in radians. +/// * axis − Rotation axis, recommended to be normalized. +pub fn rotate(m: &Mat, angle: N, axis: &Vec) -> Mat { + m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous() +} + +/// Builds a scale 4 * 4 matrix created from 3 scalars. +/// +/// # Parameters +/// * m − Input matrix multiplied by this scale matrix. +/// * v − Ratio of scaling for each axis. +pub fn scale(m: &Mat, v: &Vec) -> Mat { + m.prepend_nonuniform_scaling(v) +} + +/// Builds a translation 4 * 4 matrix created from a vector of 3 components. +/// +/// # Parameters +/// * m − Input matrix multiplied by this translation matrix. +/// * v − Coordinates of a translation vector. +pub fn translate(m: &Mat, v: &Vec) -> Mat { + m.prepend_translation(v) +} diff --git a/nalgebra-glm/src/ext/mod.rs b/nalgebra-glm/src/ext/mod.rs new file mode 100644 index 00000000..e5fb92fb --- /dev/null +++ b/nalgebra-glm/src/ext/mod.rs @@ -0,0 +1,20 @@ +//! (Reexported) Additional features not specified by GLSL specification + +pub use self::matrix_clip_space::*; +pub use self::matrix_projection::*; +pub use self::matrix_relationnal::*; +pub use self::matrix_transform::*; +pub use self::scalar_common::*; +pub use self::scalar_constants::*; +pub use self::vector_common::*; +pub use self::vector_relational::*; + + +mod matrix_clip_space; +mod matrix_projection; +mod matrix_relationnal; +mod matrix_transform; +mod scalar_common; +mod scalar_constants; +mod vector_common; +mod vector_relational; \ No newline at end of file diff --git a/nalgebra-glm/src/ext_scalar_common.rs b/nalgebra-glm/src/ext/scalar_common.rs similarity index 70% rename from nalgebra-glm/src/ext_scalar_common.rs rename to nalgebra-glm/src/ext/scalar_common.rs index 17119d7e..ca5e2e3d 100644 --- a/nalgebra-glm/src/ext_scalar_common.rs +++ b/nalgebra-glm/src/ext/scalar_common.rs @@ -2,18 +2,22 @@ use na; use traits::Number; +/// Returns the maximum value among three. pub fn max3(a: N, b: N, c: N) -> N { na::sup(&na::sup(&a, &b), &c) } +/// Returns the maximum value among four. pub fn max4(a: N, b: N, c: N, d: N) -> N { na::sup(&na::sup(&a, &b), &na::sup(&c, &d)) } +/// Returns the maximum value among three. pub fn min3(a: N, b: N, c: N) -> N { na::inf(&na::inf(&a, &b), &c) } +/// Returns the maximum value among four. pub fn min4(a: N, b: N, c: N, d: N) -> N { na::inf(&na::inf(&a, &b), &na::inf(&c, &d)) } \ No newline at end of file diff --git a/nalgebra-glm/src/ext_scalar_constants.rs b/nalgebra-glm/src/ext/scalar_constants.rs similarity index 66% rename from nalgebra-glm/src/ext_scalar_constants.rs rename to nalgebra-glm/src/ext/scalar_constants.rs index d34c58bf..89e3746c 100644 --- a/nalgebra-glm/src/ext_scalar_constants.rs +++ b/nalgebra-glm/src/ext/scalar_constants.rs @@ -1,10 +1,12 @@ use approx::AbsDiffEq; use na::Real; +/// Default epsilon value used for apporximate comparison. pub fn epsilon>() -> N { N::default_epsilon() } +/// The value of PI. pub fn pi() -> N { N::pi() } diff --git a/nalgebra-glm/src/ext_vector_common.rs b/nalgebra-glm/src/ext/vector_common.rs similarity index 73% rename from nalgebra-glm/src/ext_vector_common.rs rename to nalgebra-glm/src/ext/vector_common.rs index 59033378..a97062dd 100644 --- a/nalgebra-glm/src/ext_vector_common.rs +++ b/nalgebra-glm/src/ext/vector_common.rs @@ -3,41 +3,49 @@ use na::{self, DefaultAllocator}; use traits::{Alloc, Number, Dimension}; use aliases::Vec; +/// Componentwise maximum between a vector and a scalar. pub fn max(a: &Vec, b: N) -> Vec where DefaultAllocator: Alloc { a.map(|a| na::sup(&a, &b)) } +/// Componentwise maximum between two vectors. pub fn max2(a: &Vec, b: &Vec) -> Vec where DefaultAllocator: Alloc { na::sup(a, b) } +/// Componentwise maximum between three vectors. pub fn max3(a: &Vec, b: &Vec, c: &Vec) -> Vec where DefaultAllocator: Alloc { max2(&max2(a, b), c) } +/// Componentwise maximum between four vectors. pub fn max4(a: &Vec, b: &Vec, c: &Vec, d: &Vec) -> Vec where DefaultAllocator: Alloc { max2(&max2(a, b), &max2(c, d)) } -pub fn min(x: &Vec,y: N) -> Vec +/// Componentwise maximum between a vector and a scalar. +pub fn min(x: &Vec, y: N) -> Vec where DefaultAllocator: Alloc { x.map(|x| na::inf(&x, &y)) } +/// Componentwise maximum between two vectors. pub fn min2(x: &Vec, y: &Vec) -> Vec where DefaultAllocator: Alloc { na::inf(x, y) } +/// Componentwise maximum between three vectors. pub fn min3(a: &Vec, b: &Vec, c: &Vec) -> Vec where DefaultAllocator: Alloc { min2(&min2(a, b), c) } +/// Componentwise maximum between four vectors. pub fn min4(a: &Vec, b: &Vec, c: &Vec, d: &Vec) -> Vec where DefaultAllocator: Alloc { min2(&min2(a, b), &min2(c, d)) diff --git a/nalgebra-glm/src/ext_vector_relational.rs b/nalgebra-glm/src/ext/vector_relational.rs similarity index 64% rename from nalgebra-glm/src/ext_vector_relational.rs rename to nalgebra-glm/src/ext/vector_relational.rs index ba505cb7..c7eeb1a5 100644 --- a/nalgebra-glm/src/ext_vector_relational.rs +++ b/nalgebra-glm/src/ext/vector_relational.rs @@ -3,21 +3,25 @@ use na::{DefaultAllocator}; use traits::{Alloc, Number, Dimension}; use aliases::Vec; +/// Component-wise approximate equality of two vectors, using a scalar epsilon. pub fn equal_eps(x: &Vec, y: &Vec, epsilon: N) -> Vec where DefaultAllocator: Alloc { - x.zip_map(y, |x, y| abs_diff_eq!(x, y)) + x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon)) } +/// Component-wise approximate equality of two vectors, using a per-component epsilon. pub fn equal_eps_vec(x: &Vec, y: &Vec, epsilon: &Vec) -> Vec where DefaultAllocator: Alloc { x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_eq!(x, y, epsilon = eps)) } +/// Component-wise approximate non-equality of two vectors, using a scalar epsilon. pub fn not_equal_eps(x: &Vec, y: &Vec, epsilon: N) -> Vec where DefaultAllocator: Alloc { - x.zip_map(y, |x, y| abs_diff_ne!(x, y)) + x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon)) } +/// Component-wise approximate non-equality of two vectors, using a per-component epsilon. pub fn not_equal_eps_vec(x: &Vec, y: &Vec, epsilon: &Vec) -> Vec where DefaultAllocator: Alloc { x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_ne!(x, y, epsilon = eps)) diff --git a/nalgebra-glm/src/ext_matrix_clip_space.rs b/nalgebra-glm/src/ext_matrix_clip_space.rs deleted file mode 100644 index 7efec074..00000000 --- a/nalgebra-glm/src/ext_matrix_clip_space.rs +++ /dev/null @@ -1,170 +0,0 @@ -use na::{Real, U4}; -use aliases::Mat; - -pub fn frustum(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn frustum_lh(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn frustum_lr_no(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn frustum_lh_zo(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn frustum_no(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn frustum_rh(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn frustum_rh_no(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn frustum_rh_zo(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn frustum_zo(left: N, right: N, bottom: N, top: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn infinite_perspective(fovy: N, aspect: N, near: N) -> Mat { - unimplemented!() -} - -pub fn infinite_perspective_lh(fovy: N, aspect: N, near: N) -> Mat { - unimplemented!() -} - -pub fn infinite_perspective_rh(fovy: N, aspect: N, near: N) -> Mat { - unimplemented!() -} - -pub fn infinite_ortho(left: N, right: N, bottom: N, top: N) -> Mat { - unimplemented!() -} - -pub fn ortho(left: N, right: N, bottom: N, top: N, zNear: N, zFar: N) -> Mat { - unimplemented!() -} - -pub fn ortho_lh(left: N, right: N, bottom: N, top: N, zNear: N, zFar: N) -> Mat { - unimplemented!() -} - -pub fn ortho_lh_no(left: N, right: N, bottom: N, top: N, zNear: N, zFar: N) -> Mat { - unimplemented!() -} - -pub fn ortho_lh_zo(left: N, right: N, bottom: N, top: N, zNear: N, zFar: N) -> Mat { - unimplemented!() -} - -pub fn ortho_no(left: N, right: N, bottom: N, top: N, zNear: N, zFar: N) -> Mat { - unimplemented!() -} - -pub fn ortho_rh(left: N, right: N, bottom: N, top: N, zNear: N, zFar: N) -> Mat { - unimplemented!() -} - -pub fn ortho_rh_no(left: N, right: N, bottom: N, top: N, zNear: N, zFar: N) -> Mat { - unimplemented!() -} - -pub fn ortho_rh_zo(left: N, right: N, bottom: N, top: N, zNear: N, zFar: N) -> Mat { - unimplemented!() -} - -pub fn ortho_zo(left: N, right: N, bottom: N, top: N, zNear: N, zFar: N) -> Mat { - unimplemented!() -} - -pub fn perspective(fovy: N, aspect: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_fov(fov: N, width: N, height: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_fov_lh(fov: N, width: N, height: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_fov_lh_no(fov: N, width: N, height: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_fov_lh_zo(fov: N, width: N, height: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_fov_no(fov: N, width: N, height: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_fov_rh(fov: N, width: N, height: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_fov_rh_no(fov: N, width: N, height: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_fov_rh_zo(fov: N, width: N, height: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_fov_zo(fov: N, width: N, height: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_lh(fovy: N, aspect: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_lh_no(fovy: N, aspect: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_lh_zo(fovy: N, aspect: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_no(fovy: N, aspect: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_rh(fovy: N, aspect: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_rh_no(fovy: N, aspect: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_rh_zo(fovy: N, aspect: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn perspective_zo(fovy: N, aspect: N, near: N, far: N) -> Mat { - unimplemented!() -} - -pub fn tweaked_infinite_perspective(fovy: N, aspect: N, near: N) -> Mat { - unimplemented!() -} - -pub fn tweaked_infinite_perspective_ep(fovy: N, aspect: N, near: N, ep: N) -> Mat { - unimplemented!() -} diff --git a/nalgebra-glm/src/ext_matrix_projection.rs b/nalgebra-glm/src/ext_matrix_projection.rs deleted file mode 100644 index 5d2a942a..00000000 --- a/nalgebra-glm/src/ext_matrix_projection.rs +++ /dev/null @@ -1,67 +0,0 @@ -use na::{self, Real, U2, U3, U4, Vector3, Vector4, Matrix4}; - -use aliases::{Mat, Vec}; - - -pub fn pick_matrix(center: &Vec, delta: &Vec, viewport: &Vec) -> Mat { - let shift = Vector3::new( - (viewport.z - (center.x - viewport.x) * na::convert(2.0)) / delta.x, - (viewport.w - (center.y - viewport.y) * na::convert(2.0)) / delta.y, - N::zero() - ); - - let result = Matrix4::new_translation(&shift); - result.prepend_nonuniform_scaling(&Vector3::new(viewport.z / delta.x, viewport.w / delta.y, N::one())) -} - -pub fn project(obj: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { - project_no(obj, model, proj, viewport) -} - -pub fn project_no(obj: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { - let proj = project_zo(obj, model, proj, viewport); - Vector3::new(proj.x, proj.y, proj.z * na::convert(0.5) + na::convert(0.5)) -} - -pub fn project_zo(obj: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { - let mut normalized = proj * model * Vector4::new(obj.x, obj.y, obj.z, N::one()); - let scale = N::one() / normalized.w; - - Vector3::new( - viewport.x + (viewport.z * (normalized.x * scale + N::one()) * na::convert(0.5)), - viewport.y + (viewport.w * (normalized.y * scale + N::one()) * na::convert(0.5)), - normalized.z * scale, - ) -} - -pub fn unproject(win: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { - unproject_no(win, model, proj, viewport) -} - -pub fn unproject_no(win: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { - let _2: N = na::convert(2.0); - let transform = (proj * model).try_inverse().unwrap_or(Matrix4::zeros()); - let pt = Vector4::new( - _2 * (win.x - viewport.x) / viewport.z - N::one(), - _2 * (win.y - viewport.y) / viewport.w - N::one(), - _2 * win.z - N::one(), - N::one(), - ); - - let result = transform * pt; - result.fixed_rows::(0) / result.w -} - -pub fn unproject_zo(win: &Vec, model: &Mat, proj: &Mat, viewport: Vec) -> Vec { - let _2: N = na::convert(2.0); - let transform = (proj * model).try_inverse().unwrap_or(Matrix4::zeros()); - let pt = Vector4::new( - _2 * (win.x - viewport.x) / viewport.z - N::one(), - _2 * (win.y - viewport.y) / viewport.w - N::one(), - win.z, - N::one(), - ); - - let result = transform * pt; - result.fixed_rows::(0) / result.w -} \ No newline at end of file diff --git a/nalgebra-glm/src/ext_matrix_relationnal.rs b/nalgebra-glm/src/ext_matrix_relationnal.rs deleted file mode 100644 index 21ab54ec..00000000 --- a/nalgebra-glm/src/ext_matrix_relationnal.rs +++ /dev/null @@ -1,59 +0,0 @@ -use na::DefaultAllocator; - -use aliases::{Vec, Mat}; -use traits::{Alloc, Number, Dimension}; - - -pub fn equal(x: &Mat, y: &Mat) -> Vec - where DefaultAllocator: Alloc { - let mut res = Vec::<_, C>::repeat(false); - - for i in 0..C::dim() { - res[i] = x.column(i) == y.column(i) - } - - res -} - -pub fn equal_eps(x: &Mat, y: &Mat, epsilon: N) -> Vec - where DefaultAllocator: Alloc { - equal_eps_vec(x, y, &Vec::<_, C>::repeat(epsilon)) -} - -pub fn equal_eps_vec(x: &Mat, y: &Mat, epsilon: &Vec) -> Vec - where DefaultAllocator: Alloc { - let mut res = Vec::<_, C>::repeat(false); - - for i in 0..C::dim() { - res[i] = (x.column(i) - y.column(i)).abs() < Vec::<_, R>::repeat(epsilon[i]) - } - - res -} - -pub fn not_equal(x: &Mat, y: &Mat) -> Vec - where DefaultAllocator: Alloc { - let mut res = Vec::<_, C>::repeat(false); - - for i in 0..C::dim() { - res[i] = x.column(i) != y.column(i) - } - - res -} - -pub fn not_equal_eps(x: &Mat, y: &Mat, epsilon: N) -> Vec - where DefaultAllocator: Alloc { - not_equal_eps_vec(x, y, &Vec::<_, C>::repeat(epsilon)) -} - -pub fn not_equal_eps_vec(x: &Mat, y: &Mat, epsilon: &Vec) -> Vec - where DefaultAllocator: Alloc { - let mut res = Vec::<_, C>::repeat(false); - - for i in 0..C::dim() { - res[i] = (x.column(i) - y.column(i)).abs() >= Vec::<_, R>::repeat(epsilon[i]) - } - - res -} diff --git a/nalgebra-glm/src/ext_matrix_transform.rs b/nalgebra-glm/src/ext_matrix_transform.rs deleted file mode 100644 index 6dff5ccc..00000000 --- a/nalgebra-glm/src/ext_matrix_transform.rs +++ /dev/null @@ -1,34 +0,0 @@ -use na::{DefaultAllocator, Scalar, Real, U3, U4, Unit, Rotation3, Point3}; - -use traits::{Dimension, Number, Alloc}; -use aliases::{Mat, Vec}; - -pub fn identity() -> Mat - where DefaultAllocator: Alloc { - Mat::::identity() -} - -/// Same as `look_at_rh` -pub fn look_at(eye: &Vec, center: &Vec, up: &Vec) -> Mat { - look_at_rh(eye, center, up) -} - -pub fn look_at_lh(eye: &Vec, center: &Vec, up: &Vec) -> Mat { - Mat::look_at_lh(&Point3::from_coordinates(*eye), &Point3::from_coordinates(*center), up) -} - -pub fn look_at_rh(eye: &Vec, center: &Vec, up: &Vec) -> Mat { - Mat::look_at_rh(&Point3::from_coordinates(*eye), &Point3::from_coordinates(*center), up) -} - -pub fn rotate(m: &Mat, angle: N, axis: &Vec) -> Mat { - m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous() -} - -pub fn scale(m: &Mat, v: &Vec) -> Mat { - m.prepend_nonuniform_scaling(v) -} - -pub fn translate(m: &Mat, v: &Vec) -> Mat { - m.prepend_translation(v) -} diff --git a/nalgebra-glm/src/geometric.rs b/nalgebra-glm/src/geometric.rs index 75050bd5..ad9910db 100644 --- a/nalgebra-glm/src/geometric.rs +++ b/nalgebra-glm/src/geometric.rs @@ -1,22 +1,26 @@ -use na::{self, Scalar, Real, U3, DefaultAllocator}; +use na::{Real, U3, DefaultAllocator}; use traits::{Number, Alloc, Dimension}; use aliases::Vec; +/// The cross product of two vectors. pub fn cross(x: &Vec, y: &Vec) -> Vec { x.cross(y) } +/// The distance between two points. pub fn distance(p0: &Vec, p1: &Vec) -> N where DefaultAllocator: Alloc { (p1 - p0).norm() } +/// The dot product of two vectors. pub fn dot(x: &Vec, y: &Vec) -> N where DefaultAllocator: Alloc { x.dot(y) } +/// If `dot(nref, i) < 0.0`, return `n`, otherwise, return `-n`. pub fn faceforward(n: &Vec, i: &Vec, nref: &Vec) -> Vec where DefaultAllocator: Alloc { if nref.dot(i) < N::zero() { @@ -26,22 +30,32 @@ pub fn faceforward(n: &Vec, i: &Vec, nref: } } +/// The magnitude of a vector. pub fn length(x: &Vec) -> N where DefaultAllocator: Alloc { x.norm() } +/// The magnitude of a vector. +pub fn magnitude(x: &Vec) -> N + where DefaultAllocator: Alloc { + x.norm() +} + +/// Normalizes a vector. pub fn normalize(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.normalize() } +/// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`. pub fn reflect(i: &Vec, n: &Vec) -> Vec where DefaultAllocator: Alloc { let _2 = N::one() + N::one(); i - n * (n.dot(i) * _2) } +/// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector. pub fn refract(i: &Vec, n: &Vec, eta: N) -> Vec where DefaultAllocator: Alloc { diff --git a/nalgebra-glm/src/gtc_bitfield.rs b/nalgebra-glm/src/gtc/bitfield.rs similarity index 100% rename from nalgebra-glm/src/gtc_bitfield.rs rename to nalgebra-glm/src/gtc/bitfield.rs diff --git a/nalgebra-glm/src/gtc_constants.rs b/nalgebra-glm/src/gtc/constants.rs similarity index 73% rename from nalgebra-glm/src/gtc_constants.rs rename to nalgebra-glm/src/gtc/constants.rs index ab9ebb2c..cfbf4ae7 100644 --- a/nalgebra-glm/src/gtc_constants.rs +++ b/nalgebra-glm/src/gtc/constants.rs @@ -1,111 +1,138 @@ use na::{self, Real}; use traits::Number; +/// The euler constant. pub fn e() -> N { N::e() } +/// The euler constant. pub fn euler() -> N { N::e() } +/// Returns `4 / pi`. pub fn four_over_pi() -> N { na::convert::<_, N>(4.0) / N::pi() } +/// Returns the golden ratio. pub fn golden_ratio() -> N { (N::one() + root_five()) / na::convert(2.0) } +/// Returns `4 / pi`. pub fn half_pi() -> N { N::frac_pi_2() } +/// Returns `4 / pi`. pub fn ln_ln_two() -> N { N::ln_2().ln() } +/// Returns `ln(10)`. pub fn ln_ten() -> N { N::ln_10() } +/// Returns `ln(2)`. pub fn ln_two() -> N { N::ln_2() } +/// Returns `1`. pub fn one() -> N { N::one() } +/// Returns `1 / pi`. pub fn one_over_pi() -> N { N::frac_1_pi() } +/// Returns `1 / sqrt(2)`. pub fn one_over_root_two() -> N { N::one() / root_two() } +/// Returns `1 / (2pi)`. pub fn one_over_two_pi() -> N { N::frac_1_pi() * na::convert(0.5) } +/// Returns `pi / 4`. pub fn quarter_pi() -> N { N::frac_pi_4() } +/// Returns `sqrt(5)`. pub fn root_five() -> N { na::convert::<_, N>(5.0).sqrt() } +/// Returns `sqrt(pi / 2)`. pub fn root_half_pi() -> N { (N::pi() / na::convert(2.0)).sqrt() } +/// Returns `sqrt(ln(4))`. pub fn root_ln_four() -> N { na::convert::<_, N>(4.0).sqrt() } +/// Returns the square root of pi. pub fn root_pi() -> N { N::pi().sqrt() } +/// Returns the square root of 3. pub fn root_three() -> N { na::convert::<_, N>(3.0).sqrt() } +/// Returns the square root of 2. pub fn root_two() -> N { // FIXME: there should be a ::sqrt_2() on the Real trait. na::convert::<_, N>(2.0).sqrt() } +/// Returns the square root of 2pi. pub fn root_two_pi() -> N { N::two_pi().sqrt() } +/// Returns `1 / 3. pub fn third() -> N { na::convert(1.0 / 2.0) } +/// Returns `3 / (2pi)`. pub fn three_over_two_pi() -> N { na::convert::<_, N>(3.0) / N::two_pi() } +/// Returns `2 / pi`. pub fn two_over_pi() -> N { N::frac_2_pi() } +/// Returns `2 / sqrt(pi)`. pub fn two_over_root_pi() -> N { N::frac_2_pi() } +/// Returns `2pi`. pub fn two_pi() -> N { N::two_pi() } +/// Returns `2 / 3`. pub fn two_thirds() -> N { na::convert(2.0 / 3.0) } +/// Returns `0`. pub fn zero() -> N { N::zero() } \ No newline at end of file diff --git a/nalgebra-glm/src/gtc/epsilon.rs b/nalgebra-glm/src/gtc/epsilon.rs new file mode 100644 index 00000000..91ba8503 --- /dev/null +++ b/nalgebra-glm/src/gtc/epsilon.rs @@ -0,0 +1,27 @@ +use approx::AbsDiffEq; +use na::DefaultAllocator; + +use traits::{Alloc, Number, Dimension}; +use aliases::Vec; + +/// Componentwise approximate equality beween two vectors. +pub fn epsilon_equal(x: &Vec, y: &Vec, epsilon: N) -> Vec + where DefaultAllocator: Alloc { + x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon)) +} + +/// Componentwise approximate equality beween two scalars. +pub fn epsilon_equal2>(x: N, y: N, epsilon: N) -> bool { + abs_diff_eq!(x, y, epsilon = epsilon) +} + +/// Componentwise approximate non-equality beween two vectors. +pub fn epsilon_not_equal(x: &Vec, y: &Vec, epsilon: N) -> Vec + where DefaultAllocator: Alloc { + x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon)) +} + +/// Componentwise approximate non-equality beween two scalars. +pub fn epsilon_not_equal2>(x: N, y: N, epsilon: N) -> bool { + abs_diff_ne!(x, y, epsilon = epsilon) +} diff --git a/nalgebra-glm/src/gtc_integer.rs b/nalgebra-glm/src/gtc/integer.rs similarity index 100% rename from nalgebra-glm/src/gtc_integer.rs rename to nalgebra-glm/src/gtc/integer.rs diff --git a/nalgebra-glm/src/gtc_matrix_access.rs b/nalgebra-glm/src/gtc/matrix_access.rs similarity index 82% rename from nalgebra-glm/src/gtc_matrix_access.rs rename to nalgebra-glm/src/gtc/matrix_access.rs index f8280e96..03b67fa5 100644 --- a/nalgebra-glm/src/gtc_matrix_access.rs +++ b/nalgebra-glm/src/gtc/matrix_access.rs @@ -3,11 +3,13 @@ use na::{Scalar, DefaultAllocator}; use traits::{Alloc, Dimension}; use aliases::{Vec, Mat}; +/// The `index`-th column of the matrix `m`. pub fn column(m: &Mat, index: usize) -> Vec where DefaultAllocator: Alloc { m.column(index).into_owned() } +/// Sets to `x` the `index`-th column of the matrix `m`. pub fn set_column(m: &Mat, index: usize, x: &Vec) -> Mat where DefaultAllocator: Alloc { let mut res = m.clone(); @@ -15,11 +17,13 @@ pub fn set_column(m: &Mat, index res } +/// The `index`-th row of the matrix `m`. pub fn row(m: &Mat, index: usize) -> Vec where DefaultAllocator: Alloc { m.row(index).into_owned().transpose() } +/// Sets to `x` the `index`-th row of the matrix `m`. pub fn set_row(m: &Mat, index: usize, x: &Vec) -> Mat where DefaultAllocator: Alloc { let mut res = m.clone(); diff --git a/nalgebra-glm/src/gtc_matrix_inverse.rs b/nalgebra-glm/src/gtc/matrix_inverse.rs similarity index 78% rename from nalgebra-glm/src/gtc_matrix_inverse.rs rename to nalgebra-glm/src/gtc/matrix_inverse.rs index c36210ea..ea5f2e06 100644 --- a/nalgebra-glm/src/gtc_matrix_inverse.rs +++ b/nalgebra-glm/src/gtc/matrix_inverse.rs @@ -1,14 +1,16 @@ -use na::{Real, DefaultAllocator, Transform, TAffine}; +use na::{Real, DefaultAllocator}; use traits::{Alloc, Dimension}; use aliases::Mat; +/// Fast matrix inverse for affine matrix. pub fn affine_inverse(m: Mat) -> Mat where DefaultAllocator: Alloc { // FIXME: this should be optimized. m.try_inverse().unwrap_or(Mat::<_, D, D>::zeros()) } +/// Compute the transpose of the inverse of a matrix. pub fn inverse_transpose(m: Mat) -> Mat where DefaultAllocator: Alloc { m.try_inverse().unwrap_or(Mat::<_, D, D>::zeros()).transpose() diff --git a/nalgebra-glm/src/gtc/mod.rs b/nalgebra-glm/src/gtc/mod.rs new file mode 100644 index 00000000..83078278 --- /dev/null +++ b/nalgebra-glm/src/gtc/mod.rs @@ -0,0 +1,26 @@ +//! (Reexported) Recommended features not specified by GLSL specification + +//pub use self::bitfield::*; +pub use self::constants::*; +pub use self::epsilon::*; +//pub use self::integer::*; +pub use self::matrix_access::*; +pub use self::matrix_inverse::*; +//pub use self::packing::*; +//pub use self::reciprocal::*; +//pub use self::round::*; +pub use self::type_ptr::*; +//pub use self::ulp::*; + + +//mod bitfield; +mod constants; +mod epsilon; +//mod integer; +mod matrix_access; +mod matrix_inverse; +//mod packing; +//mod reciprocal; +//mod round; +mod type_ptr; +//mod ulp; \ No newline at end of file diff --git a/nalgebra-glm/src/gtc_packing.rs b/nalgebra-glm/src/gtc/packing.rs similarity index 100% rename from nalgebra-glm/src/gtc_packing.rs rename to nalgebra-glm/src/gtc/packing.rs diff --git a/nalgebra-glm/src/gtc_reciprocal.rs b/nalgebra-glm/src/gtc/reciprocal.rs similarity index 100% rename from nalgebra-glm/src/gtc_reciprocal.rs rename to nalgebra-glm/src/gtc/reciprocal.rs diff --git a/nalgebra-glm/src/gtc_round.rs b/nalgebra-glm/src/gtc/round.rs similarity index 100% rename from nalgebra-glm/src/gtc_round.rs rename to nalgebra-glm/src/gtc/round.rs diff --git a/nalgebra-glm/src/gtc_type_ptr.rs b/nalgebra-glm/src/gtc/type_ptr.rs similarity index 56% rename from nalgebra-glm/src/gtc_type_ptr.rs rename to nalgebra-glm/src/gtc/type_ptr.rs index 49bb63d2..1c99440a 100644 --- a/nalgebra-glm/src/gtc_type_ptr.rs +++ b/nalgebra-glm/src/gtc/type_ptr.rs @@ -5,140 +5,211 @@ use na::{Scalar, Real, U1, U2, U3, U4, DefaultAllocator, use traits::{Number, Alloc, Dimension}; use aliases::{Qua, Vec, Mat}; - +/// Creates a 2x2 matrix from a slice arranged in column-major order. pub fn make_mat2(ptr: &[N]) -> Mat { Matrix2::from_column_slice(ptr) } +/// Creates a 2x2 matrix from a slice arranged in column-major order. pub fn make_mat2x2(ptr: &[N]) -> Mat { Matrix2::from_column_slice(ptr) } +/// Creates a 2x3 matrix from a slice arranged in column-major order. pub fn make_mat2x3(ptr: &[N]) -> Mat { Matrix2x3::from_column_slice(ptr) } +/// Creates a 2x4 matrix from a slice arranged in column-major order. pub fn make_mat2x4(ptr: &[N]) -> Mat { Matrix2x4::from_column_slice(ptr) } +/// Creates a 3 matrix from a slice arranged in column-major order. pub fn make_mat3(ptr: &[N]) -> Mat { Matrix3::from_column_slice(ptr) } +/// Creates a 3x2 matrix from a slice arranged in column-major order. pub fn make_mat3x2(ptr: &[N]) -> Mat { Matrix3x2::from_column_slice(ptr) } +/// Creates a 3x3 matrix from a slice arranged in column-major order. pub fn make_mat3x3(ptr: &[N]) -> Mat { Matrix3::from_column_slice(ptr) } +/// Creates a 3x4 matrix from a slice arranged in column-major order. pub fn make_mat3x4(ptr: &[N]) -> Mat { Matrix3x4::from_column_slice(ptr) } +/// Creates a 4x4 matrix from a slice arranged in column-major order. pub fn make_mat4(ptr: &[N]) -> Mat { Matrix4::from_column_slice(ptr) } +/// Creates a 4x2 matrix from a slice arranged in column-major order. pub fn make_mat4x2(ptr: &[N]) -> Mat { Matrix4x2::from_column_slice(ptr) } +/// Creates a 4x3 matrix from a slice arranged in column-major order. pub fn make_mat4x3(ptr: &[N]) -> Mat { Matrix4x3::from_column_slice(ptr) } +/// Creates a 4x4 matrix from a slice arranged in column-major order. pub fn make_mat4x4(ptr: &[N]) -> Mat { Matrix4::from_column_slice(ptr) } +/// Creates a quaternion from a slice arranged as `[x, y, z, w]`. pub fn make_quat(ptr: &[N]) -> Qua { Quaternion::from_vector(Vector4::from_column_slice(ptr)) } +/// Creates a 1D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec1(v: &Vec) -> Vec { *v } +/// Creates a 1D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec1_2(v: &Vec) -> Vec { Vector1::new(v.x) } +/// Creates a 1D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec1_3(v: &Vec) -> Vec { Vector1::new(v.x) } +/// Creates a 1D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec1_4(v: &Vec) -> Vec { Vector1::new(v.x) } +/// Creates a 2D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec2_1(v: &Vec) -> Vec { Vector2::new(v.x, N::zero()) } +/// Creates a 2D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec2_2(v: &Vec) -> Vec { *v } +/// Creates a 2D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec2_3(v: &Vec) -> Vec { Vector2::new(v.x, v.y) } +/// Creates a 2D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec2_4(v: &Vec) -> Vec { Vector2::new(v.x, v.y) } +/// Creates a 2D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec2(ptr: &[N]) -> Vec { Vector2::from_column_slice(ptr) } +/// Creates a 3D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec3_1(v: &Vec) -> Vec { Vector3::new(v.x, N::zero(), N::zero()) } +/// Creates a 3D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec3_2(v: &Vec) -> Vec { Vector3::new(v.x, v.y, N::zero()) } +/// Creates a 3D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec3_3(v: &Vec) -> Vec { *v } +/// Creates a 3D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec3_4(v: &Vec) -> Vec { Vector3::new(v.x, v.y, v.z) } +/// Creates a 3D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec3(ptr: &[N]) -> Vec { Vector3::from_column_slice(ptr) } +/// Creates a 4D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec4_1(v: &Vec) -> Vec { Vector4::new(v.x, N::zero(), N::zero(), N::zero()) } +/// Creates a 4D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec4_2(v: &Vec) -> Vec { Vector4::new(v.x, v.y, N::zero(), N::zero()) } +/// Creates a 4D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec4_3(v: &Vec) -> Vec { Vector4::new(v.x, v.y, v.z, N::zero()) } +/// Creates a 4D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec4_4(v: &Vec) -> Vec { *v } +/// Creates a 4D vector from another vector. +/// +/// Missing components, if any, are set to 0. pub fn make_vec4(ptr: &[N]) -> Vec { Vector4::from_column_slice(ptr) } +/// Converts a matrix or vector to a slice arranged in column-major order. pub fn value_ptr(x: &Mat) -> &[N] where DefaultAllocator: Alloc { x.as_slice() } +/// Converts a matrix or vector to a mutable slice arranged in column-major order. pub fn value_ptr_mut(x: &mut Mat) -> &mut [N] where DefaultAllocator: Alloc { x.as_mut_slice() diff --git a/nalgebra-glm/src/gtc_ulp.rs b/nalgebra-glm/src/gtc/ulp.rs similarity index 100% rename from nalgebra-glm/src/gtc_ulp.rs rename to nalgebra-glm/src/gtc/ulp.rs diff --git a/nalgebra-glm/src/gtc_epsilon.rs b/nalgebra-glm/src/gtc_epsilon.rs deleted file mode 100644 index 5b5b4c2a..00000000 --- a/nalgebra-glm/src/gtc_epsilon.rs +++ /dev/null @@ -1,23 +0,0 @@ -use approx::AbsDiffEq; -use na::DefaultAllocator; - -use traits::{Alloc, Number, Dimension}; -use aliases::Vec; - -pub fn epsilonEqual(x: &Vec, y: &Vec, epsilon: N) -> Vec - where DefaultAllocator: Alloc { - x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon)) -} - -pub fn epsilonEqual2>(x: N, y: N, epsilon: N) -> bool { - abs_diff_eq!(x, y, epsilon = epsilon) -} - -pub fn epsilonNotEqual(x: &Vec, y: &Vec, epsilon: N) -> Vec - where DefaultAllocator: Alloc { - x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon)) -} - -pub fn epsilonNotEqual2>(x: N, y: N, epsilon: N) -> bool { - abs_diff_ne!(x, y, epsilon = epsilon) -} diff --git a/nalgebra-glm/src/gtx_component_wise.rs b/nalgebra-glm/src/gtx/component_wise.rs similarity index 75% rename from nalgebra-glm/src/gtx_component_wise.rs rename to nalgebra-glm/src/gtx/component_wise.rs index 9d8a74b1..acff2a93 100644 --- a/nalgebra-glm/src/gtx_component_wise.rs +++ b/nalgebra-glm/src/gtx/component_wise.rs @@ -1,24 +1,27 @@ -use na::{self, Scalar, Real, DefaultAllocator}; +use na::{self, DefaultAllocator}; use traits::{Number, Alloc, Dimension}; use aliases::Mat; - +/// The sum of every components of the given matrix or vector. pub fn comp_add(m: &Mat) -> N where DefaultAllocator: Alloc { m.iter().fold(N::zero(), |x, y| x + *y) } +/// The maximum of every components of the given matrix or vector. pub fn comp_max(m: &Mat) -> N where DefaultAllocator: Alloc { m.iter().fold(N::min_value(), |x, y| na::sup(&x, y)) } +/// The minimum of every components of the given matrix or vector. pub fn comp_min(m: &Mat) -> N where DefaultAllocator: Alloc { m.iter().fold(N::max_value(), |x, y| na::inf(&x, y)) } +/// The product of every components of the given matrix or vector. pub fn comp_mul(m: &Mat) -> N where DefaultAllocator: Alloc { m.iter().fold(N::one(), |x, y| x * *y) diff --git a/nalgebra-glm/src/gtx/euler_angles.rs b/nalgebra-glm/src/gtx/euler_angles.rs new file mode 100644 index 00000000..cd1e0a48 --- /dev/null +++ b/nalgebra-glm/src/gtx/euler_angles.rs @@ -0,0 +1,163 @@ +use na::{Real, U3, U4}; + +use aliases::{Vec, Mat}; + +pub fn derivedEulerAngleX(angleX: N, angularVelocityX: N) -> Mat { + unimplemented!() +} + +pub fn derivedEulerAngleY(angleY: N, angularVelocityY: N) -> Mat { + unimplemented!() +} + +pub fn derivedEulerAngleZ(angleZ: N, angularVelocityZ: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleX(angleX: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleXY(angleX: N, angleY: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleXYX(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleXYZ(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleXZ(angleX: N, angleZ: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleXZX(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleXZY(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleY(angleY: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleYX(angleY: N, angleX: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleYXY(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleYXZ(yaw: N, pitch: N, roll: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleYZ(angleY: N, angleZ: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleYZX(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleYZY(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleZ(angleZ: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleZX(angle: N, angleX: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleZXY(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleZXZ(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleZY(angleZ: N, angleY: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleZYX(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn eulerAngleZYZ(t1: N, t2: N, t3: N) -> Mat { + unimplemented!() +} + +pub fn extractEulerAngleXYX(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleXYZ(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleXZX(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleXZY(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleYXY(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleYXZ(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleYZX(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleYZY(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleZXY(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleZXZ(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleZYX(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn extractEulerAngleZYZ(M: &Mat) -> (N, N, N) { + unimplemented!() +} + +pub fn orientate2(angle: N) -> Mat { + unimplemented!() +} + +pub fn orientate3(angles: Vec) -> Mat { + unimplemented!() +} + +pub fn orientate4(angles: Vec) -> Mat { + unimplemented!() +} + +pub fn yawPitchRoll(yaw: N, pitch: N, roll: N) -> Mat { + unimplemented!() +} diff --git a/nalgebra-glm/src/gtx_exterior_product.rs b/nalgebra-glm/src/gtx/exterior_product.rs similarity index 70% rename from nalgebra-glm/src/gtx_exterior_product.rs rename to nalgebra-glm/src/gtx/exterior_product.rs index 2d1f9993..9653e80f 100644 --- a/nalgebra-glm/src/gtx_exterior_product.rs +++ b/nalgebra-glm/src/gtx/exterior_product.rs @@ -3,6 +3,7 @@ use na::U2; use traits::Number; use aliases::Vec; +/// The 2D perpendicular product between two vectors. pub fn cross(v: &Vec, u: &Vec) -> N { v.perp(u) } \ No newline at end of file diff --git a/nalgebra-glm/src/gtx_handed_coordinate_space.rs b/nalgebra-glm/src/gtx/handed_coordinate_space.rs similarity index 69% rename from nalgebra-glm/src/gtx_handed_coordinate_space.rs rename to nalgebra-glm/src/gtx/handed_coordinate_space.rs index 9b5d9634..1a68fcf3 100644 --- a/nalgebra-glm/src/gtx_handed_coordinate_space.rs +++ b/nalgebra-glm/src/gtx/handed_coordinate_space.rs @@ -3,10 +3,12 @@ use na::U3; use traits::Number; use aliases::Vec; +/// Returns `true` if `{a, b, c}` forms a left-handed trihedron. pub fn left_handed(a: &Vec, b: &Vec, c: &Vec) -> bool { a.cross(b).dot(c) < N::zero() } +/// Returns `true` if `{a, b, c}` forms a right-handed trihedron. pub fn right_handed(a: &Vec, b: &Vec, c: &Vec) -> bool { a.cross(b).dot(c) > N::zero() } diff --git a/nalgebra-glm/src/gtx_matrix_cross_product.rs b/nalgebra-glm/src/gtx/matrix_cross_product.rs similarity index 72% rename from nalgebra-glm/src/gtx_matrix_cross_product.rs rename to nalgebra-glm/src/gtx/matrix_cross_product.rs index e247c2ab..1cbaddc8 100644 --- a/nalgebra-glm/src/gtx_matrix_cross_product.rs +++ b/nalgebra-glm/src/gtx/matrix_cross_product.rs @@ -1,11 +1,13 @@ -use na::{self, Real, U3, U4, Matrix4}; +use na::{Real, U3, U4, Matrix4}; use aliases::{Vec, Mat}; +/// Builds a 3x3 matrix `m` such that for any `v`: `m * v == cross(x, v)`. pub fn matrix_cross3(x: &Vec) -> Mat { x.cross_matrix() } +/// Builds a 4x4 matrix `m` such that for any `v`: `m * v == cross(x, v)`. pub fn matrix_cross4(x: &Vec) -> Mat { let m = x.cross_matrix(); diff --git a/nalgebra-glm/src/gtx_matrix_operation.rs b/nalgebra-glm/src/gtx/matrix_operation.rs similarity index 79% rename from nalgebra-glm/src/gtx_matrix_operation.rs rename to nalgebra-glm/src/gtx/matrix_operation.rs index 1cd8d300..b915808f 100644 --- a/nalgebra-glm/src/gtx_matrix_operation.rs +++ b/nalgebra-glm/src/gtx/matrix_operation.rs @@ -4,39 +4,47 @@ use na::{Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4, Matrix4, use traits::Number; use aliases::{Vec, Mat}; - +/// Builds a 2x2 diagonal matrix. pub fn diagonal2x2(v: &Vec) -> Mat { Matrix2::from_diagonal(v) } +/// Builds a 2x3 diagonal matrix. pub fn diagonal2x3(v: &Vec) -> Mat { Matrix2x3::from_partial_diagonal(v.as_slice()) } +/// Builds a 2x4 diagonal matrix. pub fn diagonal2x4(v: &Vec) -> Mat { Matrix2x4::from_partial_diagonal(v.as_slice()) } +/// Builds a 3x2 diagonal matrix. pub fn diagonal3x2(v: &Vec) -> Mat { Matrix3x2::from_partial_diagonal(v.as_slice()) } +/// Builds a 3x3 diagonal matrix. pub fn diagonal3x3(v: &Vec) -> Mat { Matrix3::from_diagonal(v) } +/// Builds a 3x4 diagonal matrix. pub fn diagonal3x4(v: &Vec) -> Mat { Matrix3x4::from_partial_diagonal(v.as_slice()) } +/// Builds a 4x2 diagonal matrix. pub fn diagonal4x2(v: &Vec) -> Mat { Matrix4x2::from_partial_diagonal(v.as_slice()) } +/// Builds a 4x3 diagonal matrix. pub fn diagonal4x3(v: &Vec) -> Mat { Matrix4x3::from_partial_diagonal(v.as_slice()) } +/// Builds a 4x4 diagonal matrix. pub fn diagonal4x4(v: &Vec) -> Mat { Matrix4::from_diagonal(v) } diff --git a/nalgebra-glm/src/gtx/mod.rs b/nalgebra-glm/src/gtx/mod.rs new file mode 100644 index 00000000..fa4294b9 --- /dev/null +++ b/nalgebra-glm/src/gtx/mod.rs @@ -0,0 +1,38 @@ +//! (Reexported) Experimental features not specified by GLSL specification. + + +pub use self::component_wise::*; +//pub use self::euler_angles::*; +pub use self::exterior_product::*; +pub use self::handed_coordinate_space::*; +pub use self::matrix_cross_product::*; +pub use self::matrix_operation::*; +pub use self::norm::*; +pub use self::normal::*; +pub use self::normalize_dot::*; +pub use self::rotate_normalized_axis::*; +pub use self::rotate_vector::*; +pub use self::transform::*; +pub use self::transform2::*; +pub use self::transform2d::*; +pub use self::vector_angle::*; +pub use self::vector_query::*; + + + +mod component_wise; +//mod euler_angles; +mod exterior_product; +mod handed_coordinate_space; +mod matrix_cross_product; +mod matrix_operation; +mod norm; +mod normal; +mod normalize_dot; +mod rotate_normalized_axis; +mod rotate_vector; +mod transform; +mod transform2; +mod transform2d; +mod vector_angle; +mod vector_query; \ No newline at end of file diff --git a/nalgebra-glm/src/gtx_norm.rs b/nalgebra-glm/src/gtx/norm.rs similarity index 77% rename from nalgebra-glm/src/gtx_norm.rs rename to nalgebra-glm/src/gtx/norm.rs index dddbf743..37b5655c 100644 --- a/nalgebra-glm/src/gtx_norm.rs +++ b/nalgebra-glm/src/gtx/norm.rs @@ -3,36 +3,48 @@ use na::{Real, DefaultAllocator}; use traits::{Alloc, Dimension}; use aliases::Vec; +/// The squared distance between two points. pub fn distance2(p0: &Vec, p1: &Vec) -> N where DefaultAllocator: Alloc { (p1 - p0).norm_squared() } +/// The l1-norm of `x - y`. pub fn l1_distance(x: &Vec, y: &Vec) -> N where DefaultAllocator: Alloc { l1_norm(&(x - y)) } +/// The l1-norm of `v`. pub fn l1_norm(v: &Vec) -> N where DefaultAllocator: Alloc { ::comp_add(&v.abs()) } +/// The l2-norm of `x - y`. pub fn l2_distance(x: &Vec, y: &Vec) -> N where DefaultAllocator: Alloc { l2_norm(&(y - x)) } +/// The l2-norm of `v`. pub fn l2_norm(x: &Vec) -> N where DefaultAllocator: Alloc { x.norm() } +/// The squared magnitude of `x`. pub fn length2(x: &Vec) -> N where DefaultAllocator: Alloc { x.norm_squared() } +/// The squared magnitude of `x`. +pub fn magnitude2(x: &Vec) -> N + where DefaultAllocator: Alloc { + x.norm_squared() +} + //pub fn lxNorm(x: &Vec, y: &Vec, unsigned int Depth) -> N // where DefaultAllocator: Alloc { // unimplemented!() diff --git a/nalgebra-glm/src/gtx/normal.rs b/nalgebra-glm/src/gtx/normal.rs new file mode 100644 index 00000000..01418490 --- /dev/null +++ b/nalgebra-glm/src/gtx/normal.rs @@ -0,0 +1,10 @@ +use na::{Real, U3}; + +use aliases::Vec; + +/// The normal vector of the given triangle. +/// +/// The normal is computed as the normalized vector `cross(p2 - p1, p3 - p1)`. +pub fn triangle_normal(p1: &Vec, p2: &Vec, p3: &Vec) -> Vec { + (p2 - p1).cross(&(p3 - p1)).normalize() +} \ No newline at end of file diff --git a/nalgebra-glm/src/gtx_normalize_dot.rs b/nalgebra-glm/src/gtx/normalize_dot.rs similarity index 51% rename from nalgebra-glm/src/gtx_normalize_dot.rs rename to nalgebra-glm/src/gtx/normalize_dot.rs index e51331d5..07855b2f 100644 --- a/nalgebra-glm/src/gtx_normalize_dot.rs +++ b/nalgebra-glm/src/gtx/normalize_dot.rs @@ -3,14 +3,15 @@ use na::{Real, DefaultAllocator}; use traits::{Dimension, Alloc}; use aliases::Vec; - -pub fn fastNormalizeDot(x: &Vec, y: &Vec) -> N +/// The dot product of the normalized version of `x` and `y`. +pub fn fast_normalize_dot(x: &Vec, y: &Vec) -> N where DefaultAllocator: Alloc { // XXX: improve those. x.normalize().dot(&y.normalize()) } -pub fn normalizeDot(x: &Vec, y: &Vec) -> N +/// The dot product of the normalized version of `x` and `y`. +pub fn normalize_dot(x: &Vec, y: &Vec) -> N where DefaultAllocator: Alloc { // XXX: improve those. x.normalize().dot(&y.normalize()) diff --git a/nalgebra-glm/src/gtx/rotate_normalized_axis.rs b/nalgebra-glm/src/gtx/rotate_normalized_axis.rs new file mode 100644 index 00000000..e465da8d --- /dev/null +++ b/nalgebra-glm/src/gtx/rotate_normalized_axis.rs @@ -0,0 +1,13 @@ +use na::{Real, Rotation3, Unit, U3, U4}; + +use aliases::{Vec, Mat}; + +/// Builds a rotation 4 * 4 matrix created from a normalized axis and an angle. +/// +/// # Parameters +/// * `m` - Input matrix multiplied by this rotation matrix. +/// * `angle` - Rotation angle expressed in radians. +/// * `axis` - Rotation axis, must be normalized. +pub fn rotate_normalized_axis(m: &Mat, angle: N, axis: &Vec) -> Mat { + m * Rotation3::from_axis_angle(&Unit::new_unchecked(*axis), angle).to_homogeneous() +} \ No newline at end of file diff --git a/nalgebra-glm/src/gtx_rotate_vector.rs b/nalgebra-glm/src/gtx/rotate_vector.rs similarity index 51% rename from nalgebra-glm/src/gtx_rotate_vector.rs rename to nalgebra-glm/src/gtx/rotate_vector.rs index 666190f7..eceef954 100644 --- a/nalgebra-glm/src/gtx_rotate_vector.rs +++ b/nalgebra-glm/src/gtx/rotate_vector.rs @@ -2,6 +2,7 @@ use na::{Real, U2, U3, U4, Rotation3, Vector3, Unit, UnitComplex}; use aliases::{Vec, Mat}; +/// Build the rotation matrix needed to align `normal` and `up`. pub fn orientation(normal: &Vec, up: &Vec) -> Mat { if let Some(r) = Rotation3::rotation_between(normal, up) { r.to_homogeneous() @@ -10,42 +11,52 @@ pub fn orientation(normal: &Vec, up: &Vec) -> Mat(v: &Vec, angle: N) -> Vec { UnitComplex::new(angle) * v } +/// Rotate a three dimensional vector around an axis. pub fn rotate(v: &Vec, angle: N, normal: &Vec) -> Vec { Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle) * v } +/// Rotate a thee dimensional vector in homogeneous coordinates around an axis. pub fn rotate4(v: &Vec, angle: N, normal: &Vec) -> Vec { Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle).to_homogeneous() * v } -pub fn rotateX(v: &Vec, angle: N) -> Vec { +/// Rotate a three dimensional vector around the `X` axis. +pub fn rotate_x(v: &Vec, angle: N) -> Vec { Rotation3::from_axis_angle(&Vector3::x_axis(), angle) * v } -pub fn rotateX4(v: &Vec, angle: N) -> Vec { +/// Rotate a three dimensional vector in homogeneous coordinates around the `X` axis. +pub fn rotate_x4(v: &Vec, angle: N) -> Vec { Rotation3::from_axis_angle(&Vector3::x_axis(), angle).to_homogeneous() * v } -pub fn rotateY(v: &Vec, angle: N) -> Vec { +/// Rotate a three dimensional vector around the `Y` axis. +pub fn rotate_y(v: &Vec, angle: N) -> Vec { Rotation3::from_axis_angle(&Vector3::y_axis(), angle) * v } -pub fn rotateY4(v: &Vec, angle: N) -> Vec { +/// Rotate a three dimensional vector in homogeneous coordinates around the `Y` axis. +pub fn rotate_y4(v: &Vec, angle: N) -> Vec { Rotation3::from_axis_angle(&Vector3::y_axis(), angle).to_homogeneous() * v } -pub fn rotateZ(v: &Vec, angle: N) -> Vec { +/// Rotate a three dimensional vector around the `Z` axis. +pub fn rotate_z(v: &Vec, angle: N) -> Vec { Rotation3::from_axis_angle(&Vector3::z_axis(), angle) * v } -pub fn rotateZ4(v: &Vec, angle: N) -> Vec { +/// Rotate a three dimensional vector in homogeneous coordinates around the `Z` axis. +pub fn rotate_z4(v: &Vec, angle: N) -> Vec { Rotation3::from_axis_angle(&Vector3::z_axis(), angle).to_homogeneous() * v } +/// Computes a spehical linear interpolation between the vectors `x` and `y` assumed to be normalized. pub fn slerp(x: &Vec, y: &Vec, a: N) -> Vec { - unimplemented!() + Unit::new_unchecked(*x).slerp(&Unit::new_unchecked(*y), a).unwrap() } diff --git a/nalgebra-glm/src/gtx_transform.rs b/nalgebra-glm/src/gtx/transform.rs similarity index 62% rename from nalgebra-glm/src/gtx_transform.rs rename to nalgebra-glm/src/gtx/transform.rs index 698c68e6..065c0079 100644 --- a/nalgebra-glm/src/gtx_transform.rs +++ b/nalgebra-glm/src/gtx/transform.rs @@ -3,15 +3,17 @@ use na::{Real, Unit, Rotation3, Matrix4, U3, U4}; use traits::Number; use aliases::{Vec, Mat}; - +/// Builds a rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in radians. pub fn rotate(angle: N, v: &Vec) -> Mat { Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous() } +/// Transforms a matrix with a scale 4 * 4 matrix created from a vector of 3 components. pub fn scale(v: &Vec) -> Mat { Matrix4::new_nonuniform_scaling(v) } +/// Transforms a matrix with a translation 4 * 4 matrix created from 3 scalars. pub fn translate(v: &Vec) -> Mat { Matrix4::new_translation(v) } diff --git a/nalgebra-glm/src/gtx_transform2.rs b/nalgebra-glm/src/gtx/transform2.rs similarity index 54% rename from nalgebra-glm/src/gtx_transform2.rs rename to nalgebra-glm/src/gtx/transform2.rs index 3d3477cd..09a788be 100644 --- a/nalgebra-glm/src/gtx_transform2.rs +++ b/nalgebra-glm/src/gtx/transform2.rs @@ -1,9 +1,10 @@ -use na::{self, U2, U3, U4, Matrix3, Matrix4}; +use na::{U2, U3, U4, Matrix3, Matrix4}; use traits::Number; use aliases::{Mat, Vec}; -pub fn proj2D(m: &Mat, normal: &Vec) -> Mat { +/// Build planar projection matrix along normal axis and right-multiply it to `m`. +pub fn proj2(m: &Mat, normal: &Vec) -> Mat { let mut res = Matrix3::identity(); { @@ -11,10 +12,11 @@ pub fn proj2D(m: &Mat, normal: &Vec) -> Mat(m: &Mat, normal: &Vec) -> Mat { +/// Build planar projection matrix along normal axis, and right-multiply it to `m`. +pub fn proj3(m: &Mat, normal: &Vec) -> Mat { let mut res = Matrix4::identity(); { @@ -22,10 +24,11 @@ pub fn proj3D(m: &Mat, normal: &Vec) -> Mat(m: &Mat, normal: &Vec) -> Mat { +/// Builds a reflection matrix and right-multiply it to `m`. +pub fn reflect2(m: &Mat, normal: &Vec) -> Mat { let mut res = Matrix3::identity(); { @@ -33,10 +36,11 @@ pub fn reflect2D(m: &Mat, normal: &Vec) -> Mat(m: &Mat, normal: &Vec) -> Mat { +/// Builds a reflection matrix, and right-multiply it to `m`. +pub fn reflect3(m: &Mat, normal: &Vec) -> Mat { let mut res = Matrix4::identity(); { @@ -44,10 +48,11 @@ pub fn reflect3D(m: &Mat, normal: &Vec) -> Mat(scale: N, bias: N) -> Mat { +/// Builds a scale-bias matrix. +pub fn scale_bias(scale: N, bias: N) -> Mat { let _0 = N::zero(); let _1 = N::one(); @@ -59,11 +64,13 @@ pub fn scaleBias(scale: N, bias: N) -> Mat { ) } -pub fn scaleBias2(m: &Mat, scale: N, bias: N) -> Mat { - m * scaleBias(scale, bias) +/// Builds a scale-bias matrix, and right-multiply it to `m`. +pub fn scale_bias2(m: &Mat, scale: N, bias: N) -> Mat { + m * scale_bias(scale, bias) } -pub fn shearX2D(m: &Mat, y: N) -> Mat { +/// Transforms a matrix with a shearing on X axis. +pub fn shear_x2(m: &Mat, y: N) -> Mat { let _0 = N::zero(); let _1 = N::one(); @@ -75,7 +82,8 @@ pub fn shearX2D(m: &Mat, y: N) -> Mat { m * shear } -pub fn shearX3D(m: &Mat, y: N, z: N) -> Mat { +/// Transforms a matrix with a shearing on Y axis. +pub fn shear_x3(m: &Mat, y: N, z: N) -> Mat { let _0 = N::zero(); let _1 = N::one(); let shear = Matrix4::new( @@ -88,7 +96,8 @@ pub fn shearX3D(m: &Mat, y: N, z: N) -> Mat { m * shear } -pub fn shearY2D(m: &Mat, x: N) -> Mat { +/// Transforms a matrix with a shearing on Y axis. +pub fn shear_y2(m: &Mat, x: N) -> Mat { let _0 = N::zero(); let _1 = N::one(); @@ -100,7 +109,8 @@ pub fn shearY2D(m: &Mat, x: N) -> Mat { m * shear } -pub fn shearY3D(m: &Mat, x: N, z: N) -> Mat { +/// Transforms a matrix with a shearing on Y axis. +pub fn shear_y3(m: &Mat, x: N, z: N) -> Mat { let _0 = N::zero(); let _1 = N::one(); let shear = Matrix4::new( @@ -113,7 +123,8 @@ pub fn shearY3D(m: &Mat, x: N, z: N) -> Mat { m * shear } -pub fn shearZ3D(m: &Mat, x: N, y: N) -> Mat { +/// Transforms a matrix with a shearing on Z axis. +pub fn shear_z3d(m: &Mat, x: N, y: N) -> Mat { let _0 = N::zero(); let _1 = N::one(); let shear = Matrix4::new( diff --git a/nalgebra-glm/src/gtx_transform2d.rs b/nalgebra-glm/src/gtx/transform2d.rs similarity index 60% rename from nalgebra-glm/src/gtx_transform2d.rs rename to nalgebra-glm/src/gtx/transform2d.rs index b04a8275..9e4de825 100644 --- a/nalgebra-glm/src/gtx_transform2d.rs +++ b/nalgebra-glm/src/gtx/transform2d.rs @@ -3,15 +3,18 @@ use na::{Real, U2, U3, UnitComplex, Matrix3}; use traits::Number; use aliases::{Mat, Vec}; +/// Builds a 2D rotation matrix from an angle and right-multiply it to `m`. pub fn rotate(m: &Mat, angle: N) -> Mat { m * UnitComplex::new(angle).to_homogeneous() } +/// Builds a 2D scaling matrix and right-multiply it to `m`. pub fn scale(m: &Mat, v: &Vec) -> Mat { m.prepend_nonuniform_scaling(v) } -pub fn shearX(m: &Mat, y: N) -> Mat { +/// Builds a 2D shearing matrix on the `X` axis and right-multiply it to `m`. +pub fn shear_x(m: &Mat, y: N) -> Mat { let _0 = N::zero(); let _1 = N::one(); @@ -23,7 +26,8 @@ pub fn shearX(m: &Mat, y: N) -> Mat { m * shear } -pub fn shearY(m: &Mat, x: N) -> Mat { +/// Builds a 2D shearing matrix on the `Y` axis and right-multiply it to `m`. +pub fn shear_y(m: &Mat, x: N) -> Mat { let _0 = N::zero(); let _1 = N::one(); @@ -35,6 +39,7 @@ pub fn shearY(m: &Mat, x: N) -> Mat { m * shear } +/// Builds a translation matrix and right-multiply it to `m`. pub fn translate(m: &Mat, v: &Vec) -> Mat { m.prepend_translation(v) } diff --git a/nalgebra-glm/src/gtx/vector_angle.rs b/nalgebra-glm/src/gtx/vector_angle.rs new file mode 100644 index 00000000..a3231456 --- /dev/null +++ b/nalgebra-glm/src/gtx/vector_angle.rs @@ -0,0 +1,19 @@ +use na::{DefaultAllocator, Real}; + +use traits::{Dimension, Alloc}; +use aliases::Vec; + + +/// The angle between two vectors. +pub fn angle(x: &Vec, y: &Vec) -> N + where DefaultAllocator: Alloc { + x.angle(y) +} + +//pub fn oriented_angle(x: &Vec, y: &Vec) -> N { +// unimplemented!() +//} +// +//pub fn oriented_angle_ref(x: &Vec, y: &Vec, refv: &Vec) -> N { +// unimplemented!() +//} diff --git a/nalgebra-glm/src/gtx_vector_query.rs b/nalgebra-glm/src/gtx/vector_query.rs similarity index 66% rename from nalgebra-glm/src/gtx_vector_query.rs rename to nalgebra-glm/src/gtx/vector_query.rs index ef5a7e21..8eb8fd2c 100644 --- a/nalgebra-glm/src/gtx_vector_query.rs +++ b/nalgebra-glm/src/gtx/vector_query.rs @@ -3,34 +3,40 @@ use na::{Real, DefaultAllocator, U2, U3}; use traits::{Number, Dimension, Alloc}; use aliases::Vec; +/// Returns `true` if two vectors are collinear (up to an epsilon). pub fn are_collinear(v0: &Vec, v1: &Vec, epsilon: N) -> bool { is_null(&v0.cross(v1), epsilon) } +/// Returns `true` if two 2D vectors are collinear (up to an epsilon). pub fn are_collinear2(v0: &Vec, v1: &Vec, epsilon: N) -> bool { abs_diff_eq!(v0.perp(v1), N::zero(), epsilon = epsilon) } +/// Returns `true` if two vectors are orthogonal (up to an epsilon). pub fn are_orthogonal(v0: &Vec, v1: &Vec, epsilon: N) -> bool where DefaultAllocator: Alloc { abs_diff_eq!(v0.dot(v1), N::zero(), epsilon = epsilon) } -pub fn are_orthonormal(v0: &Vec, v1: &Vec, epsilon: N) -> bool - where DefaultAllocator: Alloc { - unimplemented!() -} +//pub fn are_orthonormal(v0: &Vec, v1: &Vec, epsilon: N) -> bool +// where DefaultAllocator: Alloc { +// unimplemented!() +//} +/// Returns `true` if all the components of `v` are zero (up to an epsilon). pub fn is_comp_null(v: &Vec, epsilon: N) -> Vec where DefaultAllocator: Alloc { v.map(|x| abs_diff_eq!(x, N::zero(), epsilon = epsilon)) } +/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon). pub fn is_normalized(v: &Vec, epsilon: N) -> bool where DefaultAllocator: Alloc { abs_diff_eq!(v.norm_squared(), N::one(), epsilon = epsilon * epsilon) } +/// Returns `true` if `v` is zero (up to an epsilon). pub fn is_null(v: &Vec, epsilon: N) -> bool where DefaultAllocator: Alloc { abs_diff_eq!(*v, Vec::::zeros(), epsilon = epsilon) diff --git a/nalgebra-glm/src/gtx_euler_angles.rs b/nalgebra-glm/src/gtx_euler_angles.rs deleted file mode 100644 index f42a941a..00000000 --- a/nalgebra-glm/src/gtx_euler_angles.rs +++ /dev/null @@ -1,41 +0,0 @@ -pub fn mat< 4, 4, T, defaultp > derivedEulerAngleX (T const &angleX, T const &angularVelocityX) -pub fn mat< 4, 4, T, defaultp > derivedEulerAngleY (T const &angleY, T const &angularVelocityY) -pub fn mat< 4, 4, T, defaultp > derivedEulerAngleZ (T const &angleZ, T const &angularVelocityZ) -pub fn mat< 4, 4, T, defaultp > eulerAngleX (T const &angleX) -pub fn mat< 4, 4, T, defaultp > eulerAngleXY (T const &angleX, T const &angleY) -pub fn mat< 4, 4, T, defaultp > eulerAngleXYX (T const &t1, T const &t2, T const &t3) -pub fn mat< 4, 4, T, defaultp > eulerAngleXYZ (T const &t1, T const &t2, T const &t3) -pub fn mat< 4, 4, T, defaultp > eulerAngleXZ (T const &angleX, T const &angleZ) -pub fn mat< 4, 4, T, defaultp > eulerAngleXZX (T const &t1, T const &t2, T const &t3) -pub fn mat< 4, 4, T, defaultp > eulerAngleXZY (T const &t1, T const &t2, T const &t3) -pub fn mat< 4, 4, T, defaultp > eulerAngleY (T const &angleY) -pub fn mat< 4, 4, T, defaultp > eulerAngleYX (T const &angleY, T const &angleX) -pub fn mat< 4, 4, T, defaultp > eulerAngleYXY (T const &t1, T const &t2, T const &t3) -pub fn mat< 4, 4, T, defaultp > eulerAngleYXZ (T const &yaw, T const &pitch, T const &roll) -pub fn mat< 4, 4, T, defaultp > eulerAngleYZ (T const &angleY, T const &angleZ) -pub fn mat< 4, 4, T, defaultp > eulerAngleYZX (T const &t1, T const &t2, T const &t3) -pub fn mat< 4, 4, T, defaultp > eulerAngleYZY (T const &t1, T const &t2, T const &t3) -pub fn mat< 4, 4, T, defaultp > eulerAngleZ (T const &angleZ) -pub fn mat< 4, 4, T, defaultp > eulerAngleZX (T const &angle, T const &angleX) -pub fn mat< 4, 4, T, defaultp > eulerAngleZXY (T const &t1, T const &t2, T const &t3) -pub fn mat< 4, 4, T, defaultp > eulerAngleZXZ (T const &t1, T const &t2, T const &t3) -pub fn mat< 4, 4, T, defaultp > eulerAngleZY (T const &angleZ, T const &angleY) -pub fn mat< 4, 4, T, defaultp > eulerAngleZYX (T const &t1, T const &t2, T const &t3) -pub fn mat< 4, 4, T, defaultp > eulerAngleZYZ (T const &t1, T const &t2, T const &t3) -pub fn void extractEulerAngleXYX (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleXYZ (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleXZX (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleXZY (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleYXY (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleYXZ (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleYZX (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleYZY (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleZXY (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleZXZ (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleZYX (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn void extractEulerAngleZYZ (mat< 4, 4, T, defaultp > const &M, T &t1, T &t2, T &t3) -pub fn mat< 2, 2, T, defaultp > orientate2 (T const &angle) -pub fn mat< 3, 3, T, defaultp > orientate3 (T const &angle) -pub fn mat< 3, 3, T, Q > orientate3 (vec< 3, T, Q > const &angles) -pub fn mat< 4, 4, T, Q > orientate4 (vec< 3, T, Q > const &angles) -pub fn mat< 4, 4, T, defaultp > yawPitchRoll (T const &yaw, T const &pitch, T const &roll) \ No newline at end of file diff --git a/nalgebra-glm/src/gtx_normal.rs b/nalgebra-glm/src/gtx_normal.rs deleted file mode 100644 index aa32c875..00000000 --- a/nalgebra-glm/src/gtx_normal.rs +++ /dev/null @@ -1,7 +0,0 @@ -use na::{Real, U3}; - -use aliases::Vec; - -pub fn triangleNormal(p1: &Vec, p2: &Vec, p3: &Vec) -> Vec { - (p2 - p1).cross(&(p3 - p1)).normalize() -} \ No newline at end of file diff --git a/nalgebra-glm/src/gtx_quaternion.rs b/nalgebra-glm/src/gtx_quaternion.rs deleted file mode 100644 index 6c7e7c99..00000000 --- a/nalgebra-glm/src/gtx_quaternion.rs +++ /dev/null @@ -1,16 +0,0 @@ -pub fn vec< 3, T, Q > cross (qua< T, Q > const &q, vec< 3, T, Q > const &v) -pub fn vec< 3, T, Q > cross (vec< 3, T, Q > const &v, qua< T, Q > const &q) -pub fn T extractRealComponent (qua< T, Q > const &q) -pub fn qua< T, Q > fastMix (qua< T, Q > const &x, qua< T, Q > const &y, T const &a) -pub fn qua< T, Q > intermediate (qua< T, Q > const &prev, qua< T, Q > const &curr, qua< T, Q > const &next) -pub fn T length2 (qua< T, Q > const &q) -pub fn qua< T, Q > quat_identity () -pub fn vec< 3, T, Q > rotate (qua< T, Q > const &q, vec< 3, T, Q > const &v) -pub fn vec< 4, T, Q > rotate (qua< T, Q > const &q, vec< 4, T, Q > const &v) -pub fn qua< T, Q > rotation (vec< 3, T, Q > const &orig, vec< 3, T, Q > const &dest) -pub fn qua< T, Q > shortMix (qua< T, Q > const &x, qua< T, Q > const &y, T const &a) -pub fn qua< T, Q > squad (qua< T, Q > const &q1, qua< T, Q > const &q2, qua< T, Q > const &s1, qua< T, Q > const &s2, T const &h) -pub fn mat< 3, 3, T, Q > toMat3 (qua< T, Q > const &x) -pub fn mat< 4, 4, T, Q > toMat4 (qua< T, Q > const &x) -pub fn qua< T, Q > toQuat (mat< 3, 3, T, Q > const &x) -pub fn qua< T, Q > toQuat (mat< 4, 4, T, Q > const &x) diff --git a/nalgebra-glm/src/gtx_rotate_normalized_axis.rs b/nalgebra-glm/src/gtx_rotate_normalized_axis.rs deleted file mode 100644 index ab30ca15..00000000 --- a/nalgebra-glm/src/gtx_rotate_normalized_axis.rs +++ /dev/null @@ -1,11 +0,0 @@ -use na::{Real, Rotation3, UnitQuaternion, Unit, U3, U4}; - -use aliases::{Vec, Mat, Qua}; - -pub fn rotateNormalizedAxis(m: &Mat, angle: N, axis: &Vec) -> Mat { - m * Rotation3::from_axis_angle(&Unit::new_unchecked(*axis), angle).to_homogeneous() -} - -pub fn rotateNormalizedAxis2(q: &Qua, angle: N, axis: &Vec) -> Qua { - q * UnitQuaternion::from_axis_angle(&Unit::new_unchecked(*axis), angle).unwrap() -} \ No newline at end of file diff --git a/nalgebra-glm/src/gtx_vector_angle.rs b/nalgebra-glm/src/gtx_vector_angle.rs deleted file mode 100644 index 74e7ca38..00000000 --- a/nalgebra-glm/src/gtx_vector_angle.rs +++ /dev/null @@ -1,18 +0,0 @@ -use na::{self, DefaultAllocator, Real, U2, U3}; - -use traits::{Dimension, Alloc}; -use aliases::Vec; - - -pub fn angle(x: &Vec, y: &Vec) -> N - where DefaultAllocator: Alloc { - x.angle(y) -} - -pub fn oriented_angle(x: &Vec, y: &Vec) -> N { - unimplemented!() -} - -pub fn oriented_angle_ref(x: &Vec, y: &Vec, refv: &Vec) -> N { - unimplemented!() -} diff --git a/nalgebra-glm/src/lib.rs b/nalgebra-glm/src/lib.rs index 2ee8b708..e56dd6bc 100644 --- a/nalgebra-glm/src/lib.rs +++ b/nalgebra-glm/src/lib.rs @@ -1,3 +1,8 @@ + +#![allow(dead_code)] + + + extern crate num_traits as num; #[macro_use] extern crate approx; @@ -6,6 +11,7 @@ extern crate nalgebra as na; pub use aliases::*; pub use constructors::*; +pub use common::*; pub use geometric::*; pub use matrix::*; pub use traits::*; @@ -13,61 +19,23 @@ pub use trigonometric::*; pub use vector_relational::*; pub use exponential::*; -pub use ext_vector_relational::*; - -pub use gtx_component_wise::*; +pub use gtx::*; +pub use gtc::*; +pub use ext::*; mod aliases; -pub mod constructors; +mod constructors; mod common; -pub mod matrix; -pub mod geometric; +mod matrix; +mod geometric; mod traits; -pub mod trigonometric; -pub mod vector_relational; -pub mod exponential; -pub mod integer; -pub mod packing; -pub mod ext_matrix_clip_space; -pub mod ext_matrix_projection; -pub mod ext_matrix_relationnal; -pub mod ext_matrix_transform; -pub mod ext_quaternion_common; -pub mod ext_quaternion_geometric; -pub mod ext_quaternion_transform; -pub mod ext_quaternion_trigonometric; -pub mod ext_quaternion_relational; -pub mod ext_scalar_common; -pub mod ext_scalar_constants; -pub mod ext_vector_common; -pub mod ext_vector_relational; -//pub mod gtc_bitfield; -pub mod gtc_constants; -pub mod gtc_epsilon; -//pub mod gtc_integer; -pub mod gtc_matrix_access; -pub mod gtc_matrix_inverse; -//pub mod gtc_packing; -pub mod gtc_quaternion; -//pub mod gtc_reciprocal; -//pub mod gtc_round; -pub mod gtc_type_ptr; -//pub mod gtc_ulp; +mod trigonometric; +mod vector_relational; +mod exponential; +//mod integer; +//mod packing; -pub mod gtx_component_wise; -//pub mod gtx_euler_angles; -pub mod gtx_exterior_product; -pub mod gtx_handed_coordinate_space; -pub mod gtx_matrix_cross_product; -pub mod gtx_matrix_operation; -pub mod gtx_norm; -pub mod gtx_normal; -pub mod gtx_normalize_dot; -//pub mod gtx_quaternion; -pub mod gtx_rotate_normalized_axis; -//pub mod gtx_rotate_vector; -pub mod gtx_transform; -//pub mod gtx_transform2; -//pub mod gtx_transform2d; -//pub mod gtx_vector_angle; -pub mod gtx_vector_query; \ No newline at end of file +pub mod ext; +pub mod gtc; +pub mod gtx; +pub mod quat; \ No newline at end of file diff --git a/nalgebra-glm/src/matrix.rs b/nalgebra-glm/src/matrix.rs index 99b9e565..d3dcd64d 100644 --- a/nalgebra-glm/src/matrix.rs +++ b/nalgebra-glm/src/matrix.rs @@ -1,30 +1,33 @@ -use num::Num; -use na::{Scalar, Real, DefaultAllocator, U1}; +use na::{Scalar, Real, DefaultAllocator}; use traits::{Alloc, Dimension, Number}; use aliases::{Mat, Vec}; - +/// The determinant of the matrix `m`. pub fn determinant(m: &Mat) -> N where DefaultAllocator: Alloc { m.determinant() } +/// The inverse of the matrix `m`. pub fn inverse(m: &Mat) -> Mat where DefaultAllocator: Alloc { m.clone().try_inverse().unwrap_or(Mat::::zeros()) } +/// Componentwise multiplication of two matrices. pub fn matrix_comp_mult(x: &Mat, y: &Mat) -> Mat where DefaultAllocator: Alloc { x.component_mul(y) } +/// Treats the first parameter `c` as a column vector and the second parameter `r` as a row vector and does a linear algebraic matrix multiply `c * r`. pub fn outer_product(c: &Vec, r: &Vec) -> Mat where DefaultAllocator: Alloc { c * r.transpose() } +/// The transpose of the matrix `m`. pub fn transpose(x: &Mat) -> Mat where DefaultAllocator: Alloc { x.transpose() diff --git a/nalgebra-glm/src/gtc_quaternion.rs b/nalgebra-glm/src/quat/gtc_quaternion.rs similarity index 63% rename from nalgebra-glm/src/gtc_quaternion.rs rename to nalgebra-glm/src/quat/gtc_quaternion.rs index 7adf0e14..f8729391 100644 --- a/nalgebra-glm/src/gtc_quaternion.rs +++ b/nalgebra-glm/src/quat/gtc_quaternion.rs @@ -1,72 +1,87 @@ -use na::{self, Real, U3, U4, UnitQuaternion, Vector3, Rotation3}; +use na::{Real, U3, U4, UnitQuaternion, Vector3, Rotation3}; use aliases::{Qua, Vec, Mat}; -/// Euler angles of the quaternion as (pitch, yaw, roll). +/// Euler angles of the quaternion `q` as (pitch, yaw, roll). pub fn euler_angles(x: &Qua) -> Vec { let q = UnitQuaternion::new_unchecked(*x); let a = q.to_euler_angles(); Vector3::new(a.2, a.1, a.0) } +/// Componentwise `>` comparison between two quaternions. pub fn greater_than(x: &Qua, y: &Qua) -> Vec { ::greater_than(&x.coords, &y.coords) } +/// Componentwise `>=` comparison between two quaternions. pub fn greater_than_equal(x: &Qua, y: &Qua) -> Vec { ::greater_than_equal(&x.coords, &y.coords) } +/// Componentwise `<` comparison between two quaternions. pub fn less_than(x: &Qua, y: &Qua) -> Vec { ::less_than(&x.coords, &y.coords) } +/// Componentwise `<=` comparison between two quaternions. pub fn less_than_equal(x: &Qua, y: &Qua) -> Vec { ::less_than_equal(&x.coords, &y.coords) } + +/// Convert a quaternion to a rotation matrix. pub fn mat3_cast(x: Qua) -> Mat { let q = UnitQuaternion::new_unchecked(x); q.to_rotation_matrix().unwrap() } +/// Convert a quaternion to a rotation matrix in homogeneous coordinates. pub fn mat4_cast(x: Qua) -> Mat { let q = UnitQuaternion::new_unchecked(x); q.to_homogeneous() } +/// Convert a rotation matrix to a quaternion. pub fn quat_cast(x: Mat) -> Qua { let rot = Rotation3::from_matrix_unchecked(x); UnitQuaternion::from_rotation_matrix(&rot).unwrap() } +/// Convert a rotation matrix in homogeneous coordinates to a quaternion. pub fn quat_cast2(x: Mat) -> Qua { quat_cast(x.fixed_slice::(0, 0).into_owned()) } +/// Computes a right-handed look-at quaternion (equivalent to a right-handed look-at matrix). pub fn quat_look_at(direction: &Vec, up: &Vec) -> Qua { quat_look_at_rh(direction, up) } +/// Computes a left-handed look-at quaternion (equivalent to a left-handed look-at matrix). pub fn quat_look_at_lh(direction: &Vec, up: &Vec) -> Qua { UnitQuaternion::look_at_lh(direction, up).unwrap() } +/// Computes a right-handed look-at quaternion (equivalent to a right-handed look-at matrix). pub fn quat_look_at_rh(direction: &Vec, up: &Vec) -> Qua { UnitQuaternion::look_at_rh(direction, up).unwrap() } +/// The "roll" euler angle of the quaternion `x` assumed to be normalized. pub fn roll(x: &Qua) -> N { // FIXME: optimize this. euler_angles(x).z } +/// The "yaw" euler angle of the quaternion `x` assumed to be normalized. pub fn yaw(x: &Qua) -> N { // FIXME: optimize this. euler_angles(x).y } +/// The "pitch" euler angle of the quaternion `x` assumed to be normalized. pub fn pitch(x: &Qua) -> N { // FIXME: optimize this. euler_angles(x).x diff --git a/nalgebra-glm/src/quat/gtx_quaternion.rs b/nalgebra-glm/src/quat/gtx_quaternion.rs new file mode 100644 index 00000000..74a0fca6 --- /dev/null +++ b/nalgebra-glm/src/quat/gtx_quaternion.rs @@ -0,0 +1,91 @@ +use na::{Real, Unit, Rotation3, Vector4, UnitQuaternion, U3, U4}; + +use aliases::{Qua, Vec, Mat}; + +/// Rotate the vector `v` by the quaternion `q` assumed to be normalized. +pub fn cross(q: &Qua, v: &Vec) -> Vec { + UnitQuaternion::new_unchecked(*q) * v +} + +/// Rotate the vector `v` by the inverse of the quaternion `q` assumed to be normalized. +pub fn cross2(v: &Vec, q: &Qua) -> Vec { + UnitQuaternion::new_unchecked(*q).inverse() * v +} + +/// The quaternion `w` component. +pub fn extract_real_component(q: &Qua) -> N { + q.w +} + +/// Normalized linear interpolation between two quaternions. +pub fn fast_mix(x: &Qua, y: &Qua, a: N) -> Qua { + Unit::new_unchecked(*x).nlerp(&Unit::new_unchecked(*y), a).unwrap() +} + +//pub fn intermediate(prev: &Qua, curr: &Qua, next: &Qua) -> Qua { +// unimplemented!() +//} + +/// The squared magnitude of a quaternion `q`. +pub fn length2(q: &Qua) -> N { + q.norm_squared() +} + +/// The squared magnitude of a quaternion `q`. +pub fn magnitude2(q: &Qua) -> N { + q.norm_squared() +} + +/// The quaternion representing the identity rotation. +pub fn quat_identity() -> Qua { + UnitQuaternion::identity().unwrap() +} + +/// Rotates a vector by a quaternion assumed to be normalized. +pub fn rotate(q: &Qua, v: &Vec) -> Vec { + UnitQuaternion::new_unchecked(*q) * v +} + +/// Rotates a vector in homogeneous coordinates by a quaternion assumed to be normalized. +pub fn rotate2(q: &Qua, v: &Vec) -> Vec { +// UnitQuaternion::new_unchecked(*q) * v + let rotated = Unit::new_unchecked(*q) * v.fixed_rows::(0); + Vector4::new(rotated.x, rotated.y, rotated.z, v.w) +} + +/// The rotation required to align `orig` to `dest`. +pub fn rotation(orig: &Vec, dest: &Vec) -> Qua { + UnitQuaternion::rotation_between(orig, dest).unwrap_or(UnitQuaternion::identity()).unwrap() +} + +/// The spherical linear interpolation between two quaternions. +pub fn short_mix(x: &Qua, y: &Qua, a: N) -> Qua { + Unit::new_normalize(*x).slerp(&Unit::new_normalize(*y), a).unwrap() +} + +//pub fn squad(q1: &Qua, q2: &Qua, s1: &Qua, s2: &Qua, h: N) -> Qua { +// unimplemented!() +//} + +/// Converts a quaternion to a rotation matrix. +pub fn to_mat3(x: &Qua) -> Mat { + UnitQuaternion::new_unchecked(*x).to_rotation_matrix().unwrap() +} + +/// Converts a quaternion to a rotation matrix in homogenous coordinates. +pub fn to_mat4(x: &Qua) -> Mat { + UnitQuaternion::new_unchecked(*x).to_homogeneous() +} + +/// Converts a rotation matrix to a quaternion. +pub fn to_quat(x: &Mat) -> Qua { + let r = Rotation3::from_matrix_unchecked(*x); + UnitQuaternion::from_rotation_matrix(&r).unwrap() +} + +/// Converts a rotation matrix in homogeneous coordinates to a quaternion. +pub fn to_quat2(x: &Mat) -> Qua { + let rot = x.fixed_slice::(0, 0).into_owned(); + to_quat(&rot) +} + diff --git a/nalgebra-glm/src/quat/gtx_rotate_normalized_axis.rs b/nalgebra-glm/src/quat/gtx_rotate_normalized_axis.rs new file mode 100644 index 00000000..3cb9f515 --- /dev/null +++ b/nalgebra-glm/src/quat/gtx_rotate_normalized_axis.rs @@ -0,0 +1,13 @@ +use na::{Real, Unit, UnitQuaternion, U3}; + +use aliases::{Vec, Qua}; + +/// Rotates a quaternion from a vector of 3 components normalized axis and an angle. +/// +/// # Parameters +/// * `q` - Source orientation +/// * `angle` - Angle expressed in radians. +/// * `axis` - Normalized axis of the rotation, must be normalized. +pub fn rotate_normalized_axis(q: &Qua, angle: N, axis: &Vec) -> Qua { + q * UnitQuaternion::from_axis_angle(&Unit::new_unchecked(*axis), angle).unwrap() +} \ No newline at end of file diff --git a/nalgebra-glm/src/quat/mod.rs b/nalgebra-glm/src/quat/mod.rs new file mode 100644 index 00000000..05326932 --- /dev/null +++ b/nalgebra-glm/src/quat/mod.rs @@ -0,0 +1,19 @@ +//! Definition and operations on quaternions. + +pub use self::gtc_quaternion::*; +pub use self::gtx_quaternion::*; +pub use self::gtx_rotate_normalized_axis::*; +pub use self::quaternion_common::*; +pub use self::quaternion_geometric::*; +pub use self::quaternion_relational::*; +pub use self::quaternion_transform::*; +pub use self::quaternion_trigonometric::*; + +mod gtc_quaternion; +mod gtx_quaternion; +mod gtx_rotate_normalized_axis; +mod quaternion_common; +mod quaternion_geometric; +mod quaternion_relational; +mod quaternion_transform; +mod quaternion_trigonometric; \ No newline at end of file diff --git a/nalgebra-glm/src/ext_quaternion_common.rs b/nalgebra-glm/src/quat/quaternion_common.rs similarity index 66% rename from nalgebra-glm/src/ext_quaternion_common.rs rename to nalgebra-glm/src/quat/quaternion_common.rs index 05d33b2b..75eaae4d 100644 --- a/nalgebra-glm/src/ext_quaternion_common.rs +++ b/nalgebra-glm/src/quat/quaternion_common.rs @@ -1,11 +1,13 @@ -use na::{self, Real, Unit, U4}; +use na::{self, Real, Unit}; -use aliases::{Vec, Qua}; +use aliases::Qua; +/// The conjugate of `q`. pub fn conjugate(q: &Qua) -> Qua { q.conjugate() } +/// The inverse of `q`. pub fn inverse(q: &Qua) -> Qua { q.try_inverse().unwrap_or(na::zero()) } @@ -18,14 +20,16 @@ pub fn inverse(q: &Qua) -> Qua { // x.coords.map(|e| e.is_nan()) //} +/// Interpolate linearly between `x` and `y`. pub fn lerp(x: &Qua, y: &Qua, a: N) -> Qua { x.lerp(y, a) } -pub fn mix(x: &Qua, y: &Qua, a: N) -> Qua { - x * (N::one() - a) + y * a -} +//pub fn mix(x: &Qua, y: &Qua, a: N) -> Qua { +// x * (N::one() - a) + y * a +//} +/// Interpolate spherically between `x` and `y`. pub fn slerp(x: &Qua, y: &Qua, a: N) -> Qua { Unit::new_normalize(*x).slerp(&Unit::new_normalize(*y), a).unwrap() } diff --git a/nalgebra-glm/src/ext_quaternion_geometric.rs b/nalgebra-glm/src/quat/quaternion_geometric.rs similarity index 53% rename from nalgebra-glm/src/ext_quaternion_geometric.rs rename to nalgebra-glm/src/quat/quaternion_geometric.rs index 7b231101..952815a8 100644 --- a/nalgebra-glm/src/ext_quaternion_geometric.rs +++ b/nalgebra-glm/src/quat/quaternion_geometric.rs @@ -2,15 +2,27 @@ use na::Real; use aliases::Qua; +/// Multiplies two quaternions. pub fn cross(q1: &Qua, q2: &Qua) -> Qua { q1 * q2 } + +/// The scalar product of two quaternions. pub fn dot(x: &Qua, y: &Qua) -> N { x.dot(y) } + +/// The magnitude of the quaternion `q`. pub fn length(q: &Qua) -> N { q.norm() } + +/// The magnitude of the quaternion `q`. +pub fn magnitude(q: &Qua) -> N { + q.norm() +} + +/// Normalizes the quaternion `q`. pub fn normalize(q: &Qua) -> Qua { q.normalize() } \ No newline at end of file diff --git a/nalgebra-glm/src/ext_quaternion_relational.rs b/nalgebra-glm/src/quat/quaternion_relational.rs similarity index 65% rename from nalgebra-glm/src/ext_quaternion_relational.rs rename to nalgebra-glm/src/quat/quaternion_relational.rs index ab37d297..50541455 100644 --- a/nalgebra-glm/src/ext_quaternion_relational.rs +++ b/nalgebra-glm/src/quat/quaternion_relational.rs @@ -3,18 +3,22 @@ use na::{Real, U4}; use aliases::{Qua, Vec}; +/// Componentwise equality comparison between two quaternions. pub fn equal(x: &Qua, y: &Qua) -> Vec { ::equal(&x.coords, &y.coords) } +/// Componentwise approximate equality comparison between two quaternions. pub fn equal_eps(x: &Qua, y: &Qua, epsilon: N) -> Vec { ::equal_eps(&x.coords, &y.coords, epsilon) } +/// Componentwise non-equality comparison between two quaternions. pub fn not_equal(x: &Qua, y: &Qua) -> Vec { ::not_equal(&x.coords, &y.coords) } +/// Componentwise approximate non-equality comparison between two quaternions. pub fn not_equal_eps(x: &Qua, y: &Qua, epsilon: N) -> Vec { ::not_equal_eps(&x.coords, &y.coords, epsilon) } diff --git a/nalgebra-glm/src/ext_quaternion_transform.rs b/nalgebra-glm/src/quat/quaternion_transform.rs similarity index 58% rename from nalgebra-glm/src/ext_quaternion_transform.rs rename to nalgebra-glm/src/quat/quaternion_transform.rs index 08f7b393..a0b29172 100644 --- a/nalgebra-glm/src/ext_quaternion_transform.rs +++ b/nalgebra-glm/src/quat/quaternion_transform.rs @@ -2,22 +2,26 @@ use na::{Real, U3, UnitQuaternion, Unit}; use aliases::{Vec, Qua}; +/// Computes the quaternion exponential. pub fn exp(q: &Qua) -> Qua { q.exp() } +/// Computes the quaternion logarithm. pub fn log(q: &Qua) -> Qua { q.ln() } +/// Raises the quaternion `q` to the power `y`. pub fn pow(q: &Qua, y: N) -> Qua { q.powf(y) } +/// Builds a quaternion from an axis and an angle, and right-multiply it to the quaternion `q`. pub fn rotate(q: &Qua, angle: N, axis: &Vec) -> Qua { q * UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).unwrap() } -pub fn sqrt(q: &Qua) -> Qua { - unimplemented!() -} \ No newline at end of file +//pub fn sqrt(q: &Qua) -> Qua { +// unimplemented!() +//} \ No newline at end of file diff --git a/nalgebra-glm/src/ext_quaternion_trigonometric.rs b/nalgebra-glm/src/quat/quaternion_trigonometric.rs similarity index 63% rename from nalgebra-glm/src/ext_quaternion_trigonometric.rs rename to nalgebra-glm/src/quat/quaternion_trigonometric.rs index 3f0e6b61..20f39cde 100644 --- a/nalgebra-glm/src/ext_quaternion_trigonometric.rs +++ b/nalgebra-glm/src/quat/quaternion_trigonometric.rs @@ -2,14 +2,17 @@ use na::{Real, U3, Unit, UnitQuaternion, Vector3}; use aliases::{Vec, Qua}; +/// The rotation angle of this quaternion assumed to be normalized. pub fn angle(x: &Qua) -> N { UnitQuaternion::from_quaternion(*x).angle() } -pub fn angleAxis(angle: N, axis: &Vec) -> Qua { +/// Creates a quaternion from an axis and an angle. +pub fn angle_axis(angle: N, axis: &Vec) -> Qua { UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).unwrap() } +/// The rotation axis of a quaternion assumed to be normalized. pub fn axis(x: &Qua) -> Vec { if let Some(a) = UnitQuaternion::from_quaternion(*x).axis() { a.unwrap() diff --git a/nalgebra-glm/src/traits.rs b/nalgebra-glm/src/traits.rs index 53a16813..02e62e97 100644 --- a/nalgebra-glm/src/traits.rs +++ b/nalgebra-glm/src/traits.rs @@ -1,4 +1,3 @@ -use std::cmp::{PartialOrd, PartialEq}; use num::{Signed, FromPrimitive, Bounded}; use approx::AbsDiffEq; @@ -6,10 +5,12 @@ use alga::general::{Ring, Lattice}; use na::{Scalar, DimName, DimMin, U1}; use na::allocator::Allocator; +/// A type-level number representing a vector, matrix row, or matrix column, dimension. pub trait Dimension: DimName + DimMin {} impl> Dimension for D {} +/// A number that can either be an integer or a float. pub trait Number: Scalar + Ring + Lattice + AbsDiffEq + Signed + FromPrimitive + Bounded { } diff --git a/nalgebra-glm/src/trigonometric.rs b/nalgebra-glm/src/trigonometric.rs index f590ce1a..71673f29 100644 --- a/nalgebra-glm/src/trigonometric.rs +++ b/nalgebra-glm/src/trigonometric.rs @@ -3,76 +3,92 @@ use na::{self, Real, DefaultAllocator}; use aliases::Vec; use traits::{Alloc, Dimension}; + +/// Componentwise arc-cosinus. pub fn acos(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|e| e.acos()) } +/// Componentwise hyperbolic arc-cosinus. pub fn acosh(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|e| e.acosh()) } +/// Componentwise arc-sinus. pub fn asin(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|e| e.asin()) } +/// Componentwise hyperbolic arc-sinus. pub fn asinh(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|e| e.asinh()) } +/// Componentwise arc-tangent of `y / x`. pub fn atan2(y: &Vec, x: &Vec) -> Vec where DefaultAllocator: Alloc { y.zip_map(x, |y, x| y.atan2(x)) } +/// Componentwise arc-tangent. pub fn atan(y_over_x: &Vec) -> Vec where DefaultAllocator: Alloc { y_over_x.map(|e| e.atan()) } +/// Componentwise hyperbolic arc-tangent. pub fn atanh(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.map(|e| e.atanh()) } +/// Componentwise cosinus. pub fn cos(angle: &Vec) -> Vec where DefaultAllocator: Alloc { angle.map(|e| e.cos()) } +/// Componentwise hyperbolic cosinus. pub fn cosh(angle: &Vec) -> Vec where DefaultAllocator: Alloc { angle.map(|e| e.cosh()) } +/// Componentwise conversion from radians to degrees. pub fn degrees(radians: &Vec) -> Vec where DefaultAllocator: Alloc { radians.map(|e| e * na::convert(180.0) / N::pi()) } +/// Componentwise conversion fro degrees to radians. pub fn radians(degrees: &Vec) -> Vec where DefaultAllocator: Alloc { degrees.map(|e| e * N::pi() / na::convert(180.0)) } +/// Componentwise sinus. pub fn sin(angle: &Vec) -> Vec where DefaultAllocator: Alloc { angle.map(|e| e.sin()) } +/// Componentwise hyperbolic sinus. pub fn sinh(angle: &Vec) -> Vec where DefaultAllocator: Alloc { angle.map(|e| e.sinh()) } +/// Componentwise tangent. pub fn tan(angle: &Vec) -> Vec where DefaultAllocator: Alloc { angle.map(|e| e.tan()) } +/// Componentwise hyperbolic tangent. pub fn tanh(angle: &Vec) -> Vec where DefaultAllocator: Alloc { angle.map(|e| e.tanh()) diff --git a/nalgebra-glm/src/vector_relational.rs b/nalgebra-glm/src/vector_relational.rs index ae1a2a2e..e414dd27 100644 --- a/nalgebra-glm/src/vector_relational.rs +++ b/nalgebra-glm/src/vector_relational.rs @@ -1,49 +1,57 @@ -use na::{self, Real, DefaultAllocator}; +use na::{DefaultAllocator}; use aliases::Vec; use traits::{Number, Alloc, Dimension}; - +/// Checks that all the vector components are `true`. pub fn all(v: &Vec) -> bool where DefaultAllocator: Alloc { v.iter().all(|x| *x) } +/// Checks that at least one of the vector components is `true`. pub fn any(v: &Vec) -> bool where DefaultAllocator: Alloc { v.iter().any(|x| *x) } +/// Componentwise equality comparison. pub fn equal(x: &Vec, y: &Vec) -> Vec where DefaultAllocator: Alloc { x.zip_map(y, |x, y| x == y) } +/// Componentwise `>` comparison. pub fn greater_than(x: &Vec, y: &Vec) -> Vec where DefaultAllocator: Alloc { x.zip_map(y, |x, y| x > y) } +/// Componentwise `>=` comparison. pub fn greater_than_equal(x: &Vec, y: &Vec) -> Vec where DefaultAllocator: Alloc { x.zip_map(y, |x, y| x >= y) } +/// Componentwise `<` comparison. pub fn less_than(x: &Vec, y: &Vec) -> Vec where DefaultAllocator: Alloc { x.zip_map(y, |x, y| x < y) } +/// Componentwise `>=` comparison. pub fn less_than_equal(x: &Vec, y: &Vec) -> Vec where DefaultAllocator: Alloc { x.zip_map(y, |x, y| x <= y) } +/// Componentwise not `!`. pub fn not(v: &Vec) -> Vec where DefaultAllocator: Alloc { v.map(|x| !x) } +/// Componentwise not-equality `!=`. pub fn not_equal(x: &Vec, y: &Vec) -> Vec where DefaultAllocator: Alloc { x.zip_map(y, |x, y| x != y)