2013-07-11 01:43:45 +08:00
|
|
|
|
use std::num::{Zero, One};
|
2013-10-10 04:59:44 +08:00
|
|
|
|
use traits::structure::{Cast, Row, Basis};
|
2013-10-06 22:54:09 +08:00
|
|
|
|
use traits::geometry::{Norm, Cross, CrossMatrix, UniformSphereSample};
|
|
|
|
|
use structs::vec::{Vec1, Vec2, Vec3, Vec4};
|
|
|
|
|
use structs::mat::Mat3;
|
2013-07-08 04:34:18 +08:00
|
|
|
|
|
2013-08-05 16:13:44 +08:00
|
|
|
|
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> {
|
2013-08-05 15:44:56 +08:00
|
|
|
|
#[inline]
|
2013-10-17 03:44:33 +08:00
|
|
|
|
fn cross(a: &Vec2<N>, b: &Vec2<N>) -> Vec1<N> {
|
|
|
|
|
Vec1::new(a.x * b.y - a.y * b.x)
|
2013-08-05 16:13:44 +08:00
|
|
|
|
}
|
2013-06-29 08:34:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2013-08-26 05:01:44 +08:00
|
|
|
|
// FIXME: instead of returning a Vec2, define a Mat2x1 matrix?
|
|
|
|
|
impl<N: Neg<N> + Clone> CrossMatrix<Vec2<N>> for Vec2<N> {
|
|
|
|
|
#[inline]
|
2013-10-17 03:44:33 +08:00
|
|
|
|
fn cross_matrix(v: &Vec2<N>) -> Vec2<N> {
|
|
|
|
|
Vec2::new(-v.y, v.x.clone())
|
2013-08-26 05:01:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-05 16:13:44 +08:00
|
|
|
|
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N> {
|
2013-08-05 15:44:56 +08:00
|
|
|
|
#[inline]
|
2013-10-17 03:44:33 +08:00
|
|
|
|
fn cross(a: &Vec3<N>, b: &Vec3<N>) -> Vec3<N> {
|
2013-08-05 15:44:56 +08:00
|
|
|
|
Vec3::new(
|
2013-10-17 03:44:33 +08:00
|
|
|
|
a.y * b.z - a.z * b.y,
|
|
|
|
|
a.z * b.x - a.x * b.z,
|
|
|
|
|
a.x * b.y - a.y * b.x
|
2013-08-05 15:44:56 +08:00
|
|
|
|
)
|
|
|
|
|
}
|
2013-06-29 08:34:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2013-08-26 05:01:44 +08:00
|
|
|
|
impl<N: Neg<N> + Zero + Clone> CrossMatrix<Mat3<N>> for Vec3<N> {
|
|
|
|
|
#[inline]
|
2013-10-17 03:44:33 +08:00
|
|
|
|
fn cross_matrix(v: &Vec3<N>) -> Mat3<N> {
|
2013-08-26 05:01:44 +08:00
|
|
|
|
Mat3::new(
|
2013-10-17 03:44:33 +08:00
|
|
|
|
Zero::zero(), -v.z , v.y.clone(),
|
|
|
|
|
v.z.clone() , Zero::zero(), -v.x,
|
|
|
|
|
-v.y , v.x.clone() , Zero::zero()
|
2013-08-26 05:01:44 +08:00
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-06 22:54:09 +08:00
|
|
|
|
// FIXME: implement this for all other vectors
|
2013-08-26 05:01:44 +08:00
|
|
|
|
impl<N: Clone> Row<Vec1<N>> for Vec2<N> {
|
2013-09-13 16:26:19 +08:00
|
|
|
|
#[inline]
|
2013-10-06 22:54:09 +08:00
|
|
|
|
fn nrows(&self) -> uint {
|
2013-09-13 16:26:19 +08:00
|
|
|
|
2
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-26 05:01:44 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn row(&self, i: uint) -> Vec1<N> {
|
|
|
|
|
match i {
|
|
|
|
|
0 => Vec1::new(self.x.clone()),
|
|
|
|
|
1 => Vec1::new(self.y.clone()),
|
|
|
|
|
_ => fail!("Index out of range: 2d vectors do not have " + i.to_str() + " rows.")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn set_row(&mut self, i: uint, r: Vec1<N>) {
|
|
|
|
|
match i {
|
|
|
|
|
0 => self.x = r.x,
|
|
|
|
|
1 => self.y = r.x,
|
|
|
|
|
_ => fail!("Index out of range: 2d vectors do not have " + i.to_str() + " rows.")
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-05 16:13:44 +08:00
|
|
|
|
impl<N: One> Basis for Vec1<N> {
|
2013-08-05 15:44:56 +08:00
|
|
|
|
#[inline(always)]
|
2013-08-17 16:48:45 +08:00
|
|
|
|
fn canonical_basis(f: &fn(Vec1<N>) -> bool) {
|
|
|
|
|
f(Vec1::new(One::one()));
|
2013-08-05 16:13:44 +08:00
|
|
|
|
}
|
2013-06-29 08:34:45 +08:00
|
|
|
|
|
2013-08-05 15:44:56 +08:00
|
|
|
|
#[inline(always)]
|
2013-10-17 03:44:33 +08:00
|
|
|
|
fn orthonormal_subspace_basis(_: &Vec1<N>, _: &fn(Vec1<N>) -> bool ) { }
|
2013-06-29 08:34:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2013-08-05 16:13:44 +08:00
|
|
|
|
impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
|
2013-08-17 16:48:45 +08:00
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn canonical_basis(f: &fn(Vec2<N>) -> bool) {
|
|
|
|
|
if !f(Vec2::new(One::one(), Zero::zero())) { return };
|
2013-08-05 15:44:56 +08:00
|
|
|
|
f(Vec2::new(Zero::zero(), One::one()));
|
|
|
|
|
}
|
2013-06-29 08:34:45 +08:00
|
|
|
|
|
2013-08-05 15:44:56 +08:00
|
|
|
|
#[inline]
|
2013-10-17 03:44:33 +08:00
|
|
|
|
fn orthonormal_subspace_basis(n: &Vec2<N>, f: &fn(Vec2<N>) -> bool) {
|
|
|
|
|
f(Vec2::new(-n.y, n.x.clone()));
|
2013-08-05 16:13:44 +08:00
|
|
|
|
}
|
2013-06-29 08:34:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-09 00:20:06 +08:00
|
|
|
|
impl<N: Clone + Ord + Algebraic + Signed> Basis for Vec3<N> {
|
2013-08-05 15:44:56 +08:00
|
|
|
|
#[inline(always)]
|
2013-08-17 16:48:45 +08:00
|
|
|
|
fn canonical_basis(f: &fn(Vec3<N>) -> bool) {
|
|
|
|
|
if !f(Vec3::new(One::one(), Zero::zero(), Zero::zero())) { return };
|
|
|
|
|
if !f(Vec3::new(Zero::zero(), One::one(), Zero::zero())) { return };
|
2013-08-05 15:44:56 +08:00
|
|
|
|
f(Vec3::new(Zero::zero(), Zero::zero(), One::one()));
|
|
|
|
|
}
|
2013-06-29 08:34:45 +08:00
|
|
|
|
|
2013-08-05 15:44:56 +08:00
|
|
|
|
#[inline(always)]
|
2013-10-17 03:44:33 +08:00
|
|
|
|
fn orthonormal_subspace_basis(n: &Vec3<N>, f: &fn(Vec3<N>) -> bool) {
|
2013-08-05 15:44:56 +08:00
|
|
|
|
let a =
|
2013-10-17 03:44:33 +08:00
|
|
|
|
if n.x.clone().abs() > n.y.clone().abs() {
|
|
|
|
|
Norm::normalize_cpy(&Vec3::new(n.z.clone(), Zero::zero(), -n.x))
|
2013-08-05 16:13:44 +08:00
|
|
|
|
}
|
|
|
|
|
else {
|
2013-10-17 03:44:33 +08:00
|
|
|
|
Norm::normalize_cpy(&Vec3::new(Zero::zero(), -n.z, n.y.clone()))
|
2013-08-05 16:13:44 +08:00
|
|
|
|
};
|
2013-06-29 08:34:45 +08:00
|
|
|
|
|
2013-10-17 03:44:33 +08:00
|
|
|
|
if !f(Cross::cross(&a, n)) { return };
|
2013-08-05 15:44:56 +08:00
|
|
|
|
f(a);
|
|
|
|
|
}
|
2013-06-29 08:34:45 +08:00
|
|
|
|
}
|
2013-07-04 22:23:08 +08:00
|
|
|
|
|
|
|
|
|
// FIXME: this bad: this fixes definitly the number of samples…
|
2013-10-10 04:59:44 +08:00
|
|
|
|
static SAMPLES_2_F32: [Vec2<f32>, ..21] = [
|
2013-08-05 15:44:56 +08:00
|
|
|
|
Vec2 { x: 1.0, y: 0.0 },
|
|
|
|
|
Vec2 { x: 0.95557281, y: 0.29475517 },
|
|
|
|
|
Vec2 { x: 0.82623877, y: 0.56332006 },
|
|
|
|
|
Vec2 { x: 0.6234898, y: 0.78183148 },
|
|
|
|
|
Vec2 { x: 0.36534102, y: 0.93087375 },
|
|
|
|
|
Vec2 { x: 0.07473009, y: 0.9972038 },
|
|
|
|
|
Vec2 { x: -0.22252093, y: 0.97492791 },
|
|
|
|
|
Vec2 { x: -0.5, y: 0.8660254 },
|
|
|
|
|
Vec2 { x: -0.73305187, y: 0.68017274 },
|
|
|
|
|
Vec2 { x: -0.90096887, y: 0.43388374 },
|
|
|
|
|
Vec2 { x: -0.98883083, y: 0.14904227 },
|
|
|
|
|
Vec2 { x: -0.98883083, y: -0.14904227 },
|
|
|
|
|
Vec2 { x: -0.90096887, y: -0.43388374 },
|
|
|
|
|
Vec2 { x: -0.73305187, y: -0.68017274 },
|
|
|
|
|
Vec2 { x: -0.5, y: -0.8660254 },
|
|
|
|
|
Vec2 { x: -0.22252093, y: -0.97492791 },
|
|
|
|
|
Vec2 { x: 0.07473009, y: -0.9972038 },
|
|
|
|
|
Vec2 { x: 0.36534102, y: -0.93087375 },
|
|
|
|
|
Vec2 { x: 0.6234898, y: -0.78183148 },
|
|
|
|
|
Vec2 { x: 0.82623877, y: -0.56332006 },
|
|
|
|
|
Vec2 { x: 0.95557281, y: -0.29475517 },
|
2013-07-04 22:23:08 +08:00
|
|
|
|
];
|
|
|
|
|
|
2013-07-22 18:32:16 +08:00
|
|
|
|
// Those vectors come from bullet 3d
|
2013-10-10 04:59:44 +08:00
|
|
|
|
static SAMPLES_3_F32: [Vec3<f32>, ..42] = [
|
2013-08-05 15:44:56 +08:00
|
|
|
|
Vec3 { x: 0.000000 , y: -0.000000, z: -1.000000 },
|
|
|
|
|
Vec3 { x: 0.723608 , y: -0.525725, z: -0.447219 },
|
|
|
|
|
Vec3 { x: -0.276388, y: -0.850649, z: -0.447219 },
|
|
|
|
|
Vec3 { x: -0.894426, y: -0.000000, z: -0.447216 },
|
|
|
|
|
Vec3 { x: -0.276388, y: 0.850649 , z: -0.447220 },
|
|
|
|
|
Vec3 { x: 0.723608 , y: 0.525725 , z: -0.447219 },
|
|
|
|
|
Vec3 { x: 0.276388 , y: -0.850649, z: 0.447220 },
|
|
|
|
|
Vec3 { x: -0.723608, y: -0.525725, z: 0.447219 },
|
|
|
|
|
Vec3 { x: -0.723608, y: 0.525725 , z: 0.447219 },
|
|
|
|
|
Vec3 { x: 0.276388 , y: 0.850649 , z: 0.447219 },
|
|
|
|
|
Vec3 { x: 0.894426 , y: 0.000000 , z: 0.447216 },
|
|
|
|
|
Vec3 { x: -0.000000, y: 0.000000 , z: 1.000000 },
|
|
|
|
|
Vec3 { x: 0.425323 , y: -0.309011, z: -0.850654 },
|
|
|
|
|
Vec3 { x: -0.162456, y: -0.499995, z: -0.850654 },
|
|
|
|
|
Vec3 { x: 0.262869 , y: -0.809012, z: -0.525738 },
|
|
|
|
|
Vec3 { x: 0.425323 , y: 0.309011 , z: -0.850654 },
|
|
|
|
|
Vec3 { x: 0.850648 , y: -0.000000, z: -0.525736 },
|
|
|
|
|
Vec3 { x: -0.525730, y: -0.000000, z: -0.850652 },
|
|
|
|
|
Vec3 { x: -0.688190, y: -0.499997, z: -0.525736 },
|
|
|
|
|
Vec3 { x: -0.162456, y: 0.499995 , z: -0.850654 },
|
|
|
|
|
Vec3 { x: -0.688190, y: 0.499997 , z: -0.525736 },
|
|
|
|
|
Vec3 { x: 0.262869 , y: 0.809012 , z: -0.525738 },
|
|
|
|
|
Vec3 { x: 0.951058 , y: 0.309013 , z: 0.000000 },
|
|
|
|
|
Vec3 { x: 0.951058 , y: -0.309013, z: 0.000000 },
|
|
|
|
|
Vec3 { x: 0.587786 , y: -0.809017, z: 0.000000 },
|
|
|
|
|
Vec3 { x: 0.000000 , y: -1.000000, z: 0.000000 },
|
|
|
|
|
Vec3 { x: -0.587786, y: -0.809017, z: 0.000000 },
|
|
|
|
|
Vec3 { x: -0.951058, y: -0.309013, z: -0.000000 },
|
|
|
|
|
Vec3 { x: -0.951058, y: 0.309013 , z: -0.000000 },
|
|
|
|
|
Vec3 { x: -0.587786, y: 0.809017 , z: -0.000000 },
|
|
|
|
|
Vec3 { x: -0.000000, y: 1.000000 , z: -0.000000 },
|
|
|
|
|
Vec3 { x: 0.587786 , y: 0.809017 , z: -0.000000 },
|
|
|
|
|
Vec3 { x: 0.688190 , y: -0.499997, z: 0.525736 },
|
|
|
|
|
Vec3 { x: -0.262869, y: -0.809012, z: 0.525738 },
|
|
|
|
|
Vec3 { x: -0.850648, y: 0.000000 , z: 0.525736 },
|
|
|
|
|
Vec3 { x: -0.262869, y: 0.809012 , z: 0.525738 },
|
|
|
|
|
Vec3 { x: 0.688190 , y: 0.499997 , z: 0.525736 },
|
|
|
|
|
Vec3 { x: 0.525730 , y: 0.000000 , z: 0.850652 },
|
|
|
|
|
Vec3 { x: 0.162456 , y: -0.499995, z: 0.850654 },
|
|
|
|
|
Vec3 { x: -0.425323, y: -0.309011, z: 0.850654 },
|
|
|
|
|
Vec3 { x: -0.425323, y: 0.309011 , z: 0.850654 },
|
|
|
|
|
Vec3 { x: 0.162456 , y: 0.499995 , z: 0.850654 }
|
2013-07-22 18:32:16 +08:00
|
|
|
|
];
|
|
|
|
|
|
2013-09-08 22:03:03 +08:00
|
|
|
|
impl<N: One + Clone> UniformSphereSample for Vec1<N> {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn sample(f: &fn(Vec1<N>)) {
|
|
|
|
|
f(One::one())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-10 04:59:44 +08:00
|
|
|
|
impl<N: Cast<f32> + Clone> UniformSphereSample for Vec2<N> {
|
2013-08-08 02:53:51 +08:00
|
|
|
|
#[inline(always)]
|
Rework of the traits for Vectors.
The goal is to make traits less fine-grained for vectors, and reduce the amount of `use`.
- Scalar{Mul, Div} are removed, replaced by Mul<N, V> and Div<N, V>,
- Ring and DivisionRing are removed. Use Num instead.
- VectorSpace, Dot, and Norm are removed, replaced by the new, higher-level traits.
Add four traits:
- Vec: common operations on vectors. Replaces VectorSpace and Dot.
- AlgebraicVec: Vec + the old Norm trait.
- VecExt: Vec + every other traits vectors implement.
- AlgebraicVecExt: AlgebraicVec + VecExt.
2013-08-19 00:33:25 +08:00
|
|
|
|
fn sample(f: &fn(Vec2<N>)) {
|
2013-10-10 04:59:44 +08:00
|
|
|
|
for sample in SAMPLES_2_F32.iter() {
|
|
|
|
|
f(Cast::from(*sample))
|
2013-08-14 15:43:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2013-07-04 22:23:08 +08:00
|
|
|
|
}
|
2013-07-06 06:54:42 +08:00
|
|
|
|
|
2013-10-10 04:59:44 +08:00
|
|
|
|
impl<N: Cast<f32> + Clone> UniformSphereSample for Vec3<N> {
|
2013-08-08 02:53:51 +08:00
|
|
|
|
#[inline(always)]
|
Rework of the traits for Vectors.
The goal is to make traits less fine-grained for vectors, and reduce the amount of `use`.
- Scalar{Mul, Div} are removed, replaced by Mul<N, V> and Div<N, V>,
- Ring and DivisionRing are removed. Use Num instead.
- VectorSpace, Dot, and Norm are removed, replaced by the new, higher-level traits.
Add four traits:
- Vec: common operations on vectors. Replaces VectorSpace and Dot.
- AlgebraicVec: Vec + the old Norm trait.
- VecExt: Vec + every other traits vectors implement.
- AlgebraicVecExt: AlgebraicVec + VecExt.
2013-08-19 00:33:25 +08:00
|
|
|
|
fn sample(f: &fn(Vec3<N>)) {
|
2013-10-10 04:59:44 +08:00
|
|
|
|
for sample in SAMPLES_3_F32.iter() {
|
|
|
|
|
f(Cast::from(*sample))
|
2013-08-05 16:13:44 +08:00
|
|
|
|
}
|
2013-08-05 15:44:56 +08:00
|
|
|
|
}
|
2013-07-06 06:54:42 +08:00
|
|
|
|
}
|
2013-10-04 00:26:09 +08:00
|
|
|
|
|
2013-10-10 04:59:44 +08:00
|
|
|
|
impl<N: Cast<f32> + Clone> UniformSphereSample for Vec4<N> {
|
2013-10-04 00:26:09 +08:00
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn sample(_: &fn(Vec4<N>)) {
|
|
|
|
|
fail!("UniformSphereSample::<Vec4<N>>::sample : Not yet implemented.")
|
2013-10-10 04:59:44 +08:00
|
|
|
|
// for sample in SAMPLES_3_F32.iter() {
|
|
|
|
|
// f(Cast::from(*sample))
|
2013-10-04 00:26:09 +08:00
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
}
|