#ifndef MENGA_MATH #define MENGA_MATH #include #include namespace Mengu { // Copied from Godot #define MATH_PI 3.1415926535897932 #define MATH_TAU 6.283185307179586 // Make room for our constexpr's below by overriding potential system-specific macros. #undef ABS #undef SIGN #undef MIN #undef MAX #undef CLAMP // Generic ABS function, for math uses please use Math::abs. template constexpr T ABS(T m_v) { return m_v < 0 ? -m_v : m_v; } template constexpr const T SIGN(const T m_v) { return m_v == 0 ? 0.0f : (m_v < 0 ? -1.0f : +1.0f); } template constexpr auto MIN(const T m_a, const T2 m_b) { return m_a < m_b ? m_a : m_b; } template constexpr auto MAX(const T m_a, const T2 m_b) { return m_a > m_b ? m_a : m_b; } template constexpr auto CLAMP(const T m_a, const T2 m_min, const T3 m_max) { return m_a < m_min ? m_min : (m_a > m_max ? m_max : m_a); } //// ##### template inline T min(T a, T b) { return a < b ? a : b; } template inline T max(T a, T b) { return a > b ? a : b; } template inline T sign(T x) { return static_cast(SIGN(x)); } template inline T abs(T x) { return std::abs(x); } template inline T pow(T x, T e) { return std::pow(x, e); } template inline T exp2(T x) { return std::exp2(x); } template inline T log2(T x) { return std::log2(x); } template inline T log10(T x) { return std::log10(x); } template inline T logb(T base, T x) { return std::log2(x) / std::log2(base); } template inline T sqrt(T x) { return std::sqrt(x); } template inline T lerp(T min_v, T max_v, float w) { return min_v + w * (max_v - min_v); } inline float inverse_lerp(float min_v, float max_v, float v) { return (v - min_v) / (max_v - min_v); } // linearly interpelates between the shortest path between 2 angles. Does NOT gaurentee th output be within [-pi, pi] inline float lerp_angle(float min_v, float max_v, float w) { if ((max_v - min_v) > MATH_PI) { min_v += MATH_TAU; } else if ((min_v - max_v) > MATH_PI) { max_v += MATH_TAU; } return lerp(min_v, max_v, w); } template inline T modf(T x, T *iptr) { return std::modf(x, iptr); } inline int posmod(int x, int y) { int v = x % y; if (v < 0) { v += y; } return v; } inline float fposmod(float x, float y) { float v = std::fmod(x, y); if (v * y < 0.0f) { v += y; } return v; } inline bool is_pow_2(uint32_t x) { return x != 0 && ((x - 1) & x) == 0; } inline uint32_t last_pow_2(uint32_t x) { x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return x - (x >> 1); } inline uint32_t next_pow_2(uint32_t x) { x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return (x << 1) & ~x; } }; #endif