use core::f32::consts::TAU;
use crate::math;
#[inline]
pub const fn to_radians(degrees: f32) -> f32 {
degrees * TAU / 360.0
}
#[inline]
pub const fn to_degrees(radians: f32) -> f32 {
radians * 360.0 / TAU
}
pub fn angle_diff(radians_a: f32, radians_b: f32) -> f32 {
let diff = radians_b - radians_a;
let mut delta = diff % TAU;
if delta < 0.0 {
delta += TAU;
}
if delta > 0.5 * TAU {
delta - TAU
} else {
delta
}
}
#[inline]
pub fn angle_diff_radians(a: crate::angle::Radians, b: crate::angle::Radians) -> crate::angle::Radians {
crate::angle::Radians(angle_diff(a.0, b.0))
}
#[inline]
pub fn square<T: core::ops::Mul<Output = T> + Copy>(x: T) -> T {
x * x
}
#[inline]
pub fn cube<T: core::ops::Mul<Output = T> + Copy>(x: T) -> T {
x * x * x
}
#[inline]
pub fn remainder(x: f32, y: f32) -> f32 {
if y == 0.0 {
return f32::NAN;
}
x - gb_round_rust(x / y) * y
}
#[inline]
pub fn modulo(x: f32, y: f32) -> f32 {
if y == 0.0 {
return f32::NAN;
}
let y_abs = y.abs();
let mut res = remainder(x.abs(), y_abs);
res += y_abs;
math::copysign(res, x)
}
#[inline]
pub fn quake_rsqrt(a: f32) -> f32 {
let x2 = a * 0.5;
let mut i = a.to_bits(); i = 0x5f375a86 - (i >> 1); let mut y = f32::from_bits(i);
const THREE_HALFS: f32 = 1.5;
y = y * (THREE_HALFS - (x2 * y * y)); y = y * (THREE_HALFS - (x2 * y * y)); y
}
#[inline]
fn gb_round_rust(x: f32) -> f32 {
if x >= 0.0 {
math::floor(x + 0.5)
} else {
math::ceil(x - 0.5)
}
}
#[inline]
pub const fn lerp(a: f32, b: f32, t: f32) -> f32 {
a * (1.0 - t) + b * t
}
#[inline]
pub const fn unlerp(t: f32, a: f32, b: f32) -> f32 {
(t - a) / (b - a)
}
#[inline]
pub fn smooth_step(a: f32, b: f32, t: f32) -> f32 {
let x = ((t - a) / (b - a)).clamp(0.0, 1.0); x * x * (3.0 - 2.0 * x)
}
#[inline]
pub fn smoother_step(a: f32, b: f32, t: f32) -> f32 {
let x = ((t - a) / (b - a)).clamp(0.0, 1.0); x * x * x * (x * (x * 6.0 - 15.0) + 10.0)
}
#[inline]
pub const fn clamp(x: f32, min: f32, max: f32) -> f32 {
if x < min {
min
} else if x > max {
max
} else {
x
}
}
#[inline]
pub const fn min(a: f32, b: f32) -> f32 {
if a < b { a } else { b }
}
#[inline]
pub const fn max(a: f32, b: f32) -> f32 {
if a > b { a } else { b }
}
#[inline]
pub const fn sign(x: f32) -> f32 {
if x > 0.0 {
1.0
} else if x < 0.0 {
-1.0
} else {
0.0
}
}
#[inline]
pub const fn abs(x: f32) -> f32 {
if x < 0.0 { -x } else { x }
}
#[inline]
pub fn is_nan(x: f32) -> bool {
x.is_nan()
}
#[inline]
pub fn is_finite(x: f32) -> bool {
x.is_finite()
}
#[inline]
pub fn approx_eq(a: f32, b: f32, epsilon: f32) -> bool {
(a - b).abs() <= epsilon
}