initial commit
This commit is contained in:
commit
aed74ae3c9
12 changed files with 1579 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
.DS_Store
|
||||
build
|
||||
lib
|
||||
*.sublime-workspace
|
10
Makefile
Normal file
10
Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
# adapted from https://github.com/z0w0/rusty-math/blob/master/Makefile
|
||||
|
||||
all:
|
||||
rustc src/om3d.rc --lib --out-dir=lib
|
||||
test: all
|
||||
rustc --test -L lib test/*-test.rs -o test/build/test.elf
|
||||
./test/build/test.elf
|
||||
clean:
|
||||
rm -R -f ./lib/*
|
||||
rm -R -f ./test/*.elf
|
27
README.md
Normal file
27
README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# om3D: A Linear Algebra Library for Rust
|
||||
|
||||
Here's some linear algebra I've been working on. I've translated it over from my unpublished D library that I was using to teach myself 3D mathematics.
|
||||
|
||||
For some reason my makefile isn't working - it give me the following error:
|
||||
|
||||
rustc src/om3d.rc --lib --out-dir=lib
|
||||
error: failed to resolve imports
|
||||
src/quat.rs:5:7: 5:14 error: unresolved import
|
||||
src/quat.rs:5 import mat::*;
|
||||
^~~~~~~
|
||||
src/mat.rs:5:7: 5:15 error: unresolved import
|
||||
src/mat.rs:5 import quat::*;
|
||||
^~~~~~~~
|
||||
src/projection.rs:2:7: 2:14 error: unresolved import
|
||||
src/projection.rs:2 import mat::*;
|
||||
^~~~~~~
|
||||
error: aborting due to 4 previous errors
|
||||
make: *** [all] Error 101
|
||||
|
||||
Any assistance would be most appreciated!
|
||||
|
||||
## Disclaimer:
|
||||
|
||||
I'm new to Rust and a novice at linear algebra. I also haven't written any unittests yet (although I plan to soon). I've almost certainly made mistakes, so use this at your own risk!
|
||||
|
||||
At the time of writing (September 2012) the Rust language is still in a state of flux. There is a good chance that the code will be soon out of date.
|
700
src/mat.rs
Normal file
700
src/mat.rs
Normal file
|
@ -0,0 +1,700 @@
|
|||
import std::cmp::FuzzyEq;
|
||||
import cmp::Ord;
|
||||
import num::Num;
|
||||
// import to_str::ToStr;
|
||||
import quat::*;
|
||||
import vec::*;
|
||||
|
||||
// TODO: Unittests! I've probably made lots of mistakes...
|
||||
|
||||
//
|
||||
// NxN Matrix
|
||||
//
|
||||
trait Matrix<T:Num Ord FuzzyEq, V:Vector<T>> {
|
||||
pure fn rows() -> uint;
|
||||
pure fn cols() -> uint;
|
||||
pure fn is_col_major() -> bool;
|
||||
|
||||
pure fn index(&&index:uint) -> V;
|
||||
pure fn row(&&i:uint) -> V;
|
||||
pure fn col(&&i:uint) -> V;
|
||||
|
||||
pure fn neg() -> self;
|
||||
|
||||
pure fn add_m(&&other:self) -> self;
|
||||
pure fn sub_m(&&other:self) -> self;
|
||||
pure fn mul_f(&&value:T) -> self;
|
||||
pure fn mul_v(&&other:V) -> V;
|
||||
pure fn mul_m(&&other:self) -> self;
|
||||
|
||||
// pure fn invert(&&other:self) -> self;
|
||||
pure fn transpose() -> self;
|
||||
|
||||
pure fn exact_eq(&&other:self) -> bool;
|
||||
pure fn fuzzy_eq(&&other:self) -> bool;
|
||||
pure fn eq(&&other:self) -> bool;
|
||||
|
||||
pure fn is_identity() -> bool;
|
||||
pure fn is_symmetric() -> bool;
|
||||
pure fn is_diagonal() -> bool;
|
||||
pure fn is_rotated() -> bool;
|
||||
}
|
||||
|
||||
//
|
||||
// 3x3 Matrix
|
||||
//
|
||||
trait Matrix3<T:Num Ord FuzzyEq, V:Vector<T>> {
|
||||
pure fn scale(&&vec:V) -> self;
|
||||
pure fn to_mat4() -> mat4;
|
||||
pure fn to_quat() -> quat;
|
||||
}
|
||||
|
||||
//
|
||||
// 4x4 Matrix
|
||||
//
|
||||
trait Matrix4<T:Num Ord FuzzyEq, V:Vector<T>> {
|
||||
pure fn scale(&&vec:vec3) -> self; // I don't like the use of `vec3` here
|
||||
pure fn translate(&&vec:vec3) -> self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Mat2: A 2x2, column major matrix
|
||||
//
|
||||
struct mat2 { data:[vec2 * 2] }
|
||||
|
||||
//
|
||||
// Mat2 Constructor
|
||||
//
|
||||
#[inline(always)]
|
||||
pure fn mat2(m00:float, m01:float,
|
||||
m10:float, m11:float) -> mat2 {
|
||||
mat2 { data: [ vec2(m00, m01),
|
||||
vec2(m10, m11) ] }
|
||||
}
|
||||
|
||||
//
|
||||
// Construct Mat2 from column vectors
|
||||
//
|
||||
#[inline(always)]
|
||||
pure fn mat2_v(col0:vec2, col1:vec2) -> mat2 {
|
||||
mat2 { data: [ col0, col1 ] }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mat2_zero() -> mat2 {
|
||||
mat2 (0.0, 0.0,
|
||||
0.0, 0.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mat2_identity() -> mat2 {
|
||||
mat2 (1.0, 0.0,
|
||||
0.0, 1.0)
|
||||
}
|
||||
|
||||
//
|
||||
// Matrix2x2 Implementation
|
||||
//
|
||||
impl mat2: Matrix<float, vec2> {
|
||||
#[inline(always)]
|
||||
pure fn rows() -> uint { 2 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn cols() -> uint { 2 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_col_major() -> bool { true }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn index(&&i: uint) -> vec2 {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn row(&&i:uint) -> vec2 {
|
||||
vec2(self[0][i],
|
||||
self[1][i])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn col(&&i:uint) -> vec2 {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn neg() -> mat2 {
|
||||
mat2_v(-self[0], -self[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn add_m(&&other:mat2) -> mat2 {
|
||||
mat2_v(self[0].add_v(other[0]),
|
||||
self[1].add_v(other[1]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sub_m(&&other:mat2) -> mat2 {
|
||||
mat2_v(self[0].add_v(other[0]),
|
||||
self[1].add_v(other[1]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_f(&&value:float) -> mat2 {
|
||||
mat2_v(self[0].mul_f(value),
|
||||
self[1].mul_f(value))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_v(&&other:vec2) -> vec2 {
|
||||
vec2(self[0][0]*other[0] + self[1][0]*other[1],
|
||||
self[0][1]*other[0] + self[1][1]*other[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_m(&&other:mat2) -> mat2 {
|
||||
mat2(self[0][0]*other[0][0] + self[1][0]*other[0][1],
|
||||
self[0][1]*other[0][0] + self[1][1]*other[0][1],
|
||||
|
||||
self[0][0]*other[1][0] + self[1][0]*other[1][1],
|
||||
self[0][1]*other[1][0] + self[1][1]*other[1][1])
|
||||
}
|
||||
|
||||
// TODO - inversion is harrrd D:
|
||||
// #[inline(always)]
|
||||
// pure fn invert(&&other:mat2) -> mat2 {}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn transpose() -> mat2 {
|
||||
mat2(self[0][0], self[1][0],
|
||||
self[0][1], self[1][1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn exact_eq(&&other:mat2) -> bool {
|
||||
self[0].exact_eq(other[0]) &&
|
||||
self[1].exact_eq(other[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn fuzzy_eq(&&other:mat2) -> bool {
|
||||
self[0].fuzzy_eq(other[0]) &&
|
||||
self[1].fuzzy_eq(other[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn eq(&&other:mat2) -> bool {
|
||||
self.fuzzy_eq(other)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_identity() -> bool {
|
||||
self.fuzzy_eq(mat2_identity())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_symmetric() -> bool {
|
||||
self[0][1].fuzzy_eq(&self[1][0]) &&
|
||||
self[1][0].fuzzy_eq(&self[0][1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_diagonal() -> bool {
|
||||
self[0][1].fuzzy_eq(&0.0) &&
|
||||
self[1][0].fuzzy_eq(&0.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_rotated() -> bool {
|
||||
!self.fuzzy_eq(mat2_identity())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Mat3: A 3x3, column major matrix
|
||||
//
|
||||
struct mat3 { data:[vec3 * 3] }
|
||||
|
||||
//
|
||||
// Mat3 Constructor
|
||||
//
|
||||
#[inline(always)]
|
||||
pure fn mat3(m00:float, m01:float, m02:float,
|
||||
m10:float, m11:float, m12:float,
|
||||
m20:float, m21:float, m22:float) -> mat3 {
|
||||
mat3 { data: [ vec3(m00, m01, m02),
|
||||
vec3(m10, m11, m12),
|
||||
vec3(m20, m21, m22) ] }
|
||||
}
|
||||
|
||||
//
|
||||
// Construct Mat3 from column vectors
|
||||
//
|
||||
#[inline(always)]
|
||||
pure fn mat3_v(col0:vec3, col1:vec3, col2:vec3) -> mat3 {
|
||||
mat3 { data: [ col0, col1, col2 ] }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mat3_zero() -> mat3 {
|
||||
mat3 (0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mat3_identity() -> mat3 {
|
||||
mat3 (1.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 1.0)
|
||||
}
|
||||
|
||||
//
|
||||
// Matrix3x3 Implementation
|
||||
//
|
||||
impl mat3: Matrix<float, vec3> {
|
||||
#[inline(always)]
|
||||
pure fn rows() -> uint { 3 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn cols() -> uint { 3 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_col_major() -> bool { true }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn index(&&i: uint) -> vec3 {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn row(&&i:uint) -> vec3 {
|
||||
vec3(self[0][i],
|
||||
self[1][i],
|
||||
self[2][i])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn col(&&i:uint) -> vec3 {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn neg() -> mat3 {
|
||||
mat3_v(-self[0], -self[1], -self[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn add_m(&&other:mat3) -> mat3 {
|
||||
mat3_v(self[0].add_v(other[0]),
|
||||
self[1].add_v(other[1]),
|
||||
self[2].add_v(other[2]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sub_m(&&other:mat3) -> mat3 {
|
||||
mat3_v(self[0].add_v(other[0]),
|
||||
self[1].add_v(other[1]),
|
||||
self[2].add_v(other[2]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_f(&&value:float) -> mat3 {
|
||||
mat3_v(self[0].mul_f(value),
|
||||
self[1].mul_f(value),
|
||||
self[2].mul_f(value))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_v(&&other:vec3) -> vec3 {
|
||||
vec3(self[0][0]*other[0] + self[1][0]*other[1] + self[2][0]*other[2],
|
||||
self[0][1]*other[0] + self[1][1]*other[1] + self[2][1]*other[2],
|
||||
self[0][2]*other[0] + self[1][2]*other[1] + self[2][2]*other[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_m(&&other:mat3) -> mat3 {
|
||||
mat3(self[0][0]*other[0][0] + self[1][0]*other[0][1] + self[2][0]*other[0][2],
|
||||
self[0][1]*other[0][0] + self[1][1]*other[0][1] + self[2][1]*other[0][2],
|
||||
self[0][2]*other[0][0] + self[1][2]*other[0][1] + self[2][2]*other[0][2],
|
||||
|
||||
self[0][0]*other[1][0] + self[1][0]*other[1][1] + self[2][0]*other[1][2],
|
||||
self[0][1]*other[1][0] + self[1][1]*other[1][1] + self[2][1]*other[1][2],
|
||||
self[0][2]*other[1][0] + self[1][2]*other[1][1] + self[2][2]*other[1][2],
|
||||
|
||||
self[0][0]*other[2][0] + self[1][0]*other[2][1] + self[2][0]*other[2][2],
|
||||
self[0][1]*other[2][0] + self[1][1]*other[2][1] + self[2][1]*other[2][2],
|
||||
self[0][2]*other[2][0] + self[1][2]*other[2][1] + self[2][2]*other[2][2])
|
||||
}
|
||||
|
||||
// TODO - inversion is harrrd D:
|
||||
// #[inline(always)]
|
||||
// pure fn invert(&&other:mat3) -> mat3 {}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn transpose() -> mat3 {
|
||||
mat3(self[0][0], self[1][0], self[2][0],
|
||||
self[0][1], self[1][1], self[2][1],
|
||||
self[0][2], self[1][2], self[2][2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn exact_eq(&&other:mat3) -> bool {
|
||||
self[0].exact_eq(other[0]) &&
|
||||
self[1].exact_eq(other[1]) &&
|
||||
self[2].exact_eq(other[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn fuzzy_eq(&&other:mat3) -> bool {
|
||||
self[0].fuzzy_eq(other[0]) &&
|
||||
self[1].fuzzy_eq(other[1]) &&
|
||||
self[2].fuzzy_eq(other[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn eq(&&other:mat3) -> bool {
|
||||
self.fuzzy_eq(other)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_identity() -> bool {
|
||||
self.fuzzy_eq(mat3_identity())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_symmetric() -> bool {
|
||||
self[0][1].fuzzy_eq(&self[1][0]) &&
|
||||
self[0][2].fuzzy_eq(&self[2][0]) &&
|
||||
|
||||
self[1][0].fuzzy_eq(&self[0][1]) &&
|
||||
self[1][2].fuzzy_eq(&self[2][1]) &&
|
||||
|
||||
self[2][0].fuzzy_eq(&self[0][2]) &&
|
||||
self[2][1].fuzzy_eq(&self[1][2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_diagonal() -> bool {
|
||||
self[0][1].fuzzy_eq(&0.0) &&
|
||||
self[0][2].fuzzy_eq(&0.0) &&
|
||||
|
||||
self[1][0].fuzzy_eq(&0.0) &&
|
||||
self[1][2].fuzzy_eq(&0.0) &&
|
||||
|
||||
self[2][0].fuzzy_eq(&0.0) &&
|
||||
self[2][1].fuzzy_eq(&0.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_rotated() -> bool {
|
||||
!self.fuzzy_eq(mat3_identity())
|
||||
}
|
||||
}
|
||||
|
||||
impl mat3: Matrix3<float, vec3> {
|
||||
#[inline(always)]
|
||||
pure fn scale(&&vec:V) -> mat3 {
|
||||
self.mul_m(mat3(vec.x(), 0, 0,
|
||||
0, vec.y(), 0,
|
||||
0, 0, vec.z()))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn to_mat4() -> mat4 {
|
||||
mat4(self[0][0], self[0][1], self[0][2], 0,
|
||||
self[1][0], self[1][1], self[1][2], 0,
|
||||
self[2][0], self[2][1], self[2][2], 0,
|
||||
0, 0, 0, 1)
|
||||
}
|
||||
|
||||
pure fn to_quat() -> quat {
|
||||
// Implemented using a mix of ideas from jMonkeyEngine and Ken Shoemake's
|
||||
// paper on Quaternions: http://www.cs.ucr.edu/~vbz/resources/quatut.pdf
|
||||
|
||||
let w:float, x:float, y:float, z:float, s:float;
|
||||
let trace:float = self[0][0] + self[1][1] + self[2][2];
|
||||
|
||||
if trace >= 0 {
|
||||
s = sqrt(trace + 1);
|
||||
w = 0.5 * s;
|
||||
s = 0.5 / s;
|
||||
x = self[1][2] - self[2][1] * s;
|
||||
y = self[2][0] - self[0][2] * s;
|
||||
z = self[0][1] - self[1][0] * s;
|
||||
} else if (self[0][0] > self[1][1]) && (self[0][0] > self[2][2]) {
|
||||
s = sqrt(1 + self[0][0] - self[1][1] - self[2][2]);
|
||||
w = 0.5 * s;
|
||||
s = 0.5 / s;
|
||||
x = self[0][1] - self[1][0] * s;
|
||||
y = self[2][0] - self[0][2] * s;
|
||||
z = self[1][2] - self[2][1] * s;
|
||||
} else if self[1][1] > self[2][2] {
|
||||
s = sqrt(1 + self[1][1] - self[0][0] - self[2][2]);
|
||||
w = 0.5 * s;
|
||||
s = 0.5 / s;
|
||||
x = self[0][1] - self[1][0] * s;
|
||||
y = self[1][2] - self[2][1] * s;
|
||||
z = self[2][0] - self[0][2] * s;
|
||||
} else {
|
||||
s = sqrt(1 + self[2][2] - self[0][0] - self[1][1]);
|
||||
w = 0.5 * s;
|
||||
s = 0.5 / s;
|
||||
x = self[2][0] - self[0][2] * s;
|
||||
y = self[1][2] - self[2][1] * s;
|
||||
z = self[0][1] - self[1][0] * s;
|
||||
}
|
||||
return quat(w, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Mat4: A 4x4, column major matrix
|
||||
//
|
||||
struct mat4 { data:[vec4 * 4] }
|
||||
|
||||
//
|
||||
// Mat4 Constructor
|
||||
//
|
||||
#[inline(always)]
|
||||
pure fn mat4(m00:float, m01:float, m02:float, m03:float,
|
||||
m10:float, m11:float, m12:float, m13:float,
|
||||
m20:float, m21:float, m22:float, m23:float,
|
||||
m30:float, m31:float, m32:float, m33:float) -> mat4 {
|
||||
mat4 { data: [ vec4(m00, m01, m02, m03),
|
||||
vec4(m10, m11, m12, m13),
|
||||
vec4(m20, m21, m22, m23),
|
||||
vec4(m30, m31, m32, m33) ] }
|
||||
}
|
||||
|
||||
//
|
||||
// Construct Mat4 from column vectors
|
||||
//
|
||||
#[inline(always)]
|
||||
pure fn mat4_v(col0:vec4, col1:vec4, col2:vec4, col3:vec4) -> mat4 {
|
||||
mat4 { data: [ col0, col1, col2, col3 ] }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mat4_zero() -> mat4 {
|
||||
mat4 (0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mat4_identity() -> mat4 {
|
||||
mat4 (1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0)
|
||||
}
|
||||
|
||||
//
|
||||
// Matrix4x4 Implementation
|
||||
//
|
||||
impl mat4: Matrix<float, vec4> {
|
||||
#[inline(always)]
|
||||
pure fn rows() -> uint { 4 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn cols() -> uint { 4 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_col_major() -> bool { true }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn index(&&i: uint) -> vec4 {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn row(&&i:uint) -> vec4 {
|
||||
vec4(self[0][i],
|
||||
self[1][i],
|
||||
self[2][i],
|
||||
self[3][i])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn col(&&i:uint) -> vec4 {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn neg() -> mat4 {
|
||||
mat4_v(-self[0], -self[1], -self[2], -self[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn add_m(&&other:mat4) -> mat4 {
|
||||
mat4_v(self[0].add_v(other[0]),
|
||||
self[1].add_v(other[1]),
|
||||
self[2].add_v(other[2]),
|
||||
self[3].add_v(other[3]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sub_m(&&other:mat4) -> mat4 {
|
||||
mat4_v(self[0].add_v(other[0]),
|
||||
self[1].add_v(other[1]),
|
||||
self[2].add_v(other[2]),
|
||||
self[3].add_v(other[3]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_f(&&value:float) -> mat4 {
|
||||
mat4_v(self[0].mul_f(value),
|
||||
self[1].mul_f(value),
|
||||
self[2].mul_f(value),
|
||||
self[3].mul_f(value))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_v(&&other:vec4) -> vec4 {
|
||||
vec4(self[0][0]*other[0] + self[1][0]*other[1] + self[2][0]*other[2] + self[3][0]*other[3],
|
||||
self[0][1]*other[0] + self[1][1]*other[1] + self[2][1]*other[2] + self[3][1]*other[3],
|
||||
self[0][2]*other[0] + self[1][2]*other[1] + self[2][2]*other[2] + self[3][2]*other[3],
|
||||
self[0][3]*other[0] + self[1][3]*other[1] + self[2][3]*other[2] + self[3][3]*other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_m(&&other:mat4) -> mat4 {
|
||||
mat4(self[0][0]*other[0][0] + self[1][0]*other[0][1] + self[2][0]*other[0][2] + self[3][0]*other[0][3],
|
||||
self[0][1]*other[0][0] + self[1][1]*other[0][1] + self[2][1]*other[0][2] + self[3][1]*other[0][3],
|
||||
self[0][2]*other[0][0] + self[1][2]*other[0][1] + self[2][2]*other[0][2] + self[3][2]*other[0][3],
|
||||
self[0][3]*other[0][0] + self[1][3]*other[0][1] + self[2][3]*other[0][2] + self[3][3]*other[0][3],
|
||||
|
||||
self[0][0]*other[1][0] + self[1][0]*other[1][1] + self[2][0]*other[1][2] + self[3][0]*other[1][3],
|
||||
self[0][1]*other[1][0] + self[1][1]*other[1][1] + self[2][1]*other[1][2] + self[3][1]*other[1][3],
|
||||
self[0][2]*other[1][0] + self[1][2]*other[1][1] + self[2][2]*other[1][2] + self[3][2]*other[1][3],
|
||||
self[0][3]*other[1][0] + self[1][3]*other[1][1] + self[2][3]*other[1][2] + self[3][3]*other[1][3],
|
||||
|
||||
self[0][0]*other[2][0] + self[1][0]*other[2][1] + self[2][0]*other[2][2] + self[3][0]*other[2][3],
|
||||
self[0][1]*other[2][0] + self[1][1]*other[2][1] + self[2][1]*other[2][2] + self[3][1]*other[2][3],
|
||||
self[0][2]*other[2][0] + self[1][2]*other[2][1] + self[2][2]*other[2][2] + self[3][2]*other[2][3],
|
||||
self[0][3]*other[2][0] + self[1][3]*other[2][1] + self[2][3]*other[2][2] + self[3][3]*other[2][3],
|
||||
|
||||
self[0][0]*other[3][0] + self[1][0]*other[3][1] + self[2][0]*other[3][2] + self[3][0]*other[3][3],
|
||||
self[0][1]*other[3][0] + self[1][1]*other[3][1] + self[2][1]*other[3][2] + self[3][1]*other[3][3],
|
||||
self[0][2]*other[3][0] + self[1][2]*other[3][1] + self[2][2]*other[3][2] + self[3][2]*other[3][3],
|
||||
self[0][3]*other[3][0] + self[1][3]*other[3][1] + self[2][3]*other[3][2] + self[3][3]*other[3][3])
|
||||
}
|
||||
|
||||
// TODO - inversion is harrrd D:
|
||||
// #[inline(always)]
|
||||
// pure fn invert(&&other:mat4) -> mat4 {}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn transpose() -> mat4 {
|
||||
mat4(self[0][0], self[1][0], self[2][0], self[3][0],
|
||||
self[0][1], self[1][1], self[2][1], self[3][1],
|
||||
self[0][2], self[1][2], self[2][2], self[3][2],
|
||||
self[0][3], self[1][3], self[2][3], self[3][3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn exact_eq(&&other:mat4) -> bool {
|
||||
self[0].exact_eq(other[0]) &&
|
||||
self[1].exact_eq(other[1]) &&
|
||||
self[2].exact_eq(other[2]) &&
|
||||
self[3].exact_eq(other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn fuzzy_eq(&&other:mat4) -> bool {
|
||||
self[0].fuzzy_eq(other[0]) &&
|
||||
self[1].fuzzy_eq(other[1]) &&
|
||||
self[2].fuzzy_eq(other[2]) &&
|
||||
self[3].fuzzy_eq(other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn eq(&&other:mat4) -> bool {
|
||||
self.fuzzy_eq(other)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_identity() -> bool {
|
||||
self.fuzzy_eq(mat4_identity())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_symmetric() -> bool {
|
||||
self[0][1].fuzzy_eq(&self[1][0]) &&
|
||||
self[0][2].fuzzy_eq(&self[2][0]) &&
|
||||
self[0][3].fuzzy_eq(&self[3][0]) &&
|
||||
|
||||
self[1][0].fuzzy_eq(&self[0][1]) &&
|
||||
self[1][2].fuzzy_eq(&self[2][1]) &&
|
||||
self[1][3].fuzzy_eq(&self[3][1]) &&
|
||||
|
||||
self[2][0].fuzzy_eq(&self[0][2]) &&
|
||||
self[2][1].fuzzy_eq(&self[1][2]) &&
|
||||
self[2][3].fuzzy_eq(&self[3][2]) &&
|
||||
|
||||
self[3][0].fuzzy_eq(&self[0][3]) &&
|
||||
self[3][1].fuzzy_eq(&self[1][3]) &&
|
||||
self[3][2].fuzzy_eq(&self[2][3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_diagonal() -> bool {
|
||||
self[0][1].fuzzy_eq(&0.0) &&
|
||||
self[0][2].fuzzy_eq(&0.0) &&
|
||||
self[0][3].fuzzy_eq(&0.0) &&
|
||||
|
||||
self[1][0].fuzzy_eq(&0.0) &&
|
||||
self[1][2].fuzzy_eq(&0.0) &&
|
||||
self[1][3].fuzzy_eq(&0.0) &&
|
||||
|
||||
self[2][0].fuzzy_eq(&0.0) &&
|
||||
self[2][1].fuzzy_eq(&0.0) &&
|
||||
self[2][3].fuzzy_eq(&0.0) &&
|
||||
|
||||
self[3][0].fuzzy_eq(&0.0) &&
|
||||
self[3][1].fuzzy_eq(&0.0) &&
|
||||
self[3][2].fuzzy_eq(&0.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn is_rotated() -> bool {
|
||||
!self.fuzzy_eq(mat4_identity())
|
||||
}
|
||||
}
|
||||
|
||||
impl mat4: Matrix4<float, vec4> {
|
||||
#[inline(always)]
|
||||
pure fn scale(&&vec:vec3) -> mat4 {
|
||||
self.mul_m(mat3(vec.x(), 0, 0, 0,
|
||||
0, vec.y(), 0, 0,
|
||||
0, 0, vec.z(), 0,
|
||||
0, 0, 0, 1))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn translate(&&vec:vec3) -> mat4 {
|
||||
mat4(self[0],
|
||||
self[1],
|
||||
self[2],
|
||||
vec4(self[3][0] + vec.x(),
|
||||
self[3][1] + vec.y(),
|
||||
self[3][2] + vec.z(),
|
||||
self[3][3]))
|
||||
}
|
||||
}
|
13
src/om3d.rc
Normal file
13
src/om3d.rc
Normal file
|
@ -0,0 +1,13 @@
|
|||
#[link(name = "om3d",
|
||||
vers = "0.1",
|
||||
author = "Brendan Zabarauskas")];
|
||||
|
||||
#[comment = "Linear algebra library for Rust. Incomplete and probably buggy."];
|
||||
#[crate_type = "lib"];
|
||||
|
||||
use std;
|
||||
|
||||
mod mat;
|
||||
mod projection;
|
||||
mod quat;
|
||||
mod vec;
|
45
src/projection.rs
Normal file
45
src/projection.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
import float::consts::pi;
|
||||
import mat::*;
|
||||
|
||||
//
|
||||
// Create a perspective projection matrix
|
||||
//
|
||||
// fov is in degrees
|
||||
// http://www.opengl.org/wiki/GluPerspective_code
|
||||
//
|
||||
pure fn perspective(fovy:float, aspectRatio:float, near:float, fa:float) -> mat4 {
|
||||
let ymax = near * tan(fovy * PI / 360.0);
|
||||
let xmax = ymax * aspectRatio;
|
||||
return frustum(-xmax, xmax, -ymax, ymax, near, far);
|
||||
}
|
||||
|
||||
//
|
||||
// Define a view frustrum
|
||||
// http://www.felixgers.de/teaching/jogl/perspectiveProjection.html
|
||||
// http://www.opengl.org/wiki/GluPerspective_code
|
||||
//
|
||||
// TODO: double check algorithm
|
||||
//
|
||||
pure fn frustum(left:float, right:float, bottom:float, top:float, near:float, far:float) -> mat4 {
|
||||
let m00:float = (2*near)/(right-left);
|
||||
let m01:float = 0.0;
|
||||
let m02:float = 0.0;
|
||||
let m03:float = 0.0;
|
||||
let m10:float = 0.0;
|
||||
let m11:float = (2*near)/(top-bottom);
|
||||
let m12:float = 0.0;
|
||||
let m13:float = 0.0;
|
||||
let m20:float = (right+left)/(right-left);
|
||||
let m21:float = (top+bottom)/(top-bottom);
|
||||
let m22:float = -(far+near)/(far-near);
|
||||
let m23:float = -1.0;
|
||||
let m30:float = 0.0;
|
||||
let m31:float = 0.0;
|
||||
let m32:float = -(2*far*near)/(far-near);
|
||||
let m33:float = 0.0;
|
||||
|
||||
return mat4(m00, m01, m02, m03,
|
||||
m10, m11, m12, m13,
|
||||
m20, m21, m22, m23,
|
||||
m30, m31, m32, m33);
|
||||
}
|
206
src/quat.rs
Normal file
206
src/quat.rs
Normal file
|
@ -0,0 +1,206 @@
|
|||
import std::cmp::FuzzyEq;
|
||||
import cmp::Ord;
|
||||
import num::Num;
|
||||
import to_str::ToStr;
|
||||
import mat::*;
|
||||
import vec::*;
|
||||
|
||||
// TODO: Unittests! I've probably made lots of mistakes...
|
||||
|
||||
//
|
||||
// Quaternion
|
||||
//
|
||||
trait Quaternion<T:Num Ord FuzzyEq> {
|
||||
pure fn dim() -> uint;
|
||||
|
||||
pure fn index(&&index:uint) -> T;
|
||||
fn w() -> T;
|
||||
fn x() -> T;
|
||||
fn y() -> T;
|
||||
fn z() -> T;
|
||||
|
||||
pure fn neg() -> self;
|
||||
|
||||
pure fn mul_f(&&value:T) -> self;
|
||||
pure fn div_f(&&value:T) -> self;
|
||||
|
||||
// pure fn mul_v(&&vec3) -> vec3;
|
||||
|
||||
pure fn add_q(&&other:self) -> self;
|
||||
pure fn sub_q(&&other:self) -> self;
|
||||
pure fn mul_q(&&other:self) -> self;
|
||||
|
||||
pure fn exact_eq(&&other:self) -> bool;
|
||||
pure fn fuzzy_eq(&&other:self) -> bool;
|
||||
pure fn eq(&&other:self) -> bool;
|
||||
|
||||
pure fn conjugate() -> self;
|
||||
pure fn inverse() -> self;
|
||||
pure fn magnitude2() -> T;
|
||||
pure fn magnitude() -> T;
|
||||
|
||||
pure fn to_mat3() -> mat3;
|
||||
pure fn to_mat4() -> mat4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Quat struct definition
|
||||
//
|
||||
struct quat { data:[float * 4] }
|
||||
|
||||
//
|
||||
// Quat Constructor
|
||||
//
|
||||
#[inline(always)]
|
||||
pure fn quat(w:float, x:float, y:float, z:float) -> quat {
|
||||
quat { data: [ w, x, y, z ] }
|
||||
}
|
||||
|
||||
//
|
||||
// Quaternion Implementation
|
||||
//
|
||||
impl quat<float> {
|
||||
#[inline(always)]
|
||||
pure fn dim() -> uint { 4 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn index(&&i: uint) -> float {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn neg() -> quat {
|
||||
quat(-self[0], -self[1], -self[2], -self[3])
|
||||
}
|
||||
|
||||
#[inline(always)] fn w() -> float { self.data[0] }
|
||||
#[inline(always)] fn x() -> float { self.data[1] }
|
||||
#[inline(always)] fn y() -> float { self.data[2] }
|
||||
#[inline(always)] fn z() -> float { self.data[3] }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_f(&&value:float) -> quat {
|
||||
quat(self[0] * value,
|
||||
self[1] * value,
|
||||
self[2] * value,
|
||||
self[3] * value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn div_f(&&value:float) -> quat {
|
||||
quat(self[0] / value,
|
||||
self[1] / value,
|
||||
self[2] / value,
|
||||
self[3] / value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn add_q(&&other:quat) -> quat{
|
||||
quat(self[0] + other[0],
|
||||
self[1] + other[1],
|
||||
self[2] + other[2],
|
||||
self[3] + other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sub_q(&&other:quat) -> quat{
|
||||
quat(self[0] - other[0],
|
||||
self[1] - other[1],
|
||||
self[2] - other[2],
|
||||
self[3] - other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_q(&&other:quat) -> quat {
|
||||
quat(self.w()*other.w() - self.x()*other.x() - self.y()*other.y() - self.z()*other.z(),
|
||||
self.w()*other.x() + self.x()*other.w() + self.y()*other.z() - self.z()*other.y(),
|
||||
self.w()*other.y() + self.y()*other.w() + self.z()*other.x() - self.x()*other.z(),
|
||||
self.w()*other.z() + self.z()*other.w() + self.x()*other.y() - self.y()*other.x())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn exact_eq(&&other:quat) -> bool {
|
||||
self[0] == other[0] &&
|
||||
self[1] == other[1] &&
|
||||
self[2] == other[2] &&
|
||||
self[3] == other[3]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn fuzzy_eq(&&other: quat) -> bool {
|
||||
self[0].fuzzy_eq(&other[0]) &&
|
||||
self[1].fuzzy_eq(&other[1]) &&
|
||||
self[2].fuzzy_eq(&other[2]) &&
|
||||
self[3].fuzzy_eq(&other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn eq(&&other:quat) -> bool {
|
||||
self.fuzzy_eq(other)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn conjugate() -> quat {
|
||||
quat(self.w(), -self.x(), -self.y(), -self.z());
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn inverse() -> quat {
|
||||
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn magnitude2() -> float {
|
||||
self.w() * self.w() +
|
||||
self.x() * self.x() +
|
||||
self.y() * self.y() +
|
||||
self.z() * self.z()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn magnitude() -> float {
|
||||
sqrt(self.magnitude2)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn to_mat3() -> mat3 {
|
||||
let x2 = self.x() + self.x();
|
||||
let y2 = self.y() + self.y();
|
||||
let z2 = self.z() + self.z();
|
||||
|
||||
let xx2 = x2 * self.x();
|
||||
let xy2 = x2 * self.y();
|
||||
let xz2 = x2 * self.z();
|
||||
|
||||
let yy2 = y2 * self.y();
|
||||
let yz2 = y2 * self.z();
|
||||
let zz2 = z2 * self.z();
|
||||
|
||||
let wy2 = y2 * self.w();
|
||||
let wz2 = z2 * self.w();
|
||||
let wx2 = x2 * self.w();
|
||||
|
||||
return mat3(1 - yy2 - zz2, xy2 - wz2, xz2 + wy2,
|
||||
xy2 + wz2, 1 - xx2 - zz2, yz2 - wx2,
|
||||
xz2 - wy2, yz2 + wx2, 1 - xx2 - yy2);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn to_mat4() -> mat4 {
|
||||
self.to_mat3().to_mat4()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Convert To String
|
||||
//
|
||||
impl quat: ToStr {
|
||||
fn to_str() -> ~str {
|
||||
fmt!("quat[ %f, %f, %f, %f ]", self.w(), self.x(), self.y(), self.z())
|
||||
}
|
||||
}
|
526
src/vec.rs
Normal file
526
src/vec.rs
Normal file
|
@ -0,0 +1,526 @@
|
|||
import std::cmp::FuzzyEq;
|
||||
import cmp::Ord;
|
||||
import num::Num;
|
||||
import float::sqrt;
|
||||
import to_str::ToStr;
|
||||
|
||||
// TODO: Unittests! I've probably made lots of mistakes...
|
||||
|
||||
//
|
||||
// N-dimensional Vector
|
||||
//
|
||||
trait Vector<T:Num Ord FuzzyEq> {
|
||||
pure fn dim() -> uint;
|
||||
|
||||
pure fn index(&&index:uint) -> T;
|
||||
|
||||
pure fn neg() -> self;
|
||||
|
||||
pure fn add_f(&&value:T) -> self;
|
||||
pure fn sub_f(&&value:T) -> self;
|
||||
pure fn mul_f(&&value:T) -> self;
|
||||
pure fn div_f(&&value:T) -> self;
|
||||
|
||||
pure fn add_v(&&other: self) -> self;
|
||||
pure fn sub_v(&&other: self) -> self;
|
||||
|
||||
pure fn exact_eq(&&other:self) -> bool;
|
||||
pure fn fuzzy_eq(&&other:self) -> bool;
|
||||
pure fn eq(&&other:self) -> bool;
|
||||
|
||||
pure fn dot(&&other: self) -> T;
|
||||
|
||||
pure fn magnitude2() -> T;
|
||||
pure fn magnitude() -> T;
|
||||
pure fn normalize() -> self;
|
||||
|
||||
// pure fn lerp(&&other:self, &&value:T) -> self;
|
||||
// pure fn abs(&&other:self) -> self;
|
||||
// pure fn min(&&other:self) -> self;
|
||||
// pure fn max(&&other:self) -> self;
|
||||
}
|
||||
|
||||
//
|
||||
// 2-Dimensional Vector
|
||||
//
|
||||
trait Vector2<T:Num Ord FuzzyEq> {
|
||||
// This is where I wish rust had properties ;)
|
||||
fn x() -> T;
|
||||
fn y() -> T;
|
||||
}
|
||||
|
||||
//
|
||||
// 3-Dimensional Vector
|
||||
//
|
||||
trait Vector3<T:Num Ord FuzzyEq> {
|
||||
fn x() -> T;
|
||||
fn y() -> T;
|
||||
fn z() -> T;
|
||||
|
||||
fn cross(&&other:self) -> self;
|
||||
}
|
||||
|
||||
//
|
||||
// 4-Dimensional Vector
|
||||
//
|
||||
trait Vector4<T:Num Ord FuzzyEq> {
|
||||
fn x() -> T;
|
||||
fn y() -> T;
|
||||
fn z() -> T;
|
||||
fn w() -> T;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Vec2 struct definition
|
||||
//
|
||||
struct vec2 { data:[float * 2] }
|
||||
|
||||
//
|
||||
// Vec2 Constructor
|
||||
//
|
||||
#[inline(always)]
|
||||
pure fn vec2(x:float, y:float) -> vec2 {
|
||||
vec2 { data: [ x, y ] }
|
||||
}
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
#[inline(always)] pure fn vec2_zero() -> vec2 { vec2 (0.0, 0.0) }
|
||||
#[inline(always)] pure fn vec2_unit_x() -> vec2 { vec2 (1.0, 0.0) }
|
||||
#[inline(always)] pure fn vec2_unit_y() -> vec2 { vec2 (0.0, 1.0) }
|
||||
#[inline(always)] pure fn vec2_identity() -> vec2 { vec2 (1.0, 1.0) }
|
||||
|
||||
//
|
||||
// Vector2 Implementation
|
||||
//
|
||||
impl vec2: Vector2<float> {
|
||||
#[inline(always)] fn x() -> float { self.data[0] }
|
||||
#[inline(always)] fn y() -> float { self.data[1] }
|
||||
}
|
||||
|
||||
//
|
||||
// Vector Implementation
|
||||
//
|
||||
impl vec2: Vector<float> {
|
||||
#[inline(always)]
|
||||
pure fn dim() -> uint { 2 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn index(&&i: uint) -> float {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn neg() -> vec2 {
|
||||
vec2(-self[0], -self[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn add_f(&&value:float) -> vec2 {
|
||||
vec2(self[0] + value,
|
||||
self[1] + value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sub_f(&&value:float) -> vec2 {
|
||||
vec2(self[0] - value,
|
||||
self[1] - value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_f(&&value:float) -> vec2 {
|
||||
vec2(self[0] * value,
|
||||
self[1] * value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn div_f(&&value:float) -> vec2 {
|
||||
vec2(self[0] / value,
|
||||
self[1] / value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn add_v(&&other: vec2) -> vec2{
|
||||
vec2(self[0] + other[0],
|
||||
self[1] + other[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sub_v(&&other: vec2) -> vec2{
|
||||
vec2(self[0] - other[0],
|
||||
self[1] - other[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn exact_eq(&&other:vec2) -> bool {
|
||||
self[0] == other[0] &&
|
||||
self[1] == other[1]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn fuzzy_eq(&&other: vec2) -> bool {
|
||||
self[0].fuzzy_eq(&other[0]) &&
|
||||
self[1].fuzzy_eq(&other[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn eq(&&other:vec2) -> bool {
|
||||
self.fuzzy_eq(other)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn dot(&&other: vec2) -> float {
|
||||
self[0] * other[0] +
|
||||
self[1] * other[1]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn magnitude2() -> float {
|
||||
self[0] * self[0] +
|
||||
self[1] * self[1]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn magnitude() -> float {
|
||||
sqrt(self.magnitude2())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn normalize() -> vec2 {
|
||||
let n = 1.0 / self.magnitude();
|
||||
return self.mul_f(n);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Convert To String
|
||||
//
|
||||
impl vec2: ToStr {
|
||||
fn to_str() -> ~str {
|
||||
fmt!("vec2[ %f, %f ]", self[0], self[1])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Vec3 struct definition
|
||||
//
|
||||
struct vec3 { data:[float * 3] }
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
#[inline(always)] pure fn vec3_zero() -> vec3 { vec3(0.0, 0.0, 0.0) }
|
||||
#[inline(always)] pure fn vec3_unit_x() -> vec3 { vec3(1.0, 0.0, 0.0) }
|
||||
#[inline(always)] pure fn vec3_unit_y() -> vec3 { vec3(0.0, 1.0, 0.0) }
|
||||
#[inline(always)] pure fn vec3_unit_z() -> vec3 { vec3(0.0, 0.0, 1.0) }
|
||||
#[inline(always)] pure fn vec3_identity() -> vec3 { vec3(1.0, 1.0, 1.0) }
|
||||
|
||||
//
|
||||
// Vec3 Constructor
|
||||
//
|
||||
#[inline(always)]
|
||||
pure fn vec3(x:float, y:float, z:float) -> vec3 {
|
||||
vec3 { data: [ x, y, z ] }
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Vector3 Implementation
|
||||
//
|
||||
impl vec3: Vector3<float> {
|
||||
#[inline(always)] fn x() -> float { self.data[0] }
|
||||
#[inline(always)] fn y() -> float { self.data[1] }
|
||||
#[inline(always)] fn z() -> float { self.data[2] }
|
||||
|
||||
#[inline(always)]
|
||||
fn cross(&&other:vec3) -> vec3 {
|
||||
vec3((self[1] * other[2]) - (self[2] * other[1]),
|
||||
(self[2] * other[0]) - (self[0] * other[2]),
|
||||
(self[0] * other[1]) - (self[1] * other[0]))
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Vector Implementation
|
||||
//
|
||||
impl vec3: Vector<float> {
|
||||
#[inline(always)]
|
||||
pure fn dim() -> uint { 3 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn index(&&i: uint) -> float {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn neg() -> vec3 {
|
||||
vec3(-self[0], -self[1], -self[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn add_f(&&value:float) -> vec3 {
|
||||
vec3(self[0] + value,
|
||||
self[1] + value,
|
||||
self[2] + value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sub_f(&&value:float) -> vec3 {
|
||||
vec3(self[0] - value,
|
||||
self[1] - value,
|
||||
self[2] - value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_f(&&value:float) -> vec3 {
|
||||
vec3(self[0] * value,
|
||||
self[1] * value,
|
||||
self[2] * value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn div_f(&&value:float) -> vec3 {
|
||||
vec3(self[0] / value,
|
||||
self[1] / value,
|
||||
self[2] / value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn add_v(&&other: vec3) -> vec3{
|
||||
vec3(self[0] + other[0],
|
||||
self[1] + other[1],
|
||||
self[2] + other[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sub_v(&&other: vec3) -> vec3{
|
||||
vec3(self[0] - other[0],
|
||||
self[1] - other[1],
|
||||
self[2] - other[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn exact_eq(&&other:vec3) -> bool {
|
||||
self[0] == other[0] &&
|
||||
self[1] == other[1] &&
|
||||
self[2] == other[2]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn fuzzy_eq(&&other: vec3) -> bool {
|
||||
self[0].fuzzy_eq(&other[0]) &&
|
||||
self[1].fuzzy_eq(&other[1]) &&
|
||||
self[2].fuzzy_eq(&other[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn eq(&&other:vec3) -> bool {
|
||||
self.fuzzy_eq(other)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn dot(&&other: vec3) -> float {
|
||||
self[0] * other[0] +
|
||||
self[1] * other[1] +
|
||||
self[2] * other[2]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn magnitude2() -> float {
|
||||
self[0] * self[0] +
|
||||
self[1] * self[1] +
|
||||
self[2] * self[2]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn magnitude() -> float {
|
||||
sqrt(self.magnitude2())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn normalize() -> vec3 {
|
||||
let n = 1.0 / self.magnitude();
|
||||
return self.mul_f(n);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Convert To String
|
||||
//
|
||||
impl vec3: ToStr {
|
||||
fn to_str() -> ~str {
|
||||
fmt!("vec3[ %f, %f, %f ]", self[0], self[1], self[2])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Vec4 struct definition
|
||||
//
|
||||
struct vec4 { data:[float * 4] }
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
#[inline(always)] pure fn vec4_zero() -> vec4 { vec4(0.0, 0.0, 0.0, 0.0) }
|
||||
#[inline(always)] pure fn vec4_unit_x() -> vec4 { vec4(1.0, 0.0, 0.0, 0.0) }
|
||||
#[inline(always)] pure fn vec4_unit_y() -> vec4 { vec4(0.0, 1.0, 0.0, 0.0) }
|
||||
#[inline(always)] pure fn vec4_unit_z() -> vec4 { vec4(0.0, 0.0, 1.0, 0.0) }
|
||||
#[inline(always)] pure fn vec4_unit_w() -> vec4 { vec4(0.0, 0.0, 0.0, 1.0) }
|
||||
#[inline(always)] pure fn vec4_identity() -> vec4 { vec4(1.0, 1.0, 1.0, 1.0) }
|
||||
|
||||
//
|
||||
// Vec4 Constructor
|
||||
//
|
||||
#[inline(always)]
|
||||
pure fn vec4(x:float, y:float, z:float, w:float) -> vec4 {
|
||||
vec4 { data: [ x, y, z, w ] }
|
||||
}
|
||||
|
||||
//
|
||||
// Vector4 Implementation
|
||||
//
|
||||
impl vec4: Vector4<float> {
|
||||
#[inline(always)] fn x() -> float { self.data[0] }
|
||||
#[inline(always)] fn y() -> float { self.data[1] }
|
||||
#[inline(always)] fn z() -> float { self.data[2] }
|
||||
#[inline(always)] fn w() -> float { self.data[3] }
|
||||
}
|
||||
|
||||
//
|
||||
// Vector Implementation
|
||||
//
|
||||
impl vec4: Vector<float> {
|
||||
#[inline(always)]
|
||||
pure fn dim() -> uint { 4 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn index(&&i: uint) -> float {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn neg() -> vec4 {
|
||||
vec4(-self[0], -self[1], -self[2], -self[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn add_f(&&value:float) -> vec4 {
|
||||
vec4(self[0] + value,
|
||||
self[1] + value,
|
||||
self[2] + value,
|
||||
self[3] + value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sub_f(&&value:float) -> vec4 {
|
||||
vec4(self[0] - value,
|
||||
self[1] - value,
|
||||
self[2] - value,
|
||||
self[3] - value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn mul_f(&&value:float) -> vec4 {
|
||||
vec4(self[0] * value,
|
||||
self[1] * value,
|
||||
self[2] * value,
|
||||
self[3] * value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn div_f(&&value:float) -> vec4 {
|
||||
vec4(self[0] / value,
|
||||
self[1] / value,
|
||||
self[2] / value,
|
||||
self[3] / value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn add_v(&&other: vec4) -> vec4{
|
||||
vec4(self[0] + other[0],
|
||||
self[1] + other[1],
|
||||
self[2] + other[2],
|
||||
self[3] + other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sub_v(&&other: vec4) -> vec4{
|
||||
vec4(self[0] - other[0],
|
||||
self[1] - other[1],
|
||||
self[2] - other[2],
|
||||
self[3] - other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn exact_eq(&&other:vec4) -> bool {
|
||||
self[0] == other[0] &&
|
||||
self[1] == other[1] &&
|
||||
self[2] == other[2] &&
|
||||
self[3] == other[3]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn fuzzy_eq(&&other: vec4) -> bool {
|
||||
self[0].fuzzy_eq(&other[0]) &&
|
||||
self[1].fuzzy_eq(&other[1]) &&
|
||||
self[2].fuzzy_eq(&other[2]) &&
|
||||
self[3].fuzzy_eq(&other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn eq(&&other:vec4) -> bool {
|
||||
self.fuzzy_eq(other)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn dot(&&other:vec4) -> float {
|
||||
self[0] * other[0] +
|
||||
self[1] * other[1] +
|
||||
self[2] * other[2] +
|
||||
self[3] * other[3]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn magnitude2() -> float {
|
||||
self[0] * self[0] +
|
||||
self[1] * self[1] +
|
||||
self[2] * self[2] +
|
||||
self[3] + self[3]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn magnitude() -> float {
|
||||
sqrt(self.magnitude2())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn normalize() -> vec4 {
|
||||
let n = 1.0 / self.magnitude();
|
||||
return self.mul_f(n);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Convert To String
|
||||
//
|
||||
impl vec4: ToStr {
|
||||
fn to_str() -> ~str {
|
||||
fmt!("vec4[ %f, %f, %f, %f ]", self[0], self[1], self[2], self[3])
|
||||
}
|
||||
}
|
10
sublime/om3d.sublime-project
Normal file
10
sublime/om3d.sublime-project
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"folders":
|
||||
[
|
||||
{
|
||||
"path": "../",
|
||||
"file_exclude_patterns": ["*.sublime-workspace"],
|
||||
"folder_exclude_patterns": ["*.dSYM"]
|
||||
}
|
||||
]
|
||||
}
|
16
test/mat-test.rs
Normal file
16
test/mat-test.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// TODO
|
||||
|
||||
#[test]
|
||||
fn test_mat2() {
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mat3() {
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mat4() {
|
||||
|
||||
}
|
6
test/quat-test.rs
Normal file
6
test/quat-test.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
// TODO
|
||||
|
||||
#[test]
|
||||
fn test_quat() {
|
||||
|
||||
}
|
16
test/vec-test.rs
Normal file
16
test/vec-test.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// TODO
|
||||
|
||||
#[test]
|
||||
fn test_mat2() {
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mat3() {
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mat4() {
|
||||
|
||||
}
|
Loading…
Reference in a new issue