1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use number_traits::{Num, Cast, Signed, ApproxEq};


#[inline]
pub fn inverse<'a, 'b, T: Copy + Signed>(out: &'a mut [T; 4], a: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = -a[0];
    out[1] = -a[1];
    out[2] = -a[2];
    out[3] = -a[3];
    out
}
#[test]
fn test_inverse() {
    let mut v = [0, 0, 0, 0];
    inverse(&mut v, &[1, 1, 1, 1]);
    assert!(v[0] == -1);
    assert!(v[1] == -1);
    assert!(v[2] == -1);
    assert!(v[3] == -1);
}

#[inline]
pub fn lerp<'a, 'b, T, F>(out: &'a mut [T; 4], a: &'b [T; 4], b: &'b [T; 4], t: F) -> &'a mut [T; 4]
    where T: Copy + Num + Cast<F>,
          F: Copy + Num + Cast<T>,
{
    let a0 = a[0].cast();
    let a1 = a[1].cast();
    let a2 = a[2].cast();
    let a3 = a[3].cast();
    let b0 = b[0].cast();
    let b1 = b[1].cast();
    let b2 = b[2].cast();
    let b3 = b[3].cast();

    out[0] = (a0 + (b0 - a0) * t).cast();
    out[1] = (a1 + (b1 - a1) * t).cast();
    out[2] = (a2 + (b2 - a2) * t).cast();
    out[3] = (a3 + (b3 - a3) * t).cast();
    out
}
#[test]
fn test_lerp() {
    let mut v = [0.0, 0.0, 0.0, 0.0];
    lerp(&mut v, &[0.0, 0.0, 0.0, 0.0], &[1.0, 1.0, 1.0, 1.0], 0.5);
    assert!(v[0] == 0.5);
    assert!(v[1] == 0.5);
    assert!(v[2] == 0.5);
    assert!(v[3] == 0.5);
}

#[inline]
pub fn min<'a, 'b, T: Copy + Num>(out: &'a mut [T; 4], a: &'b [T; 4], b: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = if b[0] < a[0] {b[0]} else {a[0]};
    out[1] = if b[1] < a[1] {b[1]} else {a[1]};
    out[2] = if b[2] < a[2] {b[2]} else {a[2]};
    out[3] = if b[3] < a[3] {b[3]} else {a[3]};
    out
}
#[test]
fn test_min() {
    let mut v = [0, 0, 0, 0];
    min(&mut v, &[1, 0, 1, 0], &[0, 1, 0, 1]);
    assert!(v == [0, 0, 0, 0]);
}

#[inline]
pub fn max<'a, 'b, T: Copy + Num>(out: &'a mut [T; 4], a: &'b [T; 4], b: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = if b[0] > a[0] {b[0]} else {a[0]};
    out[1] = if b[1] > a[1] {b[1]} else {a[1]};
    out[2] = if b[2] > a[2] {b[2]} else {a[2]};
    out[3] = if b[3] > a[3] {b[3]} else {a[3]};
    out
}
#[test]
fn test_max() {
    let mut v = [0, 0, 0, 0];
    max(&mut v, &[1, 0, 1, 0], &[0, 1, 0, 1]);
    assert!(v == [1, 1, 1, 1]);
}

#[inline]
pub fn clamp<'a, 'b, T: Copy + Num>(out: &'a mut [T; 4], a: &'b [T; 4], min: &'b [T; 4], max: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = if a[0] < min[0] {min[0]} else if a[0] > max[0] {max[0]} else {a[0]};
    out[1] = if a[1] < min[1] {min[1]} else if a[1] > max[1] {max[1]} else {a[1]};
    out[2] = if a[2] < min[2] {min[2]} else if a[2] > max[2] {max[2]} else {a[2]};
    out[3] = if a[3] < min[3] {min[3]} else if a[3] > max[3] {max[3]} else {a[3]};
    out
}
#[test]
fn test_clamp() {
    let mut v = [0, 0, 0, 0];
    clamp(&mut v, &[2, 2, 2, 2], &[0, 0, 0, 0], &[1, 1, 1, 1]);
    assert!(v == [1, 1, 1, 1]);
}


#[inline]
pub fn eq<'a, T: Copy + Num + ApproxEq>(a: &'a [T; 4], b: &'a [T; 4]) -> bool {
    !ne(a, b)
}

#[inline]
pub fn ne<'a, T: Copy + Num + ApproxEq>(a: &'a [T; 4], b: &'a [T; 4]) -> bool {
    !a[0].approx_eq(&b[0]) ||
    !a[1].approx_eq(&b[1]) ||
    !a[2].approx_eq(&b[2]) ||
    !a[3].approx_eq(&b[3])
}
#[test]
fn test_ne() {
    assert_eq!(ne(&[1f32, 1f32, 1f32, 1f32], &[1f32, 1f32, 1f32, 1f32]), false);
    assert_eq!(ne(&[0f32, 0f32, 0f32, 0f32], &[1f32, 1f32, 1f32, 1f32]), true);
}