69 lines
1.4 KiB
Rust
69 lines
1.4 KiB
Rust
use num::PrimInt;
|
|
|
|
type Fract8 = u8;
|
|
pub trait Fract8Ops {
|
|
fn scale8(self, scale: Fract8) -> Self;
|
|
}
|
|
|
|
impl Fract8Ops for u8 {
|
|
fn scale8(self, scale: Fract8) -> Self {
|
|
// borrowed from FastLED
|
|
(self as u16 * (1 + scale as u16)).unsigned_shr(8) as u8
|
|
}
|
|
}
|
|
|
|
pub fn scale8<T: Fract8Ops>(i: T, scale: Fract8) -> T {
|
|
i.scale8(scale)
|
|
}
|
|
|
|
pub fn avg7(i: i8, j: i8) -> i8 {
|
|
i.unsigned_shr(1).wrapping_add(j.unsigned_shr(1)).wrapping_add(i & 0x1)
|
|
}
|
|
|
|
pub fn grad8(hash: u8, x: i8, y: i8) -> i8 {
|
|
let mut u: i8;
|
|
let mut v: i8;
|
|
|
|
if hash & 4 != 0 {
|
|
u = y; v = x;
|
|
} else {
|
|
u = x; v = y;
|
|
}
|
|
|
|
if hash & 1 != 0 {
|
|
u = u.wrapping_neg();
|
|
}
|
|
if hash & 2 != 0 {
|
|
v = v.wrapping_neg();
|
|
}
|
|
|
|
return avg7(u, v);
|
|
}
|
|
|
|
pub fn lerp7by8(a: i8, b: i8, frac: u8) -> i8 {
|
|
if b > a {
|
|
let delta: u8 = b.wrapping_sub(a) as u8;
|
|
let scaled: u8 = scale8(delta, frac);
|
|
return a.wrapping_add(scaled as i8);
|
|
} else {
|
|
let delta: u8 = a.wrapping_sub(b) as u8;
|
|
let scaled: u8 = scale8(delta, frac);
|
|
return a.wrapping_sub(scaled as i8);
|
|
}
|
|
}
|
|
|
|
pub fn ease8InOutQuad(i: u8) -> u8 {
|
|
let j = if i & 0x80 != 0 {
|
|
255 - i
|
|
} else {
|
|
i
|
|
};
|
|
let jj = scale8(j, j);
|
|
let jj2 = jj.unsigned_shl(1);
|
|
if i & 0x80 == 0 {
|
|
return jj2
|
|
} else {
|
|
return 255 - jj2;
|
|
}
|
|
}
|