gwnavruntime/math/fastmath.h Source File

fastmath.h
Go to the documentation of this file.
1 /*
2 * Copyright 2015 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 
8 
9 #ifndef Navigation_FastMath_H
10 #define Navigation_FastMath_H
11 
13 
14 
15 #if defined(KY_OS_XBOX360)
16 #include <ppcintrinsics.h>
17 #endif
18 
19 
20 #if defined(KY_OS_PS3)
21 #include <ppu_intrinsics.h>
22 #endif
23 
24 #include <math.h>
25 
26 
27 namespace Kaim
28 {
29 
30 
31 //----------------------------------------------------------------------------------------
32 // Fsel
33 
34 //-------------------------------------
35 #if defined(KY_OS_XBOX360)
36 KY_INLINE KyFloat32 Fsel(KyFloat32 cmp, KyFloat32 v1, KyFloat32 v2)
37 {
38  return (KyFloat32)__fsel(cmp, v1, v2);
39 }
40 
41 //-------------------------------------
42 #elif defined(KY_OS_PS3)
43 KY_INLINE KyFloat32 Fsel(KyFloat32 cmp, KyFloat32 v1, KyFloat32 v2)
44 {
45  return __fsels(cmp, v1, v2);
46 }
47 
48 //-------------------------------------
49 #elif defined(KY_OS_WII)
50 inline float Fsel(KyFloat32 cmp, KyFloat32 v1, KyFloat32 v2)
51 {
52  return (KyFloat32)__fsel(cmp, v1, v2);
53 }
54 
55 //-------------------------------------
56 #else
57 KY_INLINE KyFloat32 Fsel(KyFloat32 cmp, KyFloat32 v1, KyFloat32 v2)
59 {
60  return cmp >= 0.0f ? v1 : v2;
61 }
62 
63 #endif
64 
65 
66 //----------------------------------------------------------------------------------------
67 // Isel Lsel
68 
70 KY_INLINE KyInt32 Isel(KyInt32 a, KyInt32 x, KyInt32 y)
71 {
72  // C++ arithmetic-shift operator >> with signed int preserve the sing
73  // thus, this first bit (0 if positive, 1 if negative) is duplicated
74  // signMask becomes 0xFFFFFFFF if (a < 0) and 0x00000000 if (a >= 0)
75  const KyInt32 signMask = a >> 31;
76  return x + ((y - x) & signMask);
77 };
78 
80 KY_INLINE KyInt64 Lsel(KyInt64 a, KyInt64 x, KyInt64 y)
81 {
82  // C++ arithmetic-shift operator >> with signed int preserve the sing
83  // thus, this first bit (0 if positive, 1 if negative) is duplicated
84  // signMask becomes 0xFFFFFFFF if (a < 0) and 0x00000000 if (a >= 0)
85  const KyInt64 signMask = a >> 63;
86  return x + ((y - x) & signMask);
87 };
88 
89 
90 //---------------------------------------------------------------------------------------
91 // Sel
92 
93 template <class T>
94 T Sel(T cmp, T v1, T v2);
95 
96 template <>
97 KY_INLINE KyInt64 Sel<KyInt64>(KyInt64 a, KyInt64 x, KyInt64 y) { return Lsel(a, x, y); }
98 
99 template <>
100 KY_INLINE KyInt32 Sel<KyInt32>(KyInt32 a, KyInt32 x, KyInt32 y) { return Isel(a, x, y); }
101 
102 template <>
103 KY_INLINE KyFloat32 Sel<KyFloat32>(KyFloat32 a, KyFloat32 x, KyFloat32 y) { return Fsel(a, x, y); }
104 
105 
106 
107 //----------------------------------------------------------------------------------------
108 // Min / Max
109 
112 template<typename T>
113 KY_INLINE T Min(const T& a, const T& b)
114 {
115  return (a < b) ? a : b;
116 }
117 
120 template<typename T>
121 KY_INLINE T Max(const T& a, const T& b)
122 {
123  return (a < b) ? b : a;
124 }
125 
128 template <typename T>
129 KY_INLINE T Min(const T& a, const T& b, const T& c)
130 {
131  return Min(Min(a, b), c);
132 }
133 
136 template <typename T>
137 KY_INLINE T Max(const T& a, const T& b, const T& c)
138 {
139  return Max(Max(a, b), c);
140 }
141 
142 //---------------------------------------------------------------------
143 // Fsel specialization for floats
144 #if defined(KY_OS_XBOX360) || defined(KY_OS_PS3) || defined(KY_OS_WII)
145 
146 template<>
147 KY_INLINE KyFloat32 Min(const KyFloat32& a, const KyFloat32& b)
148 {
149  return Fsel(a - b, b, a);
150 }
151 
152 template<>
153 KY_INLINE KyFloat32 Max(const KyFloat32& a, const KyFloat32& b)
154 {
155  return Fsel(a - b, a, b);
156 }
157 
158 #endif
159 //---------------------------------------------------------------------
160 
161 // WARNING : Can overflow
162 KY_INLINE KyInt32 FastMin(const KyInt32& a, const KyInt32& b)
163 {
164  return Isel(a - b, b, a);
165 }
166 
167 // WARNING : Can overflow
168 KY_INLINE KyInt32 FastMax(const KyInt32& a, const KyInt32& b)
169 {
170  return Isel(a - b, a, b);
171 }
172 
173 // WARNING : Can overflow
174 KY_INLINE KyInt64 FastMin(const KyInt64& a, const KyInt64& b)
175 {
176  return Lsel(a - b, b, a);
177 }
178 
179 // WARNING : Can overflow
180 KY_INLINE KyInt64 FastMax(const KyInt64& a, const KyInt64& b)
181 {
182  return Lsel(a - b, a, b);
183 }
184 
185 // WARNING : Can overflow
186 KY_INLINE KyUInt32 FastDivisionBy3(KyUInt32 i)
187 {
188  return (i * 0x0000AAAB) >> 17;
189 }
190 
191 // WARNING : Can overflow
192 KY_INLINE KyUInt32 FastModuloBy3(KyUInt32 i)
193 {
194  return i - 3 * FastDivisionBy3(i);
195 }
196 
197 // remove this function and replace it with template<class T> struct OperatorLess
198 template <typename T1, typename T2 = T1>
199 class DefaultLess
200 {
201 public:
202  KY_INLINE bool operator()(const T1& lhs, const T2& rhs) const { return lhs < rhs; }
203 };
204 
205 
206 
207 //----------------------------------------------------------------------------------------
208 // Float32 to signed int32
209 
210 KY_INLINE KyInt32 NearestInt(KyFloat32 x)
211 {
212  return (KyInt32)(x + Kaim::Fsel(x, 0.5f, -0.5f));
213 }
214 
215 // LowerInt( 1.0f) = 1
216 // LowerInt(-1.0f) = -1
217 KY_INLINE KyInt32 LowerInt(KyFloat32 x)
218 {
219  return (KyInt32)(floorf(x));
220 }
221 
222 // FastLowerInt( 1.0f) = 1
223 // FastLowerInt(-1.0f) = -2 !!
224 KY_INLINE KyInt32 FastLowerInt(KyFloat32 x)
225 {
226  return (KyInt32)(x + Kaim::Fsel(x, 0.0f, -1.0f));
227 }
228 
229 // UpperInt( 1.0f) = 1
230 // UpperInt(-1.0f) = -1
231 KY_INLINE KyInt32 UpperInt(KyFloat32 x)
232 {
233  return (KyInt32)(ceilf(x));
234 }
235 
236 KY_INLINE KyFloat32 Acosf(KyFloat32 input)
237 {
238  // Cap the input to [-1.0, 1.0] to be robust to float precision errors and to avoid returning a NaN
239  const KyFloat32 normalizeDotProd = Kaim::Min(1.f, Kaim::Max(-1.f, input));
240  return acosf(normalizeDotProd);
241 }
242 
243 KY_INLINE KyFloat32 Sqrtf(KyFloat32 input)
244 {
245  return sqrtf(input);
246 }
247 
248 KY_INLINE KyFloat32 Cosf(KyFloat32 angleRad)
249 {
250  return cosf(angleRad);
251 }
252 
253 KY_INLINE KyFloat32 Sinf(KyFloat32 angleRad)
254 {
255  return sinf(angleRad);
256 }
257 
258 //KY_INLINE KyFloat32 Asinf(KyFloat32 input)
259 //{
260 // // Cap the input to [-1.0, 1.0] to be robust to float precision errors and to avoid returning a NaN
261 // const KyFloat32 normalizeDotProd = Kaim::Min(1.f, Kaim::Max(-1.f, input));
262 // return asinf(normalizeDotProd);
263 //}
264 
265 }
266 
267 
268 #endif
KyInt32 Isel(KyInt32 a, KyInt32 x, KyInt32 y)
If a is greater than 0, returns x. Otherwise, returns y.
Definition: fastmath.h:70
int KyInt32
Type used internally to represent a 32-bit integer.
Definition: types.h:35
T Min(const T &a, const T &b)
Returns the lesser of the two specified values.
Definition: fastmath.h:113
T Max(const T &a, const T &b)
Returns the greater of the two specified values.
Definition: fastmath.h:121
Definition: gamekitcrowddispersion.h:20
unsigned int KyUInt32
Type used internally to represent an unsigned 32-bit integer.
Definition: types.h:36
__int64 KyInt64
Type used internally to represent a 64-bit integer.
Definition: types.h:37
float KyFloat32
Type used internally to represent a 32-bit floating-point number.
Definition: types.h:43
KyFloat32 Fsel(KyFloat32 cmp, KyFloat32 v1, KyFloat32 v2)
Ifcmp is greater than 0, returnsv1. Otherwise, returnsv2.
Definition: fastmath.h:58
KyInt64 Lsel(KyInt64 a, KyInt64 x, KyInt64 y)
If a is greater than 0, returns x. Otherwise, returns y.
Definition: fastmath.h:80