Moved Float4 and Matrix and Vector math into their own sub-crates.
This commit is contained in:
parent
5ab1a51f4c
commit
88578b9eae
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -55,6 +55,13 @@ name = "crossbeam"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "float4"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gcc"
|
name = "gcc"
|
||||||
version = "0.3.45"
|
version = "0.3.45"
|
||||||
|
@ -93,6 +100,13 @@ dependencies = [
|
||||||
"rgb 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rgb 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "math3d"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"float4 0.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mem_arena"
|
name = "mem_arena"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -141,16 +155,17 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"float4 0.1.0",
|
||||||
"halton 0.1.0",
|
"halton 0.1.0",
|
||||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lodepng 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lodepng 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"math3d 0.1.0",
|
||||||
"mem_arena 0.1.0",
|
"mem_arena 0.1.0",
|
||||||
"nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openexr 0.1.0 (git+https://github.com/cessen/openexr-rs?rev=612fc6c81c031970ffddcab15509236711613de8)",
|
"openexr 0.1.0 (git+https://github.com/cessen/openexr-rs?rev=612fc6c81c031970ffddcab15509236711613de8)",
|
||||||
"rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"scoped_threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"scoped_threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"sobol 0.1.0",
|
"sobol 0.1.0",
|
||||||
"spectra_xyz 0.1.0",
|
"spectra_xyz 0.1.0",
|
||||||
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
14
Cargo.toml
14
Cargo.toml
|
@ -1,7 +1,9 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"sub_crates/mem_arena",
|
"sub_crates/float4",
|
||||||
"sub_crates/halton",
|
"sub_crates/halton",
|
||||||
|
"sub_crates/math3d",
|
||||||
|
"sub_crates/mem_arena",
|
||||||
"sub_crates/sobol",
|
"sub_crates/sobol",
|
||||||
"sub_crates/spectra_xyz"
|
"sub_crates/spectra_xyz"
|
||||||
]
|
]
|
||||||
|
@ -12,7 +14,7 @@ version = "0.1.0"
|
||||||
authors = ["Nathan Vegdahl <cessen@cessen.com>"]
|
authors = ["Nathan Vegdahl <cessen@cessen.com>"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
simd_perf = ["simd"]
|
simd_perf = ["float4/simd_perf", "math3d/simd_perf"]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = true
|
debug = true
|
||||||
|
@ -28,15 +30,21 @@ crossbeam = "0.2"
|
||||||
num_cpus = "1.0"
|
num_cpus = "1.0"
|
||||||
lodepng = "0.8"
|
lodepng = "0.8"
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
simd = { version = "0.2.0", optional = true }
|
|
||||||
|
|
||||||
# Github dependencies
|
# Github dependencies
|
||||||
openexr = { git = "https://github.com/cessen/openexr-rs", rev = "612fc6c81c031970ffddcab15509236711613de8" }
|
openexr = { git = "https://github.com/cessen/openexr-rs", rev = "612fc6c81c031970ffddcab15509236711613de8" }
|
||||||
|
|
||||||
# Local crate dependencies
|
# Local crate dependencies
|
||||||
|
[dependencies.float4]
|
||||||
|
path = "sub_crates/float4"
|
||||||
|
|
||||||
[dependencies.halton]
|
[dependencies.halton]
|
||||||
path = "sub_crates/halton"
|
path = "sub_crates/halton"
|
||||||
|
|
||||||
|
[dependencies.math3d]
|
||||||
|
path = "sub_crates/math3d"
|
||||||
|
|
||||||
[dependencies.mem_arena]
|
[dependencies.mem_arena]
|
||||||
path = "sub_crates/mem_arena"
|
path = "sub_crates/mem_arena"
|
||||||
|
|
||||||
|
|
215
src/lerp.rs
215
src/lerp.rs
|
@ -1,5 +1,8 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use float4;
|
||||||
|
use math3d::{Matrix4x4, Normal, Point, Vector};
|
||||||
|
|
||||||
/// Trait for allowing a type to be linearly interpolated.
|
/// Trait for allowing a type to be linearly interpolated.
|
||||||
pub trait Lerp {
|
pub trait Lerp {
|
||||||
fn lerp(self, other: Self, alpha: f32) -> Self;
|
fn lerp(self, other: Self, alpha: f32) -> Self;
|
||||||
|
@ -73,6 +76,46 @@ impl<T: Lerp> Lerp for (T, T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Lerp for float4::Float4 {
|
||||||
|
fn lerp(self, other: float4::Float4, alpha: f32) -> float4::Float4 {
|
||||||
|
(self * (1.0 - alpha)) + (other * alpha)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Lerp for Matrix4x4 {
|
||||||
|
fn lerp(self, other: Matrix4x4, alpha: f32) -> Matrix4x4 {
|
||||||
|
let alpha_minus = 1.0 - alpha;
|
||||||
|
Matrix4x4 {
|
||||||
|
values: [(self[0] * alpha_minus) + (other[0] * alpha),
|
||||||
|
(self[1] * alpha_minus) + (other[1] * alpha),
|
||||||
|
(self[2] * alpha_minus) + (other[2] * alpha),
|
||||||
|
(self[3] * alpha_minus) + (other[3] * alpha)],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Lerp for Normal {
|
||||||
|
fn lerp(self, other: Normal, alpha: f32) -> Normal {
|
||||||
|
(self * (1.0 - alpha)) + (other * alpha)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Lerp for Point {
|
||||||
|
fn lerp(self, other: Point, alpha: f32) -> Point {
|
||||||
|
let s = self.norm();
|
||||||
|
let o = other.norm();
|
||||||
|
Point { co: (s.co * (1.0 - alpha)) + (o.co * alpha) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Lerp for Vector {
|
||||||
|
fn lerp(self, other: Vector, alpha: f32) -> Vector {
|
||||||
|
(self * (1.0 - alpha)) + (other * alpha)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -152,4 +195,176 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(2.5, lerp_slice(&s[..], alpha));
|
assert_eq!(2.5, lerp_slice(&s[..], alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lerp_matrix() {
|
||||||
|
let a = Matrix4x4::new_from_values(0.0,
|
||||||
|
2.0,
|
||||||
|
2.0,
|
||||||
|
3.0,
|
||||||
|
4.0,
|
||||||
|
5.0,
|
||||||
|
6.0,
|
||||||
|
7.0,
|
||||||
|
8.0,
|
||||||
|
9.0,
|
||||||
|
10.0,
|
||||||
|
11.0,
|
||||||
|
12.0,
|
||||||
|
13.0,
|
||||||
|
14.0,
|
||||||
|
15.0);
|
||||||
|
let b = Matrix4x4::new_from_values(-1.0,
|
||||||
|
1.0,
|
||||||
|
3.0,
|
||||||
|
4.0,
|
||||||
|
5.0,
|
||||||
|
6.0,
|
||||||
|
7.0,
|
||||||
|
8.0,
|
||||||
|
9.0,
|
||||||
|
10.0,
|
||||||
|
11.0,
|
||||||
|
12.0,
|
||||||
|
13.0,
|
||||||
|
14.0,
|
||||||
|
15.0,
|
||||||
|
16.0);
|
||||||
|
|
||||||
|
let c1 = Matrix4x4::new_from_values(-0.25,
|
||||||
|
1.75,
|
||||||
|
2.25,
|
||||||
|
3.25,
|
||||||
|
4.25,
|
||||||
|
5.25,
|
||||||
|
6.25,
|
||||||
|
7.25,
|
||||||
|
8.25,
|
||||||
|
9.25,
|
||||||
|
10.25,
|
||||||
|
11.25,
|
||||||
|
12.25,
|
||||||
|
13.25,
|
||||||
|
14.25,
|
||||||
|
15.25);
|
||||||
|
let c2 = Matrix4x4::new_from_values(-0.5,
|
||||||
|
1.5,
|
||||||
|
2.5,
|
||||||
|
3.5,
|
||||||
|
4.5,
|
||||||
|
5.5,
|
||||||
|
6.5,
|
||||||
|
7.5,
|
||||||
|
8.5,
|
||||||
|
9.5,
|
||||||
|
10.5,
|
||||||
|
11.5,
|
||||||
|
12.5,
|
||||||
|
13.5,
|
||||||
|
14.5,
|
||||||
|
15.5);
|
||||||
|
let c3 = Matrix4x4::new_from_values(-0.75,
|
||||||
|
1.25,
|
||||||
|
2.75,
|
||||||
|
3.75,
|
||||||
|
4.75,
|
||||||
|
5.75,
|
||||||
|
6.75,
|
||||||
|
7.75,
|
||||||
|
8.75,
|
||||||
|
9.75,
|
||||||
|
10.75,
|
||||||
|
11.75,
|
||||||
|
12.75,
|
||||||
|
13.75,
|
||||||
|
14.75,
|
||||||
|
15.75);
|
||||||
|
|
||||||
|
assert_eq!(a.lerp(b, 0.0), a);
|
||||||
|
assert_eq!(a.lerp(b, 0.25), c1);
|
||||||
|
assert_eq!(a.lerp(b, 0.5), c2);
|
||||||
|
assert_eq!(a.lerp(b, 0.75), c3);
|
||||||
|
assert_eq!(a.lerp(b, 1.0), b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lerp_point_1() {
|
||||||
|
let p1 = Point::new(1.0, 2.0, 1.0);
|
||||||
|
let p2 = Point::new(-2.0, 1.0, -1.0);
|
||||||
|
let p3 = Point::new(1.0, 2.0, 1.0);
|
||||||
|
|
||||||
|
assert_eq!(p3, p1.lerp(p2, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lerp_point_2() {
|
||||||
|
let p1 = Point::new(1.0, 2.0, 1.0);
|
||||||
|
let p2 = Point::new(-2.0, 1.0, -1.0);
|
||||||
|
let p3 = Point::new(-2.0, 1.0, -1.0);
|
||||||
|
|
||||||
|
assert_eq!(p3, p1.lerp(p2, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lerp_point_3() {
|
||||||
|
let p1 = Point::new(1.0, 2.0, 1.0);
|
||||||
|
let p2 = Point::new(-2.0, 1.0, -1.0);
|
||||||
|
let p3 = Point::new(-0.5, 1.5, 0.0);
|
||||||
|
|
||||||
|
assert_eq!(p3, p1.lerp(p2, 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lerp_normal_1() {
|
||||||
|
let n1 = Normal::new(1.0, 2.0, 1.0);
|
||||||
|
let n2 = Normal::new(-2.0, 1.0, -1.0);
|
||||||
|
let n3 = Normal::new(1.0, 2.0, 1.0);
|
||||||
|
|
||||||
|
assert_eq!(n3, n1.lerp(n2, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lerp_normal_2() {
|
||||||
|
let n1 = Normal::new(1.0, 2.0, 1.0);
|
||||||
|
let n2 = Normal::new(-2.0, 1.0, -1.0);
|
||||||
|
let n3 = Normal::new(-2.0, 1.0, -1.0);
|
||||||
|
|
||||||
|
assert_eq!(n3, n1.lerp(n2, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lerp_normal_3() {
|
||||||
|
let n1 = Normal::new(1.0, 2.0, 1.0);
|
||||||
|
let n2 = Normal::new(-2.0, 1.0, -1.0);
|
||||||
|
let n3 = Normal::new(-0.5, 1.5, 0.0);
|
||||||
|
|
||||||
|
assert_eq!(n3, n1.lerp(n2, 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lerp_vector_1() {
|
||||||
|
let v1 = Vector::new(1.0, 2.0, 1.0);
|
||||||
|
let v2 = Vector::new(-2.0, 1.0, -1.0);
|
||||||
|
let v3 = Vector::new(1.0, 2.0, 1.0);
|
||||||
|
|
||||||
|
assert_eq!(v3, v1.lerp(v2, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lerp_vector_2() {
|
||||||
|
let v1 = Vector::new(1.0, 2.0, 1.0);
|
||||||
|
let v2 = Vector::new(-2.0, 1.0, -1.0);
|
||||||
|
let v3 = Vector::new(-2.0, 1.0, -1.0);
|
||||||
|
|
||||||
|
assert_eq!(v3, v1.lerp(v2, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lerp_vector_3() {
|
||||||
|
let v1 = Vector::new(1.0, 2.0, 1.0);
|
||||||
|
let v2 = Vector::new(-2.0, 1.0, -1.0);
|
||||||
|
let v3 = Vector::new(-0.5, 1.5, 0.0);
|
||||||
|
|
||||||
|
assert_eq!(v3, v1.lerp(v2, 0.5));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
|
||||||
|
extern crate float4;
|
||||||
extern crate halton;
|
extern crate halton;
|
||||||
|
extern crate math3d;
|
||||||
extern crate mem_arena;
|
extern crate mem_arena;
|
||||||
extern crate spectra_xyz;
|
extern crate spectra_xyz;
|
||||||
|
|
||||||
|
@ -17,9 +20,6 @@ extern crate nom;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
|
||||||
extern crate simd;
|
|
||||||
|
|
||||||
mod accel;
|
mod accel;
|
||||||
mod algorithm;
|
mod algorithm;
|
||||||
mod bbox;
|
mod bbox;
|
||||||
|
@ -28,7 +28,6 @@ mod bitstack;
|
||||||
mod boundable;
|
mod boundable;
|
||||||
mod camera;
|
mod camera;
|
||||||
mod color;
|
mod color;
|
||||||
mod float4;
|
|
||||||
mod hash;
|
mod hash;
|
||||||
mod hilbert;
|
mod hilbert;
|
||||||
mod image;
|
mod image;
|
||||||
|
|
|
@ -1,35 +1,5 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
pub use math3d::{Matrix4x4, Normal, Point, Vector, DotProduct, dot, CrossProduct, cross};
|
||||||
mod matrix;
|
|
||||||
mod normal;
|
|
||||||
mod point;
|
|
||||||
mod vector;
|
|
||||||
|
|
||||||
pub use self::matrix::Matrix4x4;
|
|
||||||
pub use self::normal::Normal;
|
|
||||||
pub use self::point::Point;
|
|
||||||
pub use self::vector::Vector;
|
|
||||||
|
|
||||||
|
|
||||||
/// Trait for calculating dot products.
|
|
||||||
pub trait DotProduct {
|
|
||||||
fn dot(self, other: Self) -> f32;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dot<T: DotProduct>(a: T, b: T) -> f32 {
|
|
||||||
a.dot(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Trait for calculating cross products.
|
|
||||||
pub trait CrossProduct {
|
|
||||||
fn cross(self, other: Self) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cross<T: CrossProduct>(a: T, b: T) -> T {
|
|
||||||
a.cross(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Clamps a value between a min and max.
|
/// Clamps a value between a min and max.
|
||||||
pub fn clamp<T: PartialOrd>(v: T, lower: T, upper: T) -> T {
|
pub fn clamp<T: PartialOrd>(v: T, lower: T, upper: T) -> T {
|
16
sub_crates/float4/Cargo.toml
Normal file
16
sub_crates/float4/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "float4"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Nathan Vegdahl <cessen@cessen.com>"]
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "float4"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
simd_perf = ["simd"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# Crates.io dependencies
|
||||||
|
simd = { version = "0.2.0", optional = true }
|
|
@ -1,13 +1,14 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
#[cfg(feature = "simd_perf")]
|
||||||
|
extern crate simd;
|
||||||
|
|
||||||
use std::cmp::PartialEq;
|
use std::cmp::PartialEq;
|
||||||
use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign, BitAnd};
|
use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign, BitAnd};
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
use simd::{f32x4, bool32fx4};
|
use simd::{f32x4, bool32fx4};
|
||||||
|
|
||||||
use lerp::Lerp;
|
|
||||||
|
|
||||||
/// Essentially a tuple of four floats, which will use SIMD operations
|
/// Essentially a tuple of four floats, which will use SIMD operations
|
||||||
/// where possible on a platform.
|
/// where possible on a platform.
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
@ -24,31 +25,38 @@ pub struct Float4 {
|
||||||
|
|
||||||
impl Float4 {
|
impl Float4 {
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
pub fn new(a: f32, b: f32, c: f32, d: f32) -> Float4 {
|
pub fn new(a: f32, b: f32, c: f32, d: f32) -> Float4 {
|
||||||
Float4 { data: f32x4::new(a, b, c, d) }
|
Float4 { data: f32x4::new(a, b, c, d) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline(always)]
|
||||||
pub fn new(a: f32, b: f32, c: f32, d: f32) -> Float4 {
|
pub fn new(a: f32, b: f32, c: f32, d: f32) -> Float4 {
|
||||||
Float4 { data: [a, b, c, d] }
|
Float4 { data: [a, b, c, d] }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
pub fn splat(n: f32) -> Float4 {
|
pub fn splat(n: f32) -> Float4 {
|
||||||
Float4 { data: f32x4::splat(n) }
|
Float4 { data: f32x4::splat(n) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline(always)]
|
||||||
pub fn splat(n: f32) -> Float4 {
|
pub fn splat(n: f32) -> Float4 {
|
||||||
Float4 { data: [n, n, n, n] }
|
Float4 { data: [n, n, n, n] }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn h_sum(&self) -> f32 {
|
pub fn h_sum(&self) -> f32 {
|
||||||
(self.get_0() + self.get_1()) + (self.get_2() + self.get_3())
|
(self.get_0() + self.get_1()) + (self.get_2() + self.get_3())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn h_product(&self) -> f32 {
|
pub fn h_product(&self) -> f32 {
|
||||||
(self.get_0() * self.get_1()) * (self.get_2() * self.get_3())
|
(self.get_0() * self.get_1()) * (self.get_2() * self.get_3())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn h_min(&self) -> f32 {
|
pub fn h_min(&self) -> f32 {
|
||||||
let n1 = if self.get_0() < self.get_1() {
|
let n1 = if self.get_0() < self.get_1() {
|
||||||
self.get_0()
|
self.get_0()
|
||||||
|
@ -63,6 +71,7 @@ impl Float4 {
|
||||||
if n1 < n2 { n1 } else { n2 }
|
if n1 < n2 { n1 } else { n2 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn h_max(&self) -> f32 {
|
pub fn h_max(&self) -> f32 {
|
||||||
let n1 = if self.get_0() > self.get_1() {
|
let n1 = if self.get_0() > self.get_1() {
|
||||||
self.get_0()
|
self.get_0()
|
||||||
|
@ -78,10 +87,12 @@ impl Float4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
pub fn v_min(&self, other: Float4) -> Float4 {
|
pub fn v_min(&self, other: Float4) -> Float4 {
|
||||||
Float4 { data: self.data.min(other.data) }
|
Float4 { data: self.data.min(other.data) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline]
|
||||||
pub fn v_min(&self, other: Float4) -> Float4 {
|
pub fn v_min(&self, other: Float4) -> Float4 {
|
||||||
Float4::new(if self.get_0() < other.get_0() {
|
Float4::new(if self.get_0() < other.get_0() {
|
||||||
self.get_0()
|
self.get_0()
|
||||||
|
@ -107,10 +118,12 @@ impl Float4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
pub fn v_max(&self, other: Float4) -> Float4 {
|
pub fn v_max(&self, other: Float4) -> Float4 {
|
||||||
Float4 { data: self.data.max(other.data) }
|
Float4 { data: self.data.max(other.data) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline]
|
||||||
pub fn v_max(&self, other: Float4) -> Float4 {
|
pub fn v_max(&self, other: Float4) -> Float4 {
|
||||||
Float4::new(if self.get_0() > other.get_0() {
|
Float4::new(if self.get_0() > other.get_0() {
|
||||||
self.get_0()
|
self.get_0()
|
||||||
|
@ -135,10 +148,12 @@ impl Float4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
pub fn lt(&self, other: Float4) -> Bool4 {
|
pub fn lt(&self, other: Float4) -> Bool4 {
|
||||||
Bool4 { data: self.data.lt(other.data) }
|
Bool4 { data: self.data.lt(other.data) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline]
|
||||||
pub fn lt(&self, other: Float4) -> Bool4 {
|
pub fn lt(&self, other: Float4) -> Bool4 {
|
||||||
Bool4 {
|
Bool4 {
|
||||||
data: [self.data[0] < other.data[0],
|
data: [self.data[0] < other.data[0],
|
||||||
|
@ -149,10 +164,12 @@ impl Float4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
pub fn lte(&self, other: Float4) -> Bool4 {
|
pub fn lte(&self, other: Float4) -> Bool4 {
|
||||||
Bool4 { data: self.data.le(other.data) }
|
Bool4 { data: self.data.le(other.data) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline]
|
||||||
pub fn lte(&self, other: Float4) -> Bool4 {
|
pub fn lte(&self, other: Float4) -> Bool4 {
|
||||||
Bool4 {
|
Bool4 {
|
||||||
data: [self.data[0] <= other.data[0],
|
data: [self.data[0] <= other.data[0],
|
||||||
|
@ -163,10 +180,12 @@ impl Float4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
pub fn gt(&self, other: Float4) -> Bool4 {
|
pub fn gt(&self, other: Float4) -> Bool4 {
|
||||||
Bool4 { data: self.data.gt(other.data) }
|
Bool4 { data: self.data.gt(other.data) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline]
|
||||||
pub fn gt(&self, other: Float4) -> Bool4 {
|
pub fn gt(&self, other: Float4) -> Bool4 {
|
||||||
Bool4 {
|
Bool4 {
|
||||||
data: [self.data[0] > other.data[0],
|
data: [self.data[0] > other.data[0],
|
||||||
|
@ -177,10 +196,12 @@ impl Float4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
pub fn gte(&self, other: Float4) -> Bool4 {
|
pub fn gte(&self, other: Float4) -> Bool4 {
|
||||||
Bool4 { data: self.data.ge(other.data) }
|
Bool4 { data: self.data.ge(other.data) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline]
|
||||||
pub fn gte(&self, other: Float4) -> Bool4 {
|
pub fn gte(&self, other: Float4) -> Bool4 {
|
||||||
Bool4 {
|
Bool4 {
|
||||||
data: [self.data[0] >= other.data[0],
|
data: [self.data[0] >= other.data[0],
|
||||||
|
@ -208,8 +229,8 @@ impl Float4 {
|
||||||
pub fn set_0(&mut self, n: f32) {
|
pub fn set_0(&mut self, n: f32) {
|
||||||
self.data = self.data.replace(0, n);
|
self.data = self.data.replace(0, n);
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_0(&mut self, n: f32) {
|
pub fn set_0(&mut self, n: f32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
*self.data.get_unchecked_mut(0) = n;
|
*self.data.get_unchecked_mut(0) = n;
|
||||||
|
@ -321,6 +342,7 @@ impl Float4 {
|
||||||
|
|
||||||
|
|
||||||
impl PartialEq for Float4 {
|
impl PartialEq for Float4 {
|
||||||
|
#[inline]
|
||||||
fn eq(&self, other: &Float4) -> bool {
|
fn eq(&self, other: &Float4) -> bool {
|
||||||
self.get_0() == other.get_0() && self.get_1() == other.get_1() &&
|
self.get_0() == other.get_0() && self.get_1() == other.get_1() &&
|
||||||
self.get_2() == other.get_2() && self.get_3() == other.get_3()
|
self.get_2() == other.get_2() && self.get_3() == other.get_3()
|
||||||
|
@ -332,10 +354,12 @@ impl Add for Float4 {
|
||||||
type Output = Float4;
|
type Output = Float4;
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
fn add(self, other: Float4) -> Float4 {
|
fn add(self, other: Float4) -> Float4 {
|
||||||
Float4 { data: self.data + other.data }
|
Float4 { data: self.data + other.data }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline(always)]
|
||||||
fn add(self, other: Float4) -> Float4 {
|
fn add(self, other: Float4) -> Float4 {
|
||||||
Float4 {
|
Float4 {
|
||||||
data: [self.get_0() + other.get_0(),
|
data: [self.get_0() + other.get_0(),
|
||||||
|
@ -348,6 +372,7 @@ impl Add for Float4 {
|
||||||
|
|
||||||
|
|
||||||
impl AddAssign for Float4 {
|
impl AddAssign for Float4 {
|
||||||
|
#[inline(always)]
|
||||||
fn add_assign(&mut self, rhs: Float4) {
|
fn add_assign(&mut self, rhs: Float4) {
|
||||||
*self = *self + rhs;
|
*self = *self + rhs;
|
||||||
}
|
}
|
||||||
|
@ -358,10 +383,12 @@ impl Sub for Float4 {
|
||||||
type Output = Float4;
|
type Output = Float4;
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
fn sub(self, other: Float4) -> Float4 {
|
fn sub(self, other: Float4) -> Float4 {
|
||||||
Float4 { data: self.data - other.data }
|
Float4 { data: self.data - other.data }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline(always)]
|
||||||
fn sub(self, other: Float4) -> Float4 {
|
fn sub(self, other: Float4) -> Float4 {
|
||||||
Float4 {
|
Float4 {
|
||||||
data: [self.get_0() - other.get_0(),
|
data: [self.get_0() - other.get_0(),
|
||||||
|
@ -374,6 +401,7 @@ impl Sub for Float4 {
|
||||||
|
|
||||||
|
|
||||||
impl SubAssign for Float4 {
|
impl SubAssign for Float4 {
|
||||||
|
#[inline(always)]
|
||||||
fn sub_assign(&mut self, rhs: Float4) {
|
fn sub_assign(&mut self, rhs: Float4) {
|
||||||
*self = *self - rhs;
|
*self = *self - rhs;
|
||||||
}
|
}
|
||||||
|
@ -384,10 +412,12 @@ impl Mul for Float4 {
|
||||||
type Output = Float4;
|
type Output = Float4;
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
fn mul(self, other: Float4) -> Float4 {
|
fn mul(self, other: Float4) -> Float4 {
|
||||||
Float4 { data: self.data * other.data }
|
Float4 { data: self.data * other.data }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline(always)]
|
||||||
fn mul(self, other: Float4) -> Float4 {
|
fn mul(self, other: Float4) -> Float4 {
|
||||||
Float4 {
|
Float4 {
|
||||||
data: [self.get_0() * other.get_0(),
|
data: [self.get_0() * other.get_0(),
|
||||||
|
@ -402,10 +432,12 @@ impl Mul<f32> for Float4 {
|
||||||
type Output = Float4;
|
type Output = Float4;
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
fn mul(self, other: f32) -> Float4 {
|
fn mul(self, other: f32) -> Float4 {
|
||||||
Float4 { data: self.data * f32x4::splat(other) }
|
Float4 { data: self.data * f32x4::splat(other) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline(always)]
|
||||||
fn mul(self, other: f32) -> Float4 {
|
fn mul(self, other: f32) -> Float4 {
|
||||||
Float4 {
|
Float4 {
|
||||||
data: [self.get_0() * other,
|
data: [self.get_0() * other,
|
||||||
|
@ -418,12 +450,14 @@ impl Mul<f32> for Float4 {
|
||||||
|
|
||||||
|
|
||||||
impl MulAssign for Float4 {
|
impl MulAssign for Float4 {
|
||||||
|
#[inline(always)]
|
||||||
fn mul_assign(&mut self, rhs: Float4) {
|
fn mul_assign(&mut self, rhs: Float4) {
|
||||||
*self = *self * rhs;
|
*self = *self * rhs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MulAssign<f32> for Float4 {
|
impl MulAssign<f32> for Float4 {
|
||||||
|
#[inline(always)]
|
||||||
fn mul_assign(&mut self, rhs: f32) {
|
fn mul_assign(&mut self, rhs: f32) {
|
||||||
*self = *self * rhs;
|
*self = *self * rhs;
|
||||||
}
|
}
|
||||||
|
@ -434,10 +468,12 @@ impl Div for Float4 {
|
||||||
type Output = Float4;
|
type Output = Float4;
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
fn div(self, other: Float4) -> Float4 {
|
fn div(self, other: Float4) -> Float4 {
|
||||||
Float4 { data: self.data / other.data }
|
Float4 { data: self.data / other.data }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline(always)]
|
||||||
fn div(self, other: Float4) -> Float4 {
|
fn div(self, other: Float4) -> Float4 {
|
||||||
Float4 {
|
Float4 {
|
||||||
data: [self.get_0() / other.get_0(),
|
data: [self.get_0() / other.get_0(),
|
||||||
|
@ -452,10 +488,12 @@ impl Div<f32> for Float4 {
|
||||||
type Output = Float4;
|
type Output = Float4;
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
fn div(self, other: f32) -> Float4 {
|
fn div(self, other: f32) -> Float4 {
|
||||||
Float4 { data: self.data / f32x4::splat(other) }
|
Float4 { data: self.data / f32x4::splat(other) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline(always)]
|
||||||
fn div(self, other: f32) -> Float4 {
|
fn div(self, other: f32) -> Float4 {
|
||||||
Float4 {
|
Float4 {
|
||||||
data: [self.get_0() / other,
|
data: [self.get_0() / other,
|
||||||
|
@ -468,24 +506,19 @@ impl Div<f32> for Float4 {
|
||||||
|
|
||||||
|
|
||||||
impl DivAssign for Float4 {
|
impl DivAssign for Float4 {
|
||||||
|
#[inline(always)]
|
||||||
fn div_assign(&mut self, rhs: Float4) {
|
fn div_assign(&mut self, rhs: Float4) {
|
||||||
*self = *self / rhs;
|
*self = *self / rhs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DivAssign<f32> for Float4 {
|
impl DivAssign<f32> for Float4 {
|
||||||
|
#[inline(always)]
|
||||||
fn div_assign(&mut self, rhs: f32) {
|
fn div_assign(&mut self, rhs: f32) {
|
||||||
*self = *self / rhs;
|
*self = *self / rhs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Lerp for Float4 {
|
|
||||||
fn lerp(self, other: Float4, alpha: f32) -> Float4 {
|
|
||||||
(self * (1.0 - alpha)) + (other * alpha)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn v_min(a: Float4, b: Float4) -> Float4 {
|
pub fn v_min(a: Float4, b: Float4) -> Float4 {
|
||||||
a.v_min(b)
|
a.v_min(b)
|
||||||
|
@ -560,6 +593,7 @@ impl Bool4 {
|
||||||
unsafe { *self.data.get_unchecked(3) }
|
unsafe { *self.data.get_unchecked(3) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn to_bitmask(&self) -> u8 {
|
pub fn to_bitmask(&self) -> u8 {
|
||||||
(self.get_0() as u8) | ((self.get_1() as u8) << 1) | ((self.get_2() as u8) << 2) |
|
(self.get_0() as u8) | ((self.get_1() as u8) << 1) | ((self.get_2() as u8) << 2) |
|
||||||
((self.get_3() as u8) << 3)
|
((self.get_3() as u8) << 3)
|
||||||
|
@ -570,10 +604,12 @@ impl BitAnd for Bool4 {
|
||||||
type Output = Bool4;
|
type Output = Bool4;
|
||||||
|
|
||||||
#[cfg(feature = "simd_perf")]
|
#[cfg(feature = "simd_perf")]
|
||||||
|
#[inline(always)]
|
||||||
fn bitand(self, rhs: Bool4) -> Bool4 {
|
fn bitand(self, rhs: Bool4) -> Bool4 {
|
||||||
Bool4 { data: self.data & rhs.data }
|
Bool4 { data: self.data & rhs.data }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "simd_perf"))]
|
#[cfg(not(feature = "simd_perf"))]
|
||||||
|
#[inline]
|
||||||
fn bitand(self, rhs: Bool4) -> Bool4 {
|
fn bitand(self, rhs: Bool4) -> Bool4 {
|
||||||
Bool4 {
|
Bool4 {
|
||||||
data: [self.data[0] && rhs.data[0],
|
data: [self.data[0] && rhs.data[0],
|
16
sub_crates/math3d/Cargo.toml
Normal file
16
sub_crates/math3d/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "math3d"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Nathan Vegdahl <cessen@cessen.com>"]
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "math3d"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
simd_perf = ["float4/simd_perf"]
|
||||||
|
|
||||||
|
# Local crate dependencies
|
||||||
|
[dependencies.float4]
|
||||||
|
path = "../float4"
|
36
sub_crates/math3d/src/lib.rs
Normal file
36
sub_crates/math3d/src/lib.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
extern crate float4;
|
||||||
|
|
||||||
|
mod matrix;
|
||||||
|
mod normal;
|
||||||
|
mod point;
|
||||||
|
mod vector;
|
||||||
|
|
||||||
|
pub use self::matrix::Matrix4x4;
|
||||||
|
pub use self::normal::Normal;
|
||||||
|
pub use self::point::Point;
|
||||||
|
pub use self::vector::Vector;
|
||||||
|
|
||||||
|
/// Trait for calculating dot products.
|
||||||
|
pub trait DotProduct {
|
||||||
|
#[inline]
|
||||||
|
fn dot(self, other: Self) -> f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn dot<T: DotProduct>(a: T, b: T) -> f32 {
|
||||||
|
a.dot(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Trait for calculating cross products.
|
||||||
|
pub trait CrossProduct {
|
||||||
|
#[inline]
|
||||||
|
fn cross(self, other: Self) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn cross<T: CrossProduct>(a: T, b: T) -> T {
|
||||||
|
a.cross(b)
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ use std;
|
||||||
use std::ops::{Index, IndexMut, Mul};
|
use std::ops::{Index, IndexMut, Mul};
|
||||||
|
|
||||||
use float4::Float4;
|
use float4::Float4;
|
||||||
use lerp::Lerp;
|
|
||||||
|
|
||||||
use super::Point;
|
use super::Point;
|
||||||
|
|
||||||
|
@ -12,12 +11,13 @@ use super::Point;
|
||||||
/// A 4x4 matrix, used for transforms
|
/// A 4x4 matrix, used for transforms
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct Matrix4x4 {
|
pub struct Matrix4x4 {
|
||||||
values: [Float4; 4],
|
pub values: [Float4; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Matrix4x4 {
|
impl Matrix4x4 {
|
||||||
/// Creates a new identity matrix
|
/// Creates a new identity matrix
|
||||||
|
#[inline]
|
||||||
pub fn new() -> Matrix4x4 {
|
pub fn new() -> Matrix4x4 {
|
||||||
Matrix4x4 {
|
Matrix4x4 {
|
||||||
values: [Float4::new(1.0, 0.0, 0.0, 0.0),
|
values: [Float4::new(1.0, 0.0, 0.0, 0.0),
|
||||||
|
@ -32,6 +32,7 @@ impl Matrix4x4 {
|
||||||
/// e f g h
|
/// e f g h
|
||||||
/// i j k l
|
/// i j k l
|
||||||
/// m n o p
|
/// m n o p
|
||||||
|
#[inline]
|
||||||
pub fn new_from_values(a: f32,
|
pub fn new_from_values(a: f32,
|
||||||
b: f32,
|
b: f32,
|
||||||
c: f32,
|
c: f32,
|
||||||
|
@ -57,6 +58,7 @@ impl Matrix4x4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn from_location(loc: Point) -> Matrix4x4 {
|
pub fn from_location(loc: Point) -> Matrix4x4 {
|
||||||
Matrix4x4 {
|
Matrix4x4 {
|
||||||
values: [Float4::new(1.0, 0.0, 0.0, loc.x()),
|
values: [Float4::new(1.0, 0.0, 0.0, loc.x()),
|
||||||
|
@ -69,6 +71,7 @@ impl Matrix4x4 {
|
||||||
/// Returns whether the matrices are approximately equal to each other.
|
/// Returns whether the matrices are approximately equal to each other.
|
||||||
/// Each corresponding element in the matrices cannot have a relative error
|
/// Each corresponding element in the matrices cannot have a relative error
|
||||||
/// exceeding `epsilon`.
|
/// exceeding `epsilon`.
|
||||||
|
#[inline]
|
||||||
pub fn aprx_eq(&self, other: Matrix4x4, epsilon: f32) -> bool {
|
pub fn aprx_eq(&self, other: Matrix4x4, epsilon: f32) -> bool {
|
||||||
let mut result = true;
|
let mut result = true;
|
||||||
|
|
||||||
|
@ -99,6 +102,7 @@ impl Matrix4x4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the transpose of the matrix
|
/// Returns the transpose of the matrix
|
||||||
|
#[inline]
|
||||||
pub fn transposed(&self) -> Matrix4x4 {
|
pub fn transposed(&self) -> Matrix4x4 {
|
||||||
Matrix4x4 {
|
Matrix4x4 {
|
||||||
values: {
|
values: {
|
||||||
|
@ -124,6 +128,7 @@ impl Matrix4x4 {
|
||||||
|
|
||||||
|
|
||||||
/// Returns the inverse of the Matrix
|
/// Returns the inverse of the Matrix
|
||||||
|
#[inline]
|
||||||
pub fn inverse(&self) -> Matrix4x4 {
|
pub fn inverse(&self) -> Matrix4x4 {
|
||||||
let s0 = (self[0].get_0() * self[1].get_1()) - (self[1].get_0() * self[0].get_1());
|
let s0 = (self[0].get_0() * self[1].get_1()) - (self[1].get_0() * self[0].get_1());
|
||||||
let s1 = (self[0].get_0() * self[1].get_2()) - (self[1].get_0() * self[0].get_2());
|
let s1 = (self[0].get_0() * self[1].get_2()) - (self[1].get_0() * self[0].get_2());
|
||||||
|
@ -189,6 +194,7 @@ impl Matrix4x4 {
|
||||||
impl Index<usize> for Matrix4x4 {
|
impl Index<usize> for Matrix4x4 {
|
||||||
type Output = Float4;
|
type Output = Float4;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn index<'a>(&'a self, _index: usize) -> &'a Float4 {
|
fn index<'a>(&'a self, _index: usize) -> &'a Float4 {
|
||||||
&self.values[_index]
|
&self.values[_index]
|
||||||
}
|
}
|
||||||
|
@ -196,6 +202,7 @@ impl Index<usize> for Matrix4x4 {
|
||||||
|
|
||||||
|
|
||||||
impl IndexMut<usize> for Matrix4x4 {
|
impl IndexMut<usize> for Matrix4x4 {
|
||||||
|
#[inline(always)]
|
||||||
fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut Float4 {
|
fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut Float4 {
|
||||||
&mut self.values[_index]
|
&mut self.values[_index]
|
||||||
}
|
}
|
||||||
|
@ -203,6 +210,7 @@ impl IndexMut<usize> for Matrix4x4 {
|
||||||
|
|
||||||
|
|
||||||
impl PartialEq for Matrix4x4 {
|
impl PartialEq for Matrix4x4 {
|
||||||
|
#[inline]
|
||||||
fn eq(&self, other: &Matrix4x4) -> bool {
|
fn eq(&self, other: &Matrix4x4) -> bool {
|
||||||
let mut result = true;
|
let mut result = true;
|
||||||
|
|
||||||
|
@ -221,6 +229,7 @@ impl PartialEq for Matrix4x4 {
|
||||||
impl Mul<Matrix4x4> for Matrix4x4 {
|
impl Mul<Matrix4x4> for Matrix4x4 {
|
||||||
type Output = Matrix4x4;
|
type Output = Matrix4x4;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn mul(self, other: Matrix4x4) -> Matrix4x4 {
|
fn mul(self, other: Matrix4x4) -> Matrix4x4 {
|
||||||
let m = self.transposed();
|
let m = self.transposed();
|
||||||
Matrix4x4 {
|
Matrix4x4 {
|
||||||
|
@ -248,23 +257,12 @@ impl Mul<Matrix4x4> for Matrix4x4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Lerp for Matrix4x4 {
|
|
||||||
fn lerp(self, other: Matrix4x4, alpha: f32) -> Matrix4x4 {
|
|
||||||
let alpha_minus = 1.0 - alpha;
|
|
||||||
Matrix4x4 {
|
|
||||||
values: [(self[0] * alpha_minus) + (other[0] * alpha),
|
|
||||||
(self[1] * alpha_minus) + (other[1] * alpha),
|
|
||||||
(self[2] * alpha_minus) + (other[2] * alpha),
|
|
||||||
(self[3] * alpha_minus) + (other[3] * alpha)],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use lerp::Lerp;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn equality_test() {
|
fn equality_test() {
|
||||||
|
@ -464,95 +462,4 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(b, c);
|
assert_eq!(b, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lerp_test() {
|
|
||||||
let a = Matrix4x4::new_from_values(0.0,
|
|
||||||
2.0,
|
|
||||||
2.0,
|
|
||||||
3.0,
|
|
||||||
4.0,
|
|
||||||
5.0,
|
|
||||||
6.0,
|
|
||||||
7.0,
|
|
||||||
8.0,
|
|
||||||
9.0,
|
|
||||||
10.0,
|
|
||||||
11.0,
|
|
||||||
12.0,
|
|
||||||
13.0,
|
|
||||||
14.0,
|
|
||||||
15.0);
|
|
||||||
let b = Matrix4x4::new_from_values(-1.0,
|
|
||||||
1.0,
|
|
||||||
3.0,
|
|
||||||
4.0,
|
|
||||||
5.0,
|
|
||||||
6.0,
|
|
||||||
7.0,
|
|
||||||
8.0,
|
|
||||||
9.0,
|
|
||||||
10.0,
|
|
||||||
11.0,
|
|
||||||
12.0,
|
|
||||||
13.0,
|
|
||||||
14.0,
|
|
||||||
15.0,
|
|
||||||
16.0);
|
|
||||||
|
|
||||||
let c1 = Matrix4x4::new_from_values(-0.25,
|
|
||||||
1.75,
|
|
||||||
2.25,
|
|
||||||
3.25,
|
|
||||||
4.25,
|
|
||||||
5.25,
|
|
||||||
6.25,
|
|
||||||
7.25,
|
|
||||||
8.25,
|
|
||||||
9.25,
|
|
||||||
10.25,
|
|
||||||
11.25,
|
|
||||||
12.25,
|
|
||||||
13.25,
|
|
||||||
14.25,
|
|
||||||
15.25);
|
|
||||||
let c2 = Matrix4x4::new_from_values(-0.5,
|
|
||||||
1.5,
|
|
||||||
2.5,
|
|
||||||
3.5,
|
|
||||||
4.5,
|
|
||||||
5.5,
|
|
||||||
6.5,
|
|
||||||
7.5,
|
|
||||||
8.5,
|
|
||||||
9.5,
|
|
||||||
10.5,
|
|
||||||
11.5,
|
|
||||||
12.5,
|
|
||||||
13.5,
|
|
||||||
14.5,
|
|
||||||
15.5);
|
|
||||||
let c3 = Matrix4x4::new_from_values(-0.75,
|
|
||||||
1.25,
|
|
||||||
2.75,
|
|
||||||
3.75,
|
|
||||||
4.75,
|
|
||||||
5.75,
|
|
||||||
6.75,
|
|
||||||
7.75,
|
|
||||||
8.75,
|
|
||||||
9.75,
|
|
||||||
10.75,
|
|
||||||
11.75,
|
|
||||||
12.75,
|
|
||||||
13.75,
|
|
||||||
14.75,
|
|
||||||
15.75);
|
|
||||||
|
|
||||||
assert_eq!(a.lerp(b, 0.0), a);
|
|
||||||
assert_eq!(a.lerp(b, 0.25), c1);
|
|
||||||
assert_eq!(a.lerp(b, 0.5), c2);
|
|
||||||
assert_eq!(a.lerp(b, 0.75), c3);
|
|
||||||
assert_eq!(a.lerp(b, 1.0), b);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -4,7 +4,6 @@ use std::cmp::PartialEq;
|
||||||
use std::ops::{Add, Sub, Mul, Div, Neg};
|
use std::ops::{Add, Sub, Mul, Div, Neg};
|
||||||
|
|
||||||
use float4::Float4;
|
use float4::Float4;
|
||||||
use lerp::Lerp;
|
|
||||||
|
|
||||||
use super::{DotProduct, CrossProduct};
|
use super::{DotProduct, CrossProduct};
|
||||||
use super::{Matrix4x4, Vector};
|
use super::{Matrix4x4, Vector};
|
||||||
|
@ -17,26 +16,32 @@ pub struct Normal {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Normal {
|
impl Normal {
|
||||||
|
#[inline(always)]
|
||||||
pub fn new(x: f32, y: f32, z: f32) -> Normal {
|
pub fn new(x: f32, y: f32, z: f32) -> Normal {
|
||||||
Normal { co: Float4::new(x, y, z, 0.0) }
|
Normal { co: Float4::new(x, y, z, 0.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn length(&self) -> f32 {
|
pub fn length(&self) -> f32 {
|
||||||
(self.co * self.co).h_sum().sqrt()
|
(self.co * self.co).h_sum().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn length2(&self) -> f32 {
|
pub fn length2(&self) -> f32 {
|
||||||
(self.co * self.co).h_sum()
|
(self.co * self.co).h_sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn normalized(&self) -> Normal {
|
pub fn normalized(&self) -> Normal {
|
||||||
*self / self.length()
|
*self / self.length()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn into_vector(self) -> Vector {
|
pub fn into_vector(self) -> Vector {
|
||||||
Vector::new(self.co.get_0(), self.co.get_1(), self.co.get_2())
|
Vector::new(self.co.get_0(), self.co.get_1(), self.co.get_2())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_n(&self, n: usize) -> f32 {
|
pub fn get_n(&self, n: usize) -> f32 {
|
||||||
match n {
|
match n {
|
||||||
0 => self.x(),
|
0 => self.x(),
|
||||||
|
@ -46,26 +51,32 @@ impl Normal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn x(&self) -> f32 {
|
pub fn x(&self) -> f32 {
|
||||||
self.co.get_0()
|
self.co.get_0()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn y(&self) -> f32 {
|
pub fn y(&self) -> f32 {
|
||||||
self.co.get_1()
|
self.co.get_1()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn z(&self) -> f32 {
|
pub fn z(&self) -> f32 {
|
||||||
self.co.get_2()
|
self.co.get_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_x(&mut self, x: f32) {
|
pub fn set_x(&mut self, x: f32) {
|
||||||
self.co.set_0(x);
|
self.co.set_0(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_y(&mut self, y: f32) {
|
pub fn set_y(&mut self, y: f32) {
|
||||||
self.co.set_1(y);
|
self.co.set_1(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_z(&mut self, z: f32) {
|
pub fn set_z(&mut self, z: f32) {
|
||||||
self.co.set_2(z);
|
self.co.set_2(z);
|
||||||
}
|
}
|
||||||
|
@ -73,6 +84,7 @@ impl Normal {
|
||||||
|
|
||||||
|
|
||||||
impl PartialEq for Normal {
|
impl PartialEq for Normal {
|
||||||
|
#[inline(always)]
|
||||||
fn eq(&self, other: &Normal) -> bool {
|
fn eq(&self, other: &Normal) -> bool {
|
||||||
self.co == other.co
|
self.co == other.co
|
||||||
}
|
}
|
||||||
|
@ -82,6 +94,7 @@ impl PartialEq for Normal {
|
||||||
impl Add for Normal {
|
impl Add for Normal {
|
||||||
type Output = Normal;
|
type Output = Normal;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn add(self, other: Normal) -> Normal {
|
fn add(self, other: Normal) -> Normal {
|
||||||
Normal { co: self.co + other.co }
|
Normal { co: self.co + other.co }
|
||||||
}
|
}
|
||||||
|
@ -91,6 +104,7 @@ impl Add for Normal {
|
||||||
impl Sub for Normal {
|
impl Sub for Normal {
|
||||||
type Output = Normal;
|
type Output = Normal;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn sub(self, other: Normal) -> Normal {
|
fn sub(self, other: Normal) -> Normal {
|
||||||
Normal { co: self.co - other.co }
|
Normal { co: self.co - other.co }
|
||||||
}
|
}
|
||||||
|
@ -100,6 +114,7 @@ impl Sub for Normal {
|
||||||
impl Mul<f32> for Normal {
|
impl Mul<f32> for Normal {
|
||||||
type Output = Normal;
|
type Output = Normal;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn mul(self, other: f32) -> Normal {
|
fn mul(self, other: f32) -> Normal {
|
||||||
Normal { co: self.co * other }
|
Normal { co: self.co * other }
|
||||||
}
|
}
|
||||||
|
@ -108,12 +123,13 @@ impl Mul<f32> for Normal {
|
||||||
impl Mul<Matrix4x4> for Normal {
|
impl Mul<Matrix4x4> for Normal {
|
||||||
type Output = Normal;
|
type Output = Normal;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn mul(self, other: Matrix4x4) -> Normal {
|
fn mul(self, other: Matrix4x4) -> Normal {
|
||||||
let mat = other.inverse().transposed();
|
let mat = other.inverse().transposed();
|
||||||
Normal {
|
Normal {
|
||||||
co: Float4::new((self.co * mat[0]).h_sum(),
|
co: Float4::new((self.co * mat.values[0]).h_sum(),
|
||||||
(self.co * mat[1]).h_sum(),
|
(self.co * mat.values[1]).h_sum(),
|
||||||
(self.co * mat[2]).h_sum(),
|
(self.co * mat.values[2]).h_sum(),
|
||||||
0.0),
|
0.0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,6 +139,7 @@ impl Mul<Matrix4x4> for Normal {
|
||||||
impl Div<f32> for Normal {
|
impl Div<f32> for Normal {
|
||||||
type Output = Normal;
|
type Output = Normal;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn div(self, other: f32) -> Normal {
|
fn div(self, other: f32) -> Normal {
|
||||||
Normal { co: self.co / other }
|
Normal { co: self.co / other }
|
||||||
}
|
}
|
||||||
|
@ -132,20 +149,15 @@ impl Div<f32> for Normal {
|
||||||
impl Neg for Normal {
|
impl Neg for Normal {
|
||||||
type Output = Normal;
|
type Output = Normal;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn neg(self) -> Normal {
|
fn neg(self) -> Normal {
|
||||||
Normal { co: self.co * -1.0 }
|
Normal { co: self.co * -1.0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Lerp for Normal {
|
|
||||||
fn lerp(self, other: Normal, alpha: f32) -> Normal {
|
|
||||||
(self * (1.0 - alpha)) + (other * alpha)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl DotProduct for Normal {
|
impl DotProduct for Normal {
|
||||||
|
#[inline(always)]
|
||||||
fn dot(self, other: Normal) -> f32 {
|
fn dot(self, other: Normal) -> f32 {
|
||||||
(self.co * other.co).h_sum()
|
(self.co * other.co).h_sum()
|
||||||
}
|
}
|
||||||
|
@ -153,6 +165,7 @@ impl DotProduct for Normal {
|
||||||
|
|
||||||
|
|
||||||
impl CrossProduct for Normal {
|
impl CrossProduct for Normal {
|
||||||
|
#[inline]
|
||||||
fn cross(self, other: Normal) -> Normal {
|
fn cross(self, other: Normal) -> Normal {
|
||||||
Normal {
|
Normal {
|
||||||
co: Float4::new((self.co.get_1() * other.co.get_2()) -
|
co: Float4::new((self.co.get_1() * other.co.get_2()) -
|
||||||
|
@ -171,7 +184,6 @@ impl CrossProduct for Normal {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::super::{Matrix4x4, CrossProduct, DotProduct};
|
use super::super::{Matrix4x4, CrossProduct, DotProduct};
|
||||||
use lerp::Lerp;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add() {
|
fn add() {
|
||||||
|
@ -271,31 +283,4 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(v3, v1.cross(v2));
|
assert_eq!(v3, v1.cross(v2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lerp1() {
|
|
||||||
let n1 = Normal::new(1.0, 2.0, 1.0);
|
|
||||||
let n2 = Normal::new(-2.0, 1.0, -1.0);
|
|
||||||
let n3 = Normal::new(1.0, 2.0, 1.0);
|
|
||||||
|
|
||||||
assert_eq!(n3, n1.lerp(n2, 0.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lerp2() {
|
|
||||||
let n1 = Normal::new(1.0, 2.0, 1.0);
|
|
||||||
let n2 = Normal::new(-2.0, 1.0, -1.0);
|
|
||||||
let n3 = Normal::new(-2.0, 1.0, -1.0);
|
|
||||||
|
|
||||||
assert_eq!(n3, n1.lerp(n2, 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lerp3() {
|
|
||||||
let n1 = Normal::new(1.0, 2.0, 1.0);
|
|
||||||
let n2 = Normal::new(-2.0, 1.0, -1.0);
|
|
||||||
let n3 = Normal::new(-0.5, 1.5, 0.0);
|
|
||||||
|
|
||||||
assert_eq!(n3, n1.lerp(n2, 0.5));
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -4,7 +4,6 @@ use std::cmp::PartialEq;
|
||||||
use std::ops::{Add, Sub, Mul};
|
use std::ops::{Add, Sub, Mul};
|
||||||
|
|
||||||
use float4::Float4;
|
use float4::Float4;
|
||||||
use lerp::Lerp;
|
|
||||||
|
|
||||||
use super::Matrix4x4;
|
use super::Matrix4x4;
|
||||||
use super::Vector;
|
use super::Vector;
|
||||||
|
@ -17,16 +16,19 @@ pub struct Point {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Point {
|
impl Point {
|
||||||
|
#[inline(always)]
|
||||||
pub fn new(x: f32, y: f32, z: f32) -> Point {
|
pub fn new(x: f32, y: f32, z: f32) -> Point {
|
||||||
Point { co: Float4::new(x, y, z, 1.0) }
|
Point { co: Float4::new(x, y, z, 1.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the point in standardized coordinates, where the
|
/// Returns the point in standardized coordinates, where the
|
||||||
/// fourth homogeneous component has been normalized to 1.0.
|
/// fourth homogeneous component has been normalized to 1.0.
|
||||||
|
#[inline(always)]
|
||||||
pub fn norm(&self) -> Point {
|
pub fn norm(&self) -> Point {
|
||||||
Point { co: self.co / self.co.get_3() }
|
Point { co: self.co / self.co.get_3() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn min(&self, other: Point) -> Point {
|
pub fn min(&self, other: Point) -> Point {
|
||||||
let n1 = self.norm();
|
let n1 = self.norm();
|
||||||
let n2 = other.norm();
|
let n2 = other.norm();
|
||||||
|
@ -34,6 +36,7 @@ impl Point {
|
||||||
Point { co: n1.co.v_min(n2.co) }
|
Point { co: n1.co.v_min(n2.co) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn max(&self, other: Point) -> Point {
|
pub fn max(&self, other: Point) -> Point {
|
||||||
let n1 = self.norm();
|
let n1 = self.norm();
|
||||||
let n2 = other.norm();
|
let n2 = other.norm();
|
||||||
|
@ -41,10 +44,12 @@ impl Point {
|
||||||
Point { co: n1.co.v_max(n2.co) }
|
Point { co: n1.co.v_max(n2.co) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn into_vector(self) -> Vector {
|
pub fn into_vector(self) -> Vector {
|
||||||
Vector::new(self.co.get_0(), self.co.get_1(), self.co.get_2())
|
Vector::new(self.co.get_0(), self.co.get_1(), self.co.get_2())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_n(&self, n: usize) -> f32 {
|
pub fn get_n(&self, n: usize) -> f32 {
|
||||||
match n {
|
match n {
|
||||||
0 => self.x(),
|
0 => self.x(),
|
||||||
|
@ -54,26 +59,32 @@ impl Point {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn x(&self) -> f32 {
|
pub fn x(&self) -> f32 {
|
||||||
self.co.get_0()
|
self.co.get_0()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn y(&self) -> f32 {
|
pub fn y(&self) -> f32 {
|
||||||
self.co.get_1()
|
self.co.get_1()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn z(&self) -> f32 {
|
pub fn z(&self) -> f32 {
|
||||||
self.co.get_2()
|
self.co.get_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_x(&mut self, x: f32) {
|
pub fn set_x(&mut self, x: f32) {
|
||||||
self.co.set_0(x);
|
self.co.set_0(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_y(&mut self, y: f32) {
|
pub fn set_y(&mut self, y: f32) {
|
||||||
self.co.set_1(y);
|
self.co.set_1(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_z(&mut self, z: f32) {
|
pub fn set_z(&mut self, z: f32) {
|
||||||
self.co.set_2(z);
|
self.co.set_2(z);
|
||||||
}
|
}
|
||||||
|
@ -81,6 +92,7 @@ impl Point {
|
||||||
|
|
||||||
|
|
||||||
impl PartialEq for Point {
|
impl PartialEq for Point {
|
||||||
|
#[inline(always)]
|
||||||
fn eq(&self, other: &Point) -> bool {
|
fn eq(&self, other: &Point) -> bool {
|
||||||
self.co == other.co
|
self.co == other.co
|
||||||
}
|
}
|
||||||
|
@ -90,6 +102,7 @@ impl PartialEq for Point {
|
||||||
impl Add<Vector> for Point {
|
impl Add<Vector> for Point {
|
||||||
type Output = Point;
|
type Output = Point;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn add(self, other: Vector) -> Point {
|
fn add(self, other: Vector) -> Point {
|
||||||
Point { co: self.co + other.co }
|
Point { co: self.co + other.co }
|
||||||
}
|
}
|
||||||
|
@ -99,6 +112,7 @@ impl Add<Vector> for Point {
|
||||||
impl Sub for Point {
|
impl Sub for Point {
|
||||||
type Output = Vector;
|
type Output = Vector;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn sub(self, other: Point) -> Vector {
|
fn sub(self, other: Point) -> Vector {
|
||||||
Vector { co: self.norm().co - other.norm().co }
|
Vector { co: self.norm().co - other.norm().co }
|
||||||
}
|
}
|
||||||
|
@ -107,6 +121,7 @@ impl Sub for Point {
|
||||||
impl Sub<Vector> for Point {
|
impl Sub<Vector> for Point {
|
||||||
type Output = Point;
|
type Output = Point;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn sub(self, other: Vector) -> Point {
|
fn sub(self, other: Vector) -> Point {
|
||||||
Point { co: self.co - other.co }
|
Point { co: self.co - other.co }
|
||||||
}
|
}
|
||||||
|
@ -115,31 +130,22 @@ impl Sub<Vector> for Point {
|
||||||
impl Mul<Matrix4x4> for Point {
|
impl Mul<Matrix4x4> for Point {
|
||||||
type Output = Point;
|
type Output = Point;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn mul(self, other: Matrix4x4) -> Point {
|
fn mul(self, other: Matrix4x4) -> Point {
|
||||||
Point {
|
Point {
|
||||||
co: Float4::new((self.co * other[0]).h_sum(),
|
co: Float4::new((self.co * other.values[0]).h_sum(),
|
||||||
(self.co * other[1]).h_sum(),
|
(self.co * other.values[1]).h_sum(),
|
||||||
(self.co * other[2]).h_sum(),
|
(self.co * other.values[2]).h_sum(),
|
||||||
(self.co * other[3]).h_sum()),
|
(self.co * other.values[3]).h_sum()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Lerp for Point {
|
|
||||||
fn lerp(self, other: Point, alpha: f32) -> Point {
|
|
||||||
let s = self.norm();
|
|
||||||
let o = other.norm();
|
|
||||||
Point { co: (s.co * (1.0 - alpha)) + (o.co * alpha) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::super::{Vector, Matrix4x4};
|
use super::super::{Vector, Matrix4x4};
|
||||||
use lerp::Lerp;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn norm() {
|
fn norm() {
|
||||||
|
@ -258,31 +264,4 @@ mod tests {
|
||||||
|
|
||||||
assert!((pmm1 - pmm2).length2() <= 0.00001); // Assert pmm1 and pmm2 are roughly equal
|
assert!((pmm1 - pmm2).length2() <= 0.00001); // Assert pmm1 and pmm2 are roughly equal
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lerp1() {
|
|
||||||
let p1 = Point::new(1.0, 2.0, 1.0);
|
|
||||||
let p2 = Point::new(-2.0, 1.0, -1.0);
|
|
||||||
let p3 = Point::new(1.0, 2.0, 1.0);
|
|
||||||
|
|
||||||
assert_eq!(p3, p1.lerp(p2, 0.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lerp2() {
|
|
||||||
let p1 = Point::new(1.0, 2.0, 1.0);
|
|
||||||
let p2 = Point::new(-2.0, 1.0, -1.0);
|
|
||||||
let p3 = Point::new(-2.0, 1.0, -1.0);
|
|
||||||
|
|
||||||
assert_eq!(p3, p1.lerp(p2, 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lerp3() {
|
|
||||||
let p1 = Point::new(1.0, 2.0, 1.0);
|
|
||||||
let p2 = Point::new(-2.0, 1.0, -1.0);
|
|
||||||
let p3 = Point::new(-0.5, 1.5, 0.0);
|
|
||||||
|
|
||||||
assert_eq!(p3, p1.lerp(p2, 0.5));
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -4,7 +4,6 @@ use std::cmp::PartialEq;
|
||||||
use std::ops::{Add, Sub, Mul, Div, Neg};
|
use std::ops::{Add, Sub, Mul, Div, Neg};
|
||||||
|
|
||||||
use float4::Float4;
|
use float4::Float4;
|
||||||
use lerp::Lerp;
|
|
||||||
|
|
||||||
use super::{DotProduct, CrossProduct};
|
use super::{DotProduct, CrossProduct};
|
||||||
use super::{Matrix4x4, Normal};
|
use super::{Matrix4x4, Normal};
|
||||||
|
@ -17,26 +16,32 @@ pub struct Vector {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vector {
|
impl Vector {
|
||||||
|
#[inline(always)]
|
||||||
pub fn new(x: f32, y: f32, z: f32) -> Vector {
|
pub fn new(x: f32, y: f32, z: f32) -> Vector {
|
||||||
Vector { co: Float4::new(x, y, z, 0.0) }
|
Vector { co: Float4::new(x, y, z, 0.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn length(&self) -> f32 {
|
pub fn length(&self) -> f32 {
|
||||||
(self.co * self.co).h_sum().sqrt()
|
(self.co * self.co).h_sum().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn length2(&self) -> f32 {
|
pub fn length2(&self) -> f32 {
|
||||||
(self.co * self.co).h_sum()
|
(self.co * self.co).h_sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn normalized(&self) -> Vector {
|
pub fn normalized(&self) -> Vector {
|
||||||
*self / self.length()
|
*self / self.length()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn into_normal(self) -> Normal {
|
pub fn into_normal(self) -> Normal {
|
||||||
Normal::new(self.x(), self.y(), self.z())
|
Normal::new(self.x(), self.y(), self.z())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_n(&self, n: usize) -> f32 {
|
pub fn get_n(&self, n: usize) -> f32 {
|
||||||
match n {
|
match n {
|
||||||
0 => self.x(),
|
0 => self.x(),
|
||||||
|
@ -46,26 +51,32 @@ impl Vector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn x(&self) -> f32 {
|
pub fn x(&self) -> f32 {
|
||||||
self.co.get_0()
|
self.co.get_0()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn y(&self) -> f32 {
|
pub fn y(&self) -> f32 {
|
||||||
self.co.get_1()
|
self.co.get_1()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn z(&self) -> f32 {
|
pub fn z(&self) -> f32 {
|
||||||
self.co.get_2()
|
self.co.get_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_x(&mut self, x: f32) {
|
pub fn set_x(&mut self, x: f32) {
|
||||||
self.co.set_0(x);
|
self.co.set_0(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_y(&mut self, y: f32) {
|
pub fn set_y(&mut self, y: f32) {
|
||||||
self.co.set_1(y);
|
self.co.set_1(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_z(&mut self, z: f32) {
|
pub fn set_z(&mut self, z: f32) {
|
||||||
self.co.set_2(z);
|
self.co.set_2(z);
|
||||||
}
|
}
|
||||||
|
@ -73,6 +84,7 @@ impl Vector {
|
||||||
|
|
||||||
|
|
||||||
impl PartialEq for Vector {
|
impl PartialEq for Vector {
|
||||||
|
#[inline(always)]
|
||||||
fn eq(&self, other: &Vector) -> bool {
|
fn eq(&self, other: &Vector) -> bool {
|
||||||
self.co == other.co
|
self.co == other.co
|
||||||
}
|
}
|
||||||
|
@ -82,6 +94,7 @@ impl PartialEq for Vector {
|
||||||
impl Add for Vector {
|
impl Add for Vector {
|
||||||
type Output = Vector;
|
type Output = Vector;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn add(self, other: Vector) -> Vector {
|
fn add(self, other: Vector) -> Vector {
|
||||||
Vector { co: self.co + other.co }
|
Vector { co: self.co + other.co }
|
||||||
}
|
}
|
||||||
|
@ -91,6 +104,7 @@ impl Add for Vector {
|
||||||
impl Sub for Vector {
|
impl Sub for Vector {
|
||||||
type Output = Vector;
|
type Output = Vector;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn sub(self, other: Vector) -> Vector {
|
fn sub(self, other: Vector) -> Vector {
|
||||||
Vector { co: self.co - other.co }
|
Vector { co: self.co - other.co }
|
||||||
}
|
}
|
||||||
|
@ -100,6 +114,7 @@ impl Sub for Vector {
|
||||||
impl Mul<f32> for Vector {
|
impl Mul<f32> for Vector {
|
||||||
type Output = Vector;
|
type Output = Vector;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn mul(self, other: f32) -> Vector {
|
fn mul(self, other: f32) -> Vector {
|
||||||
Vector { co: self.co * other }
|
Vector { co: self.co * other }
|
||||||
}
|
}
|
||||||
|
@ -109,12 +124,13 @@ impl Mul<f32> for Vector {
|
||||||
impl Mul<Matrix4x4> for Vector {
|
impl Mul<Matrix4x4> for Vector {
|
||||||
type Output = Vector;
|
type Output = Vector;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn mul(self, other: Matrix4x4) -> Vector {
|
fn mul(self, other: Matrix4x4) -> Vector {
|
||||||
Vector {
|
Vector {
|
||||||
co: Float4::new((self.co * other[0]).h_sum(),
|
co: Float4::new((self.co * other.values[0]).h_sum(),
|
||||||
(self.co * other[1]).h_sum(),
|
(self.co * other.values[1]).h_sum(),
|
||||||
(self.co * other[2]).h_sum(),
|
(self.co * other.values[2]).h_sum(),
|
||||||
(self.co * other[3]).h_sum()),
|
(self.co * other.values[3]).h_sum()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,6 +139,7 @@ impl Mul<Matrix4x4> for Vector {
|
||||||
impl Div<f32> for Vector {
|
impl Div<f32> for Vector {
|
||||||
type Output = Vector;
|
type Output = Vector;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn div(self, other: f32) -> Vector {
|
fn div(self, other: f32) -> Vector {
|
||||||
Vector { co: self.co / other }
|
Vector { co: self.co / other }
|
||||||
}
|
}
|
||||||
|
@ -132,20 +149,15 @@ impl Div<f32> for Vector {
|
||||||
impl Neg for Vector {
|
impl Neg for Vector {
|
||||||
type Output = Vector;
|
type Output = Vector;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn neg(self) -> Vector {
|
fn neg(self) -> Vector {
|
||||||
Vector { co: self.co * -1.0 }
|
Vector { co: self.co * -1.0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Lerp for Vector {
|
|
||||||
fn lerp(self, other: Vector, alpha: f32) -> Vector {
|
|
||||||
(self * (1.0 - alpha)) + (other * alpha)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl DotProduct for Vector {
|
impl DotProduct for Vector {
|
||||||
|
#[inline(always)]
|
||||||
fn dot(self, other: Vector) -> f32 {
|
fn dot(self, other: Vector) -> f32 {
|
||||||
(self.co * other.co).h_sum()
|
(self.co * other.co).h_sum()
|
||||||
}
|
}
|
||||||
|
@ -153,6 +165,7 @@ impl DotProduct for Vector {
|
||||||
|
|
||||||
|
|
||||||
impl CrossProduct for Vector {
|
impl CrossProduct for Vector {
|
||||||
|
#[inline]
|
||||||
fn cross(self, other: Vector) -> Vector {
|
fn cross(self, other: Vector) -> Vector {
|
||||||
Vector {
|
Vector {
|
||||||
co: Float4::new((self.co.get_1() * other.co.get_2()) -
|
co: Float4::new((self.co.get_1() * other.co.get_2()) -
|
||||||
|
@ -171,7 +184,6 @@ impl CrossProduct for Vector {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::super::{Matrix4x4, CrossProduct, DotProduct};
|
use super::super::{Matrix4x4, CrossProduct, DotProduct};
|
||||||
use lerp::Lerp;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add() {
|
fn add() {
|
||||||
|
@ -295,31 +307,4 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(v3, v1.cross(v2));
|
assert_eq!(v3, v1.cross(v2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lerp1() {
|
|
||||||
let v1 = Vector::new(1.0, 2.0, 1.0);
|
|
||||||
let v2 = Vector::new(-2.0, 1.0, -1.0);
|
|
||||||
let v3 = Vector::new(1.0, 2.0, 1.0);
|
|
||||||
|
|
||||||
assert_eq!(v3, v1.lerp(v2, 0.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lerp2() {
|
|
||||||
let v1 = Vector::new(1.0, 2.0, 1.0);
|
|
||||||
let v2 = Vector::new(-2.0, 1.0, -1.0);
|
|
||||||
let v3 = Vector::new(-2.0, 1.0, -1.0);
|
|
||||||
|
|
||||||
assert_eq!(v3, v1.lerp(v2, 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lerp3() {
|
|
||||||
let v1 = Vector::new(1.0, 2.0, 1.0);
|
|
||||||
let v2 = Vector::new(-2.0, 1.0, -1.0);
|
|
||||||
let v3 = Vector::new(-0.5, 1.5, 0.0);
|
|
||||||
|
|
||||||
assert_eq!(v3, v1.lerp(v2, 0.5));
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user