1#pragma once
2
3#include <basis/seadTypes.h>
4#include <cmath>
5#include <limits>
6#include <math/seadMathNumbers.h>
7#include <type_traits>
8
9namespace sead
10{
11template <typename T>
12class MathCalcCommon
13{
14public:
15 static const u32 cQuarterRoundIdx = 0x40000000; // 90 degrees, PI/2 radians
16 static const u32 cHalfRoundIdx = 0x80000000; // 180 degrees, PI radians
17
18 struct SinCosSample
19 {
20 T sin_val;
21 T sin_delta;
22 T cos_val;
23 T cos_delta;
24 };
25
26 struct AtanSample
27 {
28 u32 atan_val;
29 T atan_delta;
30 };
31
32 struct ExpSample
33 {
34 T exp_val;
35 T exp_delta;
36 };
37
38 struct LogSample
39 {
40 T log_val;
41 T log_delta;
42 };
43
44 static T piHalf() { return numbers::pi_v<T> / static_cast<T>(2); }
45 static T pi() { return numbers::pi_v<T>; }
46 static T pi2() { return numbers::pi_v<T> * static_cast<T>(2); }
47 static T zero() { return static_cast<T>(0); }
48 static T one() { return static_cast<T>(1); }
49 static T ln2() { return numbers::ln2_v<T>; }
50 static T ln2Inv() { return numbers::log2e_v<T>; }
51
52 static T neg(T t);
53 static T inv(T t);
54
55 /// Returns -1 for strictly negative values and 1 otherwise.
56 static T sign(T value);
57
58 static T fitSign(T value, T sign_value) { return abs(x: value) * sign(value: sign_value); }
59
60 static T square(T t) { return t * t; }
61
62 static T sqrt(T t);
63 static T rsqrt(T t);
64
65 static T pow(T x, T y);
66 static T powTable(T, T);
67
68 static T sin(T t);
69 static T cos(T t);
70 static T tan(T t);
71
72 static T asin(T s);
73 static T acos(T c);
74 static T atan(T t);
75 static T atan2(T y, T x);
76
77 static T sinIdx(u32 idx);
78 static T cosIdx(u32 idx);
79 static T tanIdx(u32 idx);
80
81 static u32 asinIdx(T s);
82 static u32 acosIdx(T c);
83 static u32 atanIdx(T t);
84 static u32 atan2Idx(T y, T x);
85
86 static void sinCosIdx(T* p_sin, T* p_cos, u32 idx);
87
88 static T exp(T t);
89 static T log(T t);
90 static T log2(T n);
91 static T log10(T t);
92
93 static T expTable(T x);
94 static T logTable(T x);
95
96 static T minNumber();
97 static T maxNumber();
98 static T infinity();
99 static T nan();
100 static T epsilon() { return std::numeric_limits<T>::epsilon(); }
101
102 static bool equalsEpsilon(T lhs, T rhs, T eps = epsilon())
103 {
104 const T diff = lhs - rhs;
105 return -eps <= diff && diff <= eps;
106 }
107
108 static T abs(T x) { return x > 0 ? x : -x; }
109
110 static T max(T a, T b);
111 static T min(T a, T b);
112 static T max3(T a, T b, T c);
113 static T min3(T a, T b, T c);
114
115 static T deg2rad(T deg);
116 static T rad2deg(T rad);
117
118 static u32 deg2idx(T a);
119 static u32 rad2idx(T a);
120 static T idx2deg(u32 a);
121 static T idx2rad(u32 a);
122
123 static T roundAngle(T);
124 static T angleDist(T, T);
125 static T random();
126 static T getRand(T);
127 static T getRandRange(T, T);
128 static T getRandSign();
129 static s32 roundOff(T);
130 static s32 floor(T);
131 static s32 ceil(T);
132 static T roundUp(T x, s32 multNumber);
133 static s32 roundUpPow2(T x, s32 y);
134 static s32 roundDownN(T val, s32 multNumber);
135 static s32 roundDownPow2(T x, s32 y);
136 static T clampMax(T val, T max_);
137 static T clampMin(T val, T min_);
138 static T clamp(T value, T low, T high);
139 // This is the same as clamp, but with a different order for arguments.
140 static T clamp2(T min_, T val, T max_);
141 static T gcd(T x, T y);
142 static T lcm(T x, T y);
143 static bool isZero(T, T);
144 static bool isNan(T);
145 static bool isPow2(T);
146 static bool isMultiplePow2(T, T);
147 static bool isInfinity(T);
148 static bool isIntersect1d(T, T, T, T);
149
150 /// Adds or subtracts `step` from `value` towards `target`.
151 /// Returns whether the new value is equal to the target.
152 static bool chase(T* value, T target, T step);
153 static bool chaseAngle(T*, T, T);
154 static bool chaseAngleIdx(u32*, u32, s64);
155
156 static T lerp(T a, T b, f32 ratio);
157
158protected:
159 static u32 atanIdx_(T t);
160 static T expLn2_(T x);
161 static T log1_2_(T x);
162 static void assertGreaterThanOrEqualToZero_(T);
163
164public:
165 /// Note: this is only defined for T = float at the moment.
166 static const SinCosSample cSinCosTbl[256 + 1];
167 static const AtanSample cAtanTbl[128 + 1];
168 static const ExpSample cExpTbl[32 + 1];
169 static const LogSample cLogTbl[256 + 1];
170};
171
172typedef MathCalcCommon<s32> Mathi;
173typedef MathCalcCommon<u32> Mathu;
174typedef MathCalcCommon<f32> Mathf;
175typedef MathCalcCommon<size_t> MathSizeT;
176
177template <>
178u32 MathCalcCommon<f32>::atanIdx_(f32 t);
179
180template <typename T>
181constexpr T log2(T n)
182{
183 static_assert(std::is_integral<T>(), "T must be an integral type");
184 return n <= 1 ? 0 : 1 + log2(n >> 1);
185}
186
187} // namespace sead
188
189#define SEAD_MATH_MATH_CALC_COMMON_H_
190#include <math/seadMathCalcCommon.hpp>
191#undef SEAD_MATH_MATH_CALC_COMMON_H_
192