sead
Loading...
Searching...
No Matches
seadMathCalcCommon.hpp
Go to the documentation of this file.
1#pragma once
2
3#ifdef cafe
4#include <math/cafe/seadMathCalcCommonCafe.h>
5#endif // cafe
6
7#include <basis/seadAssert.h>
8
9#include <cmath>
10#include <limits>
11#include <bit>
12
13namespace sead {
14
15template <typename T>
16inline constexpr T
18{
19 return std::sqrt(t);
20}
21
22template <typename T>
23inline constexpr T
25{
26 return 1 / std::sqrt(t);
27}
28
29#ifdef cafe
30
31template <>
32inline constexpr f32
34{
35 return MathCafe<f32>::rsqrt(t) * t;
36}
37
38template <>
39inline constexpr f32
41{
42 return MathCafe<f32>::rsqrt(t);
43}
44
45#endif // cafe
46
47template <typename T>
48inline constexpr T
50{
51 return std::pow(x, y);
52}
53
54template <typename T>
55inline constexpr T
57{
58 return std::sin(t);
59}
60
61template <typename T>
62inline constexpr T
64{
65 return std::cos(t);
66}
67
68template <typename T>
69inline constexpr T
71{
72 return std::tan(t);
73}
74
75template <typename T>
76inline constexpr T
78{
79 return std::asin(s);
80}
81
82template <typename T>
83inline constexpr T
85{
86 return std::acos(c);
87}
88
89template <typename T>
90inline constexpr T
92{
93 return std::atan(t);
94}
95
96template <typename T>
97inline constexpr T
99{
100 return std::atan2(y, x);
101}
102
103template <>
104inline f32
106{
107 u32 index = (idx >> 24) & 0xff;
108 u32 rest = idx & 0xffffff;
109
110 return cSinCosTbl[index].sin_val + cSinCosTbl[index].sin_delta * (static_cast<float>(rest) / static_cast<float>(0x1000000));
111}
112
113template <>
114inline f32
116{
117 u32 index = (idx >> 24) & 0xff;
118 u32 rest = idx & 0xffffff;
119
120 return cSinCosTbl[index].cos_val + cSinCosTbl[index].cos_delta * (static_cast<float>(rest) / static_cast<float>(0x1000000));
121}
122
123template <>
124inline f32
126{
127 u32 index = (idx >> 24) & 0xff;
128 f32 rest = static_cast<f32>(idx & 0xffffff) / 0x1000000;
130
132}
133
134template <>
135inline u32
137{
138 SEAD_ASSERT_MSG(s <= 1 && s >= -1, "s(%f) is not in [-1, 1].", s);
139
140 const f32 rsqrt_2 = 0.7071067690849304f; // rsqrt(2)
141
142 if (s >= 0)
143 {
144 if (s > rsqrt_2)
145 return 0x40000000 - atanIdx_(sqrt(1 - s * s) / s);
146
147 else
148 return atanIdx_(s / sqrt(1 - s * s));
149 }
150 else
151 {
152 if (s < -rsqrt_2)
153 return 0xC0000000 + atanIdx_(-sqrt(1 - s * s) / s);
154
155 else
156 return -atanIdx_(-s / sqrt(1 - s * s));
157 }
158}
159
160template <>
161inline u32
163{
164 SEAD_ASSERT_MSG(c <= 1 && c >= -1, "c(%f) is not in [-1, 1].", c);
165
166 const f32 rsqrt_2 = 0.7071067690849304f; // rsqrt(2)
167
168 if (c >= 0)
169 {
170 if (c > rsqrt_2)
171 return atanIdx_(sqrt(1 - c * c) / c);
172
173 else
174 return 0x40000000 - atanIdx_(c / sqrt(1 - c * c));
175 }
176 else
177 {
178 if (c < -rsqrt_2)
179 return 0x80000000 - atanIdx_(-sqrt(1 - c * c) / c);
180
181 else
182 return 0x40000000 + atanIdx_(-c / sqrt(1 - c * c));
183 }
184}
185
186template <>
187inline u32
189{
190 if (t >= 0)
191 {
192 if (t > 1)
193 return 0x40000000 - atanIdx_(1 / t);
194
195 else
196 return atanIdx_(t);
197 }
198 else
199 {
200 if (t < -1)
201 return 0xC0000000 + atanIdx_(-1 / t);
202
203 else
204 return -atanIdx_(-t);
205 }
206}
207
208template <>
209inline u32
211{
212#pragma clang diagnostic push
213#pragma clang diagnostic ignored "-Wfloat-equal"
214 if (x == 0 && y == 0)
215 return 0;
216#pragma clang diagnostic pop
217
218 if (x >= 0)
219 {
220 if (y >= 0)
221 {
222 if (x >= y)
223 return atanIdx_(y / x);
224
225 else
226 return 0x40000000 - atanIdx_(x / y);
227 }
228 else
229 {
230 if (x >= -y)
231 return -atanIdx_(-y / x);
232
233 else
234 return 0xC0000000 + atanIdx_(x / -y);
235 }
236 }
237 else
238 {
239 if (y >= 0)
240 {
241 if (-x >= y)
242 return 0x80000000 - atanIdx_(y / -x);
243
244 else
245 return 0x40000000 + atanIdx_(-x / y);
246 }
247 else
248 {
249 if (x <= y)
250 return 0x80000000 + atanIdx_(y / x);
251
252 else
253 return 0xC0000000 - atanIdx_(x / y);
254 }
255 }
256}
257
258template <>
259inline void
261{
262 u32 index = (idx >> 24) & 0xff;
263 f32 rest = static_cast<f32>(idx & 0xffffff) / 0x1000000;
265
266 /*if (p_sin != nullptr)*/ *p_sin = sample.sin_val + sample.sin_delta * rest;
267 /*if (p_cos != nullptr)*/ *p_cos = sample.cos_val + sample.cos_delta * rest;
268}
269
270template <typename T>
271inline constexpr T
273{
274 return std::exp(t);
275}
276
277template <typename T>
278inline constexpr T
280{
281 return std::log(t);
282}
283
284template <typename T>
285inline constexpr T
287{
288 return std::log2(t);
289}
290
291template <typename T>
292inline constexpr T
294{
295 return std::log10(t);
296}
297
298template <typename T>
299inline constexpr T
301{
302 return std::numeric_limits<T>::min();
303}
304
305template <typename T>
306inline constexpr T
308{
309 return std::numeric_limits<T>::max();
310}
311
312template <>
313inline constexpr float
315{
316 return -std::numeric_limits<float>::max();
317}
318
319template <>
320inline constexpr float
322{
323 return std::numeric_limits<float>::max();
324}
325
326template <>
327inline constexpr double
329{
330 return -std::numeric_limits<double>::max();
331}
332
333template <>
334inline constexpr double
336{
337 return std::numeric_limits<double>::max();
338}
339
340template <>
341inline constexpr long double
343{
344 return -std::numeric_limits<long double>::max();
345}
346
347template <>
348inline constexpr long double
350{
351 return std::numeric_limits<long double>::max();
352}
353
354template <typename T>
355inline constexpr T
357{
358 return std::numeric_limits<T>::infinity();
359}
360
361template <>
362inline constexpr f32
364{
365 return std::bit_cast<f32>(0x7FFFFFFF);
366}
367
368template <>
369inline constexpr f64
371{
372 return std::bit_cast<f64>(0x7FFFFFFFFFFFFFFF);
373}
374
375template <typename T>
376inline constexpr T
378{
379 return std::numeric_limits<T>::epsilon();
380}
381
382template <>
383inline constexpr s32
385{
386 return (t ^ t >> 31) - (t >> 31);
387}
388
389template <>
390inline constexpr u32
392{
393 return t;
394}
395
396#ifdef cafe
397
398template <>
399inline constexpr f32
401{
402 return std::fabs(t);
403}
404
405template <>
406inline constexpr f64
408{
409 return std::fabs(t);
410}
411
412#endif // cafe
413
414template <typename T>
415inline constexpr s32
417{
418 return std::floor(val + 0.5f);
419}
420
421template <>
422inline constexpr s32
424{
425 return val;
426}
427
428//template <>
429//inline s32
430//MathCalcCommon<u32>::roundOff(u32 val)
431//{
432// return val;
433//}
434
435template <typename T>
436inline constexpr s32
438{
439 return std::floor(val);
440}
441
442template <>
443inline constexpr s32
445{
446 return val;
447}
448
449//template <>
450//inline s32
451//MathCalcCommon<u32>::floor(u32 val)
452//{
453// return val;
454//}
455
456template <typename T>
457inline constexpr s32
459{
460 return std::ceil(val);
461}
462
463template <>
464inline constexpr s32
466{
467 return val;
468}
469
470//template <>
471//inline s32
472//MathCalcCommon<u32>::ceil(u32 val)
473//{
474// return val;
475//}
476
477template <>
478inline constexpr s32
480{
481 SEAD_ASSERT_MSG(val >= 0 && (base - 1u & base) == 0, "illegal param[val:%d, base:%d]", val, base);
482 return static_cast<s32>((static_cast<u32>(val) + (static_cast<u32>(base) - 1u)) & ~(static_cast<u32>(base) - 1u));
483}
484
485template <>
486inline constexpr u32
488{
489 SEAD_ASSERT_MSG((base - 1u & base) == 0, "illegal param[base:%d]", base);
490 return val + (static_cast<u32>(base) - 1u) & ~(static_cast<u32>(base) - 1u);
491}
492
493template <typename T>
494inline constexpr T
496{
497 if (val > max_) val = max_;
498
499 return val;
500}
501
502template <typename T>
503inline constexpr T
505{
506 if (val < min_) val = min_;
507
508 return val;
509}
510
511template <typename T>
512inline constexpr T
514{
515 if (val < min_) val = min_;
516 else if (val > max_) val = max_;
517
518 return val;
519}
520
521} // namespace sead
Definition seadAssert.h:44
#define SEAD_ASSERT_MSG(condition, format,...)
Definition seadAssert.h:33