Plasma Engine  2.0
Loading...
Searching...
No Matches
SimdMath_inl.h
1#pragma once
2
4
5// static
6PL_FORCE_INLINE plSimdVec4f plSimdMath::Exp(const plSimdVec4f& f)
7{
8#if PL_ENABLED(PL_COMPILER_MSVC) && PL_SIMD_IMPLEMENTATION == PL_SIMD_IMPLEMENTATION_SSE
9 return _mm_exp_ps(f.m_v);
10#else
11 return plSimdVec4f(plMath::Exp(f.x()), plMath::Exp(f.y()), plMath::Exp(f.z()), plMath::Exp(f.w()));
12#endif
13}
14
15// static
16PL_FORCE_INLINE plSimdVec4f plSimdMath::Ln(const plSimdVec4f& f)
17{
18#if PL_ENABLED(PL_COMPILER_MSVC) && PL_SIMD_IMPLEMENTATION == PL_SIMD_IMPLEMENTATION_SSE
19 return _mm_log_ps(f.m_v);
20#else
21 return plSimdVec4f(plMath::Ln(f.x()), plMath::Ln(f.y()), plMath::Ln(f.z()), plMath::Ln(f.w()));
22#endif
23}
24
25// static
26PL_FORCE_INLINE plSimdVec4f plSimdMath::Log2(const plSimdVec4f& f)
27{
28#if PL_ENABLED(PL_COMPILER_MSVC) && PL_SIMD_IMPLEMENTATION == PL_SIMD_IMPLEMENTATION_SSE
29 return _mm_log2_ps(f.m_v);
30#else
31 return plSimdVec4f(plMath::Log2(f.x()), plMath::Log2(f.y()), plMath::Log2(f.z()), plMath::Log2(f.w()));
32#endif
33}
34
35// static
36PL_FORCE_INLINE plSimdVec4i plSimdMath::Log2i(const plSimdVec4i& i)
37{
38 return plSimdVec4i(plMath::Log2i(i.x()), plMath::Log2i(i.y()), plMath::Log2i(i.z()), plMath::Log2i(i.w()));
39}
40
41// static
42PL_FORCE_INLINE plSimdVec4f plSimdMath::Log10(const plSimdVec4f& f)
43{
44#if PL_ENABLED(PL_COMPILER_MSVC) && PL_SIMD_IMPLEMENTATION == PL_SIMD_IMPLEMENTATION_SSE
45 return _mm_log10_ps(f.m_v);
46#else
47 return plSimdVec4f(plMath::Log10(f.x()), plMath::Log10(f.y()), plMath::Log10(f.z()), plMath::Log10(f.w()));
48#endif
49}
50
51// static
52PL_FORCE_INLINE plSimdVec4f plSimdMath::Pow2(const plSimdVec4f& f)
53{
54#if PL_ENABLED(PL_COMPILER_MSVC) && PL_SIMD_IMPLEMENTATION == PL_SIMD_IMPLEMENTATION_SSE
55 return _mm_exp2_ps(f.m_v);
56#else
57 return plSimdVec4f(plMath::Pow2(f.x()), plMath::Pow2(f.y()), plMath::Pow2(f.z()), plMath::Pow2(f.w()));
58#endif
59}
60
61// static
62PL_FORCE_INLINE plSimdVec4f plSimdMath::Sin(const plSimdVec4f& f)
63{
64#if PL_ENABLED(PL_COMPILER_MSVC) && PL_SIMD_IMPLEMENTATION == PL_SIMD_IMPLEMENTATION_SSE
65 return _mm_sin_ps(f.m_v);
66#else
69#endif
70}
71
72// static
73PL_FORCE_INLINE plSimdVec4f plSimdMath::Cos(const plSimdVec4f& f)
74{
75#if PL_ENABLED(PL_COMPILER_MSVC) && PL_SIMD_IMPLEMENTATION == PL_SIMD_IMPLEMENTATION_SSE
76 return _mm_cos_ps(f.m_v);
77#else
80#endif
81}
82
83// static
84PL_FORCE_INLINE plSimdVec4f plSimdMath::Tan(const plSimdVec4f& f)
85{
86#if PL_ENABLED(PL_COMPILER_MSVC) && PL_SIMD_IMPLEMENTATION == PL_SIMD_IMPLEMENTATION_SSE
87 return _mm_tan_ps(f.m_v);
88#else
91#endif
92}
93
94// static
95PL_ALWAYS_INLINE plSimdVec4f plSimdMath::ASin(const plSimdVec4f& f)
96{
97 return plSimdVec4f(plMath::Pi<float>() * 0.5f) - ACos(f);
98}
99
100// 4th order polynomial approximation
101// 7 * 10^-5 radians precision
102// Reference : Handbook of Mathematical Functions (chapter : Elementary Transcendental Functions), M. Abramowitz and I.A. Stegun, Ed.
103// static
104PL_FORCE_INLINE plSimdVec4f plSimdMath::ACos(const plSimdVec4f& f)
105{
106 plSimdVec4f x1 = f.Abs();
107 plSimdVec4f x2 = x1.CompMul(x1);
108 plSimdVec4f x3 = x2.CompMul(x1);
109
110 plSimdVec4f s = x1 * -0.2121144f + plSimdVec4f(1.5707288f);
111 s += x2 * 0.0742610f;
112 s += x3 * -0.0187293f;
113 s = s.CompMul((plSimdVec4f(1.0f) - x1).GetSqrt());
114
115 return plSimdVec4f::Select(f >= plSimdVec4f::MakeZero(), s, plSimdVec4f(plMath::Pi<float>()) - s);
116}
117
118// Reference: https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/
119// static
120PL_FORCE_INLINE plSimdVec4f plSimdMath::ATan(const plSimdVec4f& f)
121{
122 plSimdVec4f x = f.Abs();
123 plSimdVec4f t0 = plSimdVec4f::Select(x < plSimdVec4f(1.0f), x, x.GetReciprocal());
124 plSimdVec4f t1 = t0.CompMul(t0);
125 plSimdVec4f poly = plSimdVec4f(0.0872929f);
126 poly = plSimdVec4f(-0.301895f) + poly.CompMul(t1);
127 poly = plSimdVec4f(1.0f) + poly.CompMul(t1);
128 poly = poly.CompMul(t0);
129 t0 = plSimdVec4f::Select(x < plSimdVec4f(1.0f), poly, plSimdVec4f(plMath::Pi<float>() * 0.5f) - poly);
130
131 return plSimdVec4f::Select(f < plSimdVec4f::MakeZero(), -t0, t0);
132}
static constexpr plAngle MakeFromRadian(float fRadian)
Creates an instance of plAngle that was initialized from radian. (No need for any conversion)
Definition Angle_inl.h:38
A 4-component SIMD vector class.
Definition SimdVec4f.h:8
static plSimdVec4f MakeZero()
Creates an plSimdVec4f that is initialized to zero.
Definition SimdVec4f_inl.h:8
A SIMD 4-component vector class of signed 32b integers.
Definition SimdVec4i.h:9
constexpr TYPE Pi()
Returns the natural constant Pi.
PL_ALWAYS_INLINE float Sin(plAngle a)
***** Trigonometric Functions *****
Definition MathFloat_inl.h:62
PL_ALWAYS_INLINE float Tan(plAngle a)
Takes an angle, returns its tangent.
Definition MathFloat_inl.h:72
PL_ALWAYS_INLINE float Cos(plAngle a)
Takes an angle, returns its cosine.
Definition MathFloat_inl.h:67
PL_ALWAYS_INLINE plUInt32 Log2i(plUInt32 uiVal)
Returns the integral logarithm to the base 2, that comes closest to the given integer.
Definition MathInt32_inl.h:41
static plSimdVec4f Exp(const plSimdVec4f &f)
Definition SimdMath_inl.h:6