1 /// Custom templated math 2 module sily.math; 3 4 import std.math; 5 import std.traits: isFloatingPoint; 6 7 // https://github.com/godotengine/godot/blob/master/core/math/math_funcs.cpp 8 9 const double degtorad = PI / 180.0; 10 const double radtodeg = 180.0 / PI; 11 12 alias deg2rad = degtorad; 13 alias rad2deg = radtodeg; 14 15 /// Linearly interpolates value 16 T lerp(T)(T from, T to, T weight) if (isFloatingPoint!T) { 17 from += (weight * (to - from)); 18 return from; 19 } 20 21 /// Snaps value to step 22 T snap(T)(T p_val, T p_step) if (isFloatingPoint!T) { 23 if (p_step != 0) { 24 p_val = floor(p_val / p_step + 0.5) * p_step; 25 } 26 return p_val; 27 } 28 29 /// Snaps value to step, if T is not float, then explicit casts are used 30 /// and it may cause data loss 31 T snap(T)(T p_val, T p_step) if (!isFloatingPoint!T) { 32 if (p_step != 0) { 33 p_val = cast(T) (floor(cast(double) p_val / cast(double) p_step + 0.5) * cast(double) p_step); 34 } 35 return p_val; 36 } 37 38 // FIXME: cubic_interpolate 39 /* 40 static _ALWAYS_INLINE_ float cubic_interpolate(float p_from, float p_to, float p_pre, float p_post, float p_weight) { 41 return 0.5f * 42 ((p_from * 2.0f) + 43 (-p_pre + p_to) * p_weight + 44 (2.0f * p_pre - 5.0f * p_from + 4.0f * p_to - p_post) * (p_weight * p_weight) + 45 (-p_pre + 3.0f * p_from - 3.0f * p_to + p_post) * (p_weight * p_weight * p_weight)); 46 } 47 48 static _ALWAYS_INLINE_ float lerp_angle(float p_from, float p_to, float p_weight) { 49 float difference = fmod(p_to - p_from, (float)Math_TAU); 50 float distance = fmod(2.0f * difference, (float)Math_TAU) - difference; 51 return p_from + distance * p_weight; 52 } 53 54 static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_s) { 55 if (is_equal_approx(p_from, p_to)) { 56 return p_from; 57 } 58 float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f); 59 return s * s * (3.0f - 2.0f * s); 60 } 61 static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) { 62 double range = max - min; 63 return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range)); 64 } 65 */