#pragma once #include #include #include #include #include namespace sead { template class MathCalcCommon { public: static const u32 cQuarterRoundIdx = 0x40000000; // 90 degrees, PI/2 radians static const u32 cHalfRoundIdx = 0x80000000; // 180 degrees, PI radians struct SinCosSample { T sin_val; T sin_delta; T cos_val; T cos_delta; }; struct AtanSample { u32 atan_val; T atan_delta; }; struct ExpSample { T exp_val; T exp_delta; }; struct LogSample { T log_val; T log_delta; }; static T piHalf() { return numbers::pi_v / static_cast(2); } static T pi() { return numbers::pi_v; } static T pi2() { return numbers::pi_v * static_cast(2); } static T zero() { return static_cast(0); } static T one() { return static_cast(1); } static T ln2() { return numbers::ln2_v; } static T ln2Inv() { return numbers::log2e_v; } static T neg(T t); static T inv(T t); /// Returns -1 for strictly negative values and 1 otherwise. static T sign(T value); static T fitSign(T value, T sign_value) { return abs(value) * sign(sign_value); } static T square(T t) { return t * t; } static T sqrt(T t); static T rsqrt(T t); static T pow(T x, T y); static T powTable(T, T); static T sin(T t); static T cos(T t); static T tan(T t); static T asin(T s); static T acos(T c); static T atan(T t); static T atan2(T y, T x); static T sinIdx(u32 idx); static T cosIdx(u32 idx); static T tanIdx(u32 idx); static u32 asinIdx(T s); static u32 acosIdx(T c); static u32 atanIdx(T t); static u32 atan2Idx(T y, T x); static void sinCosIdx(T* p_sin, T* p_cos, u32 idx); static T exp(T t); static T log(T t); static T log2(T n); static T log10(T t); static T expTable(T x); static T logTable(T x); static T minNumber(); static T maxNumber(); static T infinity(); static T nan(); static T epsilon() { return std::numeric_limits::epsilon(); } static bool equalsEpsilon(T lhs, T rhs, T eps = epsilon()) { const T diff = lhs - rhs; return -eps <= diff && diff <= eps; } static T abs(T x) { return x > 0 ? x : -x; } static T max(T a, T b); static T min(T a, T b); static T max3(T a, T b, T c); static T min3(T a, T b, T c); static T deg2rad(T deg); static T rad2deg(T rad); static u32 deg2idx(T a); static u32 rad2idx(T a); static T idx2deg(u32 a); static T idx2rad(u32 a); static T roundAngle(T); static T angleDist(T, T); static T random(); static T getRand(T); static T getRandRange(T, T); static T getRandSign(); static s32 roundOff(T); static s32 floor(T); static s32 ceil(T); static T roundUp(T x, s32 multNumber); static s32 roundUpPow2(T x, s32 y); static s32 roundDownN(T val, s32 multNumber); static s32 roundDownPow2(T x, s32 y); static T clampMax(T val, T max_); static T clampMin(T val, T min_); static T clamp2(T min_, T val, T max_); // is this the same function? static T clamp(T value, T low, T high); static T gcd(T x, T y); static T lcm(T x, T y); static bool isZero(T, T); static bool isNan(T); static bool isPow2(T); static bool isMultiplePow2(T, T); static bool isInfinity(T); static bool isIntersect1d(T, T, T, T); /// Adds or subtracts `step` from `value` towards `target`. /// Returns whether the new value is equal to the target. static bool chase(T* value, T target, T step); static bool chaseAngle(T*, T, T); static bool chaseAngleIdx(u32*, u32, s64); static T lerp(T a, T b, f32 ratio); protected: static u32 atanIdx_(T t); static T expLn2_(T x); static T log1_2_(T x); static void assertGreaterThanOrEqualToZero_(T); public: /// Note: this is only defined for T = float at the moment. static const SinCosSample cSinCosTbl[256 + 1]; static const AtanSample cAtanTbl[128 + 1]; static const ExpSample cExpTbl[32 + 1]; static const LogSample cLogTbl[256 + 1]; }; typedef MathCalcCommon Mathi; typedef MathCalcCommon Mathu; typedef MathCalcCommon Mathf; typedef MathCalcCommon MathSizeT; template <> u32 MathCalcCommon::atanIdx_(f32 t); template constexpr T log2(T n) { static_assert(std::is_integral(), "T must be an integral type"); return n <= 1 ? 0 : 1 + log2(n >> 1); } } // namespace sead #define SEAD_MATH_MATH_CALC_COMMON_H_ #include #undef SEAD_MATH_MATH_CALC_COMMON_H_