diff options
author | David Walter Seikel | 2014-01-13 19:47:58 +1000 |
---|---|---|
committer | David Walter Seikel | 2014-01-13 19:47:58 +1000 |
commit | f9158592e1478b2013afc7041d9ed041cf2d2f4a (patch) | |
tree | b16e389d7988700e21b4c9741044cefa536dcbae /libraries/irrlicht-1.8.1/include/irrMath.h | |
parent | Libraries readme updated with change markers and more of the Irrlicht changes. (diff) | |
download | SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.zip SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.gz SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.bz2 SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.xz |
Update Irrlicht to 1.8.1. Include actual change markers this time. lol
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8.1/include/irrMath.h | 732 |
1 files changed, 732 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8.1/include/irrMath.h b/libraries/irrlicht-1.8.1/include/irrMath.h new file mode 100644 index 0000000..3852932 --- /dev/null +++ b/libraries/irrlicht-1.8.1/include/irrMath.h | |||
@@ -0,0 +1,732 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | ||
2 | // This file is part of the "Irrlicht Engine". | ||
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | ||
4 | |||
5 | #ifndef __IRR_MATH_H_INCLUDED__ | ||
6 | #define __IRR_MATH_H_INCLUDED__ | ||
7 | |||
8 | #include "IrrCompileConfig.h" | ||
9 | #include "irrTypes.h" | ||
10 | #include <math.h> | ||
11 | #include <float.h> | ||
12 | #include <stdlib.h> // for abs() etc. | ||
13 | #include <limits.h> // For INT_MAX / UINT_MAX | ||
14 | |||
15 | #if defined(_IRR_SOLARIS_PLATFORM_) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) || defined (_WIN32_WCE) | ||
16 | #define sqrtf(X) (irr::f32)sqrt((irr::f64)(X)) | ||
17 | #define sinf(X) (irr::f32)sin((irr::f64)(X)) | ||
18 | #define cosf(X) (irr::f32)cos((irr::f64)(X)) | ||
19 | #define asinf(X) (irr::f32)asin((irr::f64)(X)) | ||
20 | #define acosf(X) (irr::f32)acos((irr::f64)(X)) | ||
21 | #define atan2f(X,Y) (irr::f32)atan2((irr::f64)(X),(irr::f64)(Y)) | ||
22 | #define ceilf(X) (irr::f32)ceil((irr::f64)(X)) | ||
23 | #define floorf(X) (irr::f32)floor((irr::f64)(X)) | ||
24 | #define powf(X,Y) (irr::f32)pow((irr::f64)(X),(irr::f64)(Y)) | ||
25 | #define fmodf(X,Y) (irr::f32)fmod((irr::f64)(X),(irr::f64)(Y)) | ||
26 | #define fabsf(X) (irr::f32)fabs((irr::f64)(X)) | ||
27 | #define logf(X) (irr::f32)log((irr::f64)(X)) | ||
28 | #endif | ||
29 | |||
30 | #ifndef FLT_MAX | ||
31 | #define FLT_MAX 3.402823466E+38F | ||
32 | #endif | ||
33 | |||
34 | #ifndef FLT_MIN | ||
35 | #define FLT_MIN 1.17549435e-38F | ||
36 | #endif | ||
37 | |||
38 | namespace irr | ||
39 | { | ||
40 | namespace core | ||
41 | { | ||
42 | |||
43 | //! Rounding error constant often used when comparing f32 values. | ||
44 | |||
45 | const s32 ROUNDING_ERROR_S32 = 0; | ||
46 | #ifdef __IRR_HAS_S64 | ||
47 | const s64 ROUNDING_ERROR_S64 = 0; | ||
48 | #endif | ||
49 | const f32 ROUNDING_ERROR_f32 = 0.000001f; | ||
50 | const f64 ROUNDING_ERROR_f64 = 0.00000001; | ||
51 | |||
52 | #ifdef PI // make sure we don't collide with a define | ||
53 | #undef PI | ||
54 | #endif | ||
55 | //! Constant for PI. | ||
56 | const f32 PI = 3.14159265359f; | ||
57 | |||
58 | //! Constant for reciprocal of PI. | ||
59 | const f32 RECIPROCAL_PI = 1.0f/PI; | ||
60 | |||
61 | //! Constant for half of PI. | ||
62 | const f32 HALF_PI = PI/2.0f; | ||
63 | |||
64 | #ifdef PI64 // make sure we don't collide with a define | ||
65 | #undef PI64 | ||
66 | #endif | ||
67 | //! Constant for 64bit PI. | ||
68 | const f64 PI64 = 3.1415926535897932384626433832795028841971693993751; | ||
69 | |||
70 | //! Constant for 64bit reciprocal of PI. | ||
71 | const f64 RECIPROCAL_PI64 = 1.0/PI64; | ||
72 | |||
73 | //! 32bit Constant for converting from degrees to radians | ||
74 | const f32 DEGTORAD = PI / 180.0f; | ||
75 | |||
76 | //! 32bit constant for converting from radians to degrees (formally known as GRAD_PI) | ||
77 | const f32 RADTODEG = 180.0f / PI; | ||
78 | |||
79 | //! 64bit constant for converting from degrees to radians (formally known as GRAD_PI2) | ||
80 | const f64 DEGTORAD64 = PI64 / 180.0; | ||
81 | |||
82 | //! 64bit constant for converting from radians to degrees | ||
83 | const f64 RADTODEG64 = 180.0 / PI64; | ||
84 | |||
85 | //! Utility function to convert a radian value to degrees | ||
86 | /** Provided as it can be clearer to write radToDeg(X) than RADTODEG * X | ||
87 | \param radians The radians value to convert to degrees. | ||
88 | */ | ||
89 | inline f32 radToDeg(f32 radians) | ||
90 | { | ||
91 | return RADTODEG * radians; | ||
92 | } | ||
93 | |||
94 | //! Utility function to convert a radian value to degrees | ||
95 | /** Provided as it can be clearer to write radToDeg(X) than RADTODEG * X | ||
96 | \param radians The radians value to convert to degrees. | ||
97 | */ | ||
98 | inline f64 radToDeg(f64 radians) | ||
99 | { | ||
100 | return RADTODEG64 * radians; | ||
101 | } | ||
102 | |||
103 | //! Utility function to convert a degrees value to radians | ||
104 | /** Provided as it can be clearer to write degToRad(X) than DEGTORAD * X | ||
105 | \param degrees The degrees value to convert to radians. | ||
106 | */ | ||
107 | inline f32 degToRad(f32 degrees) | ||
108 | { | ||
109 | return DEGTORAD * degrees; | ||
110 | } | ||
111 | |||
112 | //! Utility function to convert a degrees value to radians | ||
113 | /** Provided as it can be clearer to write degToRad(X) than DEGTORAD * X | ||
114 | \param degrees The degrees value to convert to radians. | ||
115 | */ | ||
116 | inline f64 degToRad(f64 degrees) | ||
117 | { | ||
118 | return DEGTORAD64 * degrees; | ||
119 | } | ||
120 | |||
121 | //! returns minimum of two values. Own implementation to get rid of the STL (VS6 problems) | ||
122 | template<class T> | ||
123 | inline const T& min_(const T& a, const T& b) | ||
124 | { | ||
125 | return a < b ? a : b; | ||
126 | } | ||
127 | |||
128 | //! returns minimum of three values. Own implementation to get rid of the STL (VS6 problems) | ||
129 | template<class T> | ||
130 | inline const T& min_(const T& a, const T& b, const T& c) | ||
131 | { | ||
132 | return a < b ? min_(a, c) : min_(b, c); | ||
133 | } | ||
134 | |||
135 | //! returns maximum of two values. Own implementation to get rid of the STL (VS6 problems) | ||
136 | template<class T> | ||
137 | inline const T& max_(const T& a, const T& b) | ||
138 | { | ||
139 | return a < b ? b : a; | ||
140 | } | ||
141 | |||
142 | //! returns maximum of three values. Own implementation to get rid of the STL (VS6 problems) | ||
143 | template<class T> | ||
144 | inline const T& max_(const T& a, const T& b, const T& c) | ||
145 | { | ||
146 | return a < b ? max_(b, c) : max_(a, c); | ||
147 | } | ||
148 | |||
149 | //! returns abs of two values. Own implementation to get rid of STL (VS6 problems) | ||
150 | template<class T> | ||
151 | inline T abs_(const T& a) | ||
152 | { | ||
153 | return a < (T)0 ? -a : a; | ||
154 | } | ||
155 | |||
156 | //! returns linear interpolation of a and b with ratio t | ||
157 | //! \return: a if t==0, b if t==1, and the linear interpolation else | ||
158 | template<class T> | ||
159 | inline T lerp(const T& a, const T& b, const f32 t) | ||
160 | { | ||
161 | return (T)(a*(1.f-t)) + (b*t); | ||
162 | } | ||
163 | |||
164 | //! clamps a value between low and high | ||
165 | template <class T> | ||
166 | inline const T clamp (const T& value, const T& low, const T& high) | ||
167 | { | ||
168 | return min_ (max_(value,low), high); | ||
169 | } | ||
170 | |||
171 | //! swaps the content of the passed parameters | ||
172 | // Note: We use the same trick as boost and use two template arguments to | ||
173 | // avoid ambiguity when swapping objects of an Irrlicht type that has not | ||
174 | // it's own swap overload. Otherwise we get conflicts with some compilers | ||
175 | // in combination with stl. | ||
176 | template <class T1, class T2> | ||
177 | inline void swap(T1& a, T2& b) | ||
178 | { | ||
179 | T1 c(a); | ||
180 | a = b; | ||
181 | b = c; | ||
182 | } | ||
183 | |||
184 | //! returns if a equals b, taking possible rounding errors into account | ||
185 | inline bool equals(const f64 a, const f64 b, const f64 tolerance = ROUNDING_ERROR_f64) | ||
186 | { | ||
187 | return (a + tolerance >= b) && (a - tolerance <= b); | ||
188 | } | ||
189 | |||
190 | //! returns if a equals b, taking possible rounding errors into account | ||
191 | inline bool equals(const f32 a, const f32 b, const f32 tolerance = ROUNDING_ERROR_f32) | ||
192 | { | ||
193 | return (a + tolerance >= b) && (a - tolerance <= b); | ||
194 | } | ||
195 | |||
196 | union FloatIntUnion32 | ||
197 | { | ||
198 | FloatIntUnion32(float f1 = 0.0f) : f(f1) {} | ||
199 | // Portable sign-extraction | ||
200 | bool sign() const { return (i >> 31) != 0; } | ||
201 | |||
202 | irr::s32 i; | ||
203 | irr::f32 f; | ||
204 | }; | ||
205 | |||
206 | //! We compare the difference in ULP's (spacing between floating-point numbers, aka ULP=1 means there exists no float between). | ||
207 | //\result true when numbers have a ULP <= maxUlpDiff AND have the same sign. | ||
208 | inline bool equalsByUlp(f32 a, f32 b, int maxUlpDiff) | ||
209 | { | ||
210 | // Based on the ideas and code from Bruce Dawson on | ||
211 | // http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/ | ||
212 | // When floats are interpreted as integers the two nearest possible float numbers differ just | ||
213 | // by one integer number. Also works the other way round, an integer of 1 interpreted as float | ||
214 | // is for example the smallest possible float number. | ||
215 | |||
216 | FloatIntUnion32 fa(a); | ||
217 | FloatIntUnion32 fb(b); | ||
218 | |||
219 | // Different signs, we could maybe get difference to 0, but so close to 0 using epsilons is better. | ||
220 | if ( fa.sign() != fb.sign() ) | ||
221 | { | ||
222 | // Check for equality to make sure +0==-0 | ||
223 | if (fa.i == fb.i) | ||
224 | return true; | ||
225 | return false; | ||
226 | } | ||
227 | |||
228 | // Find the difference in ULPs. | ||
229 | int ulpsDiff = abs_(fa.i- fb.i); | ||
230 | if (ulpsDiff <= maxUlpDiff) | ||
231 | return true; | ||
232 | |||
233 | return false; | ||
234 | } | ||
235 | |||
236 | #if 0 | ||
237 | //! returns if a equals b, not using any rounding tolerance | ||
238 | inline bool equals(const s32 a, const s32 b) | ||
239 | { | ||
240 | return (a == b); | ||
241 | } | ||
242 | |||
243 | //! returns if a equals b, not using any rounding tolerance | ||
244 | inline bool equals(const u32 a, const u32 b) | ||
245 | { | ||
246 | return (a == b); | ||
247 | } | ||
248 | #endif | ||
249 | //! returns if a equals b, taking an explicit rounding tolerance into account | ||
250 | inline bool equals(const s32 a, const s32 b, const s32 tolerance = ROUNDING_ERROR_S32) | ||
251 | { | ||
252 | return (a + tolerance >= b) && (a - tolerance <= b); | ||
253 | } | ||
254 | |||
255 | //! returns if a equals b, taking an explicit rounding tolerance into account | ||
256 | inline bool equals(const u32 a, const u32 b, const s32 tolerance = ROUNDING_ERROR_S32) | ||
257 | { | ||
258 | return (a + tolerance >= b) && (a - tolerance <= b); | ||
259 | } | ||
260 | |||
261 | #ifdef __IRR_HAS_S64 | ||
262 | //! returns if a equals b, taking an explicit rounding tolerance into account | ||
263 | inline bool equals(const s64 a, const s64 b, const s64 tolerance = ROUNDING_ERROR_S64) | ||
264 | { | ||
265 | return (a + tolerance >= b) && (a - tolerance <= b); | ||
266 | } | ||
267 | #endif | ||
268 | |||
269 | //! returns if a equals zero, taking rounding errors into account | ||
270 | inline bool iszero(const f64 a, const f64 tolerance = ROUNDING_ERROR_f64) | ||
271 | { | ||
272 | return fabs(a) <= tolerance; | ||
273 | } | ||
274 | |||
275 | //! returns if a equals zero, taking rounding errors into account | ||
276 | inline bool iszero(const f32 a, const f32 tolerance = ROUNDING_ERROR_f32) | ||
277 | { | ||
278 | return fabsf(a) <= tolerance; | ||
279 | } | ||
280 | |||
281 | //! returns if a equals not zero, taking rounding errors into account | ||
282 | inline bool isnotzero(const f32 a, const f32 tolerance = ROUNDING_ERROR_f32) | ||
283 | { | ||
284 | return fabsf(a) > tolerance; | ||
285 | } | ||
286 | |||
287 | //! returns if a equals zero, taking rounding errors into account | ||
288 | inline bool iszero(const s32 a, const s32 tolerance = 0) | ||
289 | { | ||
290 | return ( a & 0x7ffffff ) <= tolerance; | ||
291 | } | ||
292 | |||
293 | //! returns if a equals zero, taking rounding errors into account | ||
294 | inline bool iszero(const u32 a, const u32 tolerance = 0) | ||
295 | { | ||
296 | return a <= tolerance; | ||
297 | } | ||
298 | |||
299 | #ifdef __IRR_HAS_S64 | ||
300 | //! returns if a equals zero, taking rounding errors into account | ||
301 | inline bool iszero(const s64 a, const s64 tolerance = 0) | ||
302 | { | ||
303 | return abs_(a) <= tolerance; | ||
304 | } | ||
305 | #endif | ||
306 | |||
307 | inline s32 s32_min(s32 a, s32 b) | ||
308 | { | ||
309 | const s32 mask = (a - b) >> 31; | ||
310 | return (a & mask) | (b & ~mask); | ||
311 | } | ||
312 | |||
313 | inline s32 s32_max(s32 a, s32 b) | ||
314 | { | ||
315 | const s32 mask = (a - b) >> 31; | ||
316 | return (b & mask) | (a & ~mask); | ||
317 | } | ||
318 | |||
319 | inline s32 s32_clamp (s32 value, s32 low, s32 high) | ||
320 | { | ||
321 | return s32_min(s32_max(value,low), high); | ||
322 | } | ||
323 | |||
324 | /* | ||
325 | float IEEE-754 bit represenation | ||
326 | |||
327 | 0 0x00000000 | ||
328 | 1.0 0x3f800000 | ||
329 | 0.5 0x3f000000 | ||
330 | 3 0x40400000 | ||
331 | +inf 0x7f800000 | ||
332 | -inf 0xff800000 | ||
333 | +NaN 0x7fc00000 or 0x7ff00000 | ||
334 | in general: number = (sign ? -1:1) * 2^(exponent) * 1.(mantissa bits) | ||
335 | */ | ||
336 | |||
337 | typedef union { u32 u; s32 s; f32 f; } inttofloat; | ||
338 | |||
339 | #define F32_AS_S32(f) (*((s32 *) &(f))) | ||
340 | #define F32_AS_U32(f) (*((u32 *) &(f))) | ||
341 | #define F32_AS_U32_POINTER(f) ( ((u32 *) &(f))) | ||
342 | |||
343 | #define F32_VALUE_0 0x00000000 | ||
344 | #define F32_VALUE_1 0x3f800000 | ||
345 | #define F32_SIGN_BIT 0x80000000U | ||
346 | #define F32_EXPON_MANTISSA 0x7FFFFFFFU | ||
347 | |||
348 | //! code is taken from IceFPU | ||
349 | //! Integer representation of a floating-point value. | ||
350 | #ifdef IRRLICHT_FAST_MATH | ||
351 | #define IR(x) ((u32&)(x)) | ||
352 | #else | ||
353 | inline u32 IR(f32 x) {inttofloat tmp; tmp.f=x; return tmp.u;} | ||
354 | #endif | ||
355 | |||
356 | //! Absolute integer representation of a floating-point value | ||
357 | #define AIR(x) (IR(x)&0x7fffffff) | ||
358 | |||
359 | //! Floating-point representation of an integer value. | ||
360 | #ifdef IRRLICHT_FAST_MATH | ||
361 | #define FR(x) ((f32&)(x)) | ||
362 | #else | ||
363 | inline f32 FR(u32 x) {inttofloat tmp; tmp.u=x; return tmp.f;} | ||
364 | inline f32 FR(s32 x) {inttofloat tmp; tmp.s=x; return tmp.f;} | ||
365 | #endif | ||
366 | |||
367 | //! integer representation of 1.0 | ||
368 | #define IEEE_1_0 0x3f800000 | ||
369 | //! integer representation of 255.0 | ||
370 | #define IEEE_255_0 0x437f0000 | ||
371 | |||
372 | #ifdef IRRLICHT_FAST_MATH | ||
373 | #define F32_LOWER_0(f) (F32_AS_U32(f) > F32_SIGN_BIT) | ||
374 | #define F32_LOWER_EQUAL_0(f) (F32_AS_S32(f) <= F32_VALUE_0) | ||
375 | #define F32_GREATER_0(f) (F32_AS_S32(f) > F32_VALUE_0) | ||
376 | #define F32_GREATER_EQUAL_0(f) (F32_AS_U32(f) <= F32_SIGN_BIT) | ||
377 | #define F32_EQUAL_1(f) (F32_AS_U32(f) == F32_VALUE_1) | ||
378 | #define F32_EQUAL_0(f) ( (F32_AS_U32(f) & F32_EXPON_MANTISSA ) == F32_VALUE_0) | ||
379 | |||
380 | // only same sign | ||
381 | #define F32_A_GREATER_B(a,b) (F32_AS_S32((a)) > F32_AS_S32((b))) | ||
382 | |||
383 | #else | ||
384 | |||
385 | #define F32_LOWER_0(n) ((n) < 0.0f) | ||
386 | #define F32_LOWER_EQUAL_0(n) ((n) <= 0.0f) | ||
387 | #define F32_GREATER_0(n) ((n) > 0.0f) | ||
388 | #define F32_GREATER_EQUAL_0(n) ((n) >= 0.0f) | ||
389 | #define F32_EQUAL_1(n) ((n) == 1.0f) | ||
390 | #define F32_EQUAL_0(n) ((n) == 0.0f) | ||
391 | #define F32_A_GREATER_B(a,b) ((a) > (b)) | ||
392 | #endif | ||
393 | |||
394 | |||
395 | #ifndef REALINLINE | ||
396 | #ifdef _MSC_VER | ||
397 | #define REALINLINE __forceinline | ||
398 | #else | ||
399 | #define REALINLINE inline | ||
400 | #endif | ||
401 | #endif | ||
402 | |||
403 | #if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) | ||
404 | |||
405 | // 8-bit bools in borland builder | ||
406 | |||
407 | //! conditional set based on mask and arithmetic shift | ||
408 | REALINLINE u32 if_c_a_else_b ( const c8 condition, const u32 a, const u32 b ) | ||
409 | { | ||
410 | return ( ( -condition >> 7 ) & ( a ^ b ) ) ^ b; | ||
411 | } | ||
412 | |||
413 | //! conditional set based on mask and arithmetic shift | ||
414 | REALINLINE u32 if_c_a_else_0 ( const c8 condition, const u32 a ) | ||
415 | { | ||
416 | return ( -condition >> 31 ) & a; | ||
417 | } | ||
418 | #else | ||
419 | |||
420 | //! conditional set based on mask and arithmetic shift | ||
421 | REALINLINE u32 if_c_a_else_b ( const s32 condition, const u32 a, const u32 b ) | ||
422 | { | ||
423 | return ( ( -condition >> 31 ) & ( a ^ b ) ) ^ b; | ||
424 | } | ||
425 | |||
426 | //! conditional set based on mask and arithmetic shift | ||
427 | REALINLINE u16 if_c_a_else_b ( const s16 condition, const u16 a, const u16 b ) | ||
428 | { | ||
429 | return ( ( -condition >> 15 ) & ( a ^ b ) ) ^ b; | ||
430 | } | ||
431 | |||
432 | //! conditional set based on mask and arithmetic shift | ||
433 | REALINLINE u32 if_c_a_else_0 ( const s32 condition, const u32 a ) | ||
434 | { | ||
435 | return ( -condition >> 31 ) & a; | ||
436 | } | ||
437 | #endif | ||
438 | |||
439 | /* | ||
440 | if (condition) state |= m; else state &= ~m; | ||
441 | */ | ||
442 | REALINLINE void setbit_cond ( u32 &state, s32 condition, u32 mask ) | ||
443 | { | ||
444 | // 0, or any postive to mask | ||
445 | //s32 conmask = -condition >> 31; | ||
446 | state ^= ( ( -condition >> 31 ) ^ state ) & mask; | ||
447 | } | ||
448 | |||
449 | inline f32 round_( f32 x ) | ||
450 | { | ||
451 | return floorf( x + 0.5f ); | ||
452 | } | ||
453 | |||
454 | REALINLINE void clearFPUException () | ||
455 | { | ||
456 | #ifdef IRRLICHT_FAST_MATH | ||
457 | return; | ||
458 | #ifdef feclearexcept | ||
459 | feclearexcept(FE_ALL_EXCEPT); | ||
460 | #elif defined(_MSC_VER) | ||
461 | __asm fnclex; | ||
462 | #elif defined(__GNUC__) && defined(__x86__) | ||
463 | __asm__ __volatile__ ("fclex \n\t"); | ||
464 | #else | ||
465 | # warn clearFPUException not supported. | ||
466 | #endif | ||
467 | #endif | ||
468 | } | ||
469 | |||
470 | // calculate: sqrt ( x ) | ||
471 | REALINLINE f32 squareroot(const f32 f) | ||
472 | { | ||
473 | return sqrtf(f); | ||
474 | } | ||
475 | |||
476 | // calculate: sqrt ( x ) | ||
477 | REALINLINE f64 squareroot(const f64 f) | ||
478 | { | ||
479 | return sqrt(f); | ||
480 | } | ||
481 | |||
482 | // calculate: sqrt ( x ) | ||
483 | REALINLINE s32 squareroot(const s32 f) | ||
484 | { | ||
485 | return static_cast<s32>(squareroot(static_cast<f32>(f))); | ||
486 | } | ||
487 | |||
488 | #ifdef __IRR_HAS_S64 | ||
489 | // calculate: sqrt ( x ) | ||
490 | REALINLINE s64 squareroot(const s64 f) | ||
491 | { | ||
492 | return static_cast<s64>(squareroot(static_cast<f64>(f))); | ||
493 | } | ||
494 | #endif | ||
495 | |||
496 | // calculate: 1 / sqrt ( x ) | ||
497 | REALINLINE f64 reciprocal_squareroot(const f64 x) | ||
498 | { | ||
499 | return 1.0 / sqrt(x); | ||
500 | } | ||
501 | |||
502 | // calculate: 1 / sqrtf ( x ) | ||
503 | REALINLINE f32 reciprocal_squareroot(const f32 f) | ||
504 | { | ||
505 | #if defined ( IRRLICHT_FAST_MATH ) | ||
506 | #if defined(_MSC_VER) | ||
507 | // SSE reciprocal square root estimate, accurate to 12 significant | ||
508 | // bits of the mantissa | ||
509 | f32 recsqrt; | ||
510 | __asm rsqrtss xmm0, f // xmm0 = rsqrtss(f) | ||
511 | __asm movss recsqrt, xmm0 // return xmm0 | ||
512 | return recsqrt; | ||
513 | |||
514 | /* | ||
515 | // comes from Nvidia | ||
516 | u32 tmp = (u32(IEEE_1_0 << 1) + IEEE_1_0 - *(u32*)&x) >> 1; | ||
517 | f32 y = *(f32*)&tmp; | ||
518 | return y * (1.47f - 0.47f * x * y * y); | ||
519 | */ | ||
520 | #else | ||
521 | return 1.f / sqrtf(f); | ||
522 | #endif | ||
523 | #else // no fast math | ||
524 | return 1.f / sqrtf(f); | ||
525 | #endif | ||
526 | } | ||
527 | |||
528 | // calculate: 1 / sqrtf( x ) | ||
529 | REALINLINE s32 reciprocal_squareroot(const s32 x) | ||
530 | { | ||
531 | return static_cast<s32>(reciprocal_squareroot(static_cast<f32>(x))); | ||
532 | } | ||
533 | |||
534 | // calculate: 1 / x | ||
535 | REALINLINE f32 reciprocal( const f32 f ) | ||
536 | { | ||
537 | #if defined (IRRLICHT_FAST_MATH) | ||
538 | |||
539 | // SSE Newton-Raphson reciprocal estimate, accurate to 23 significant | ||
540 | // bi ts of the mantissa | ||
541 | // One Newtown-Raphson Iteration: | ||
542 | // f(i+1) = 2 * rcpss(f) - f * rcpss(f) * rcpss(f) | ||
543 | f32 rec; | ||
544 | __asm rcpss xmm0, f // xmm0 = rcpss(f) | ||
545 | __asm movss xmm1, f // xmm1 = f | ||
546 | __asm mulss xmm1, xmm0 // xmm1 = f * rcpss(f) | ||
547 | __asm mulss xmm1, xmm0 // xmm2 = f * rcpss(f) * rcpss(f) | ||
548 | __asm addss xmm0, xmm0 // xmm0 = 2 * rcpss(f) | ||
549 | __asm subss xmm0, xmm1 // xmm0 = 2 * rcpss(f) | ||
550 | // - f * rcpss(f) * rcpss(f) | ||
551 | __asm movss rec, xmm0 // return xmm0 | ||
552 | return rec; | ||
553 | |||
554 | |||
555 | //! i do not divide through 0.. (fpu expection) | ||
556 | // instead set f to a high value to get a return value near zero.. | ||
557 | // -1000000000000.f.. is use minus to stay negative.. | ||
558 | // must test's here (plane.normal dot anything ) checks on <= 0.f | ||
559 | //u32 x = (-(AIR(f) != 0 ) >> 31 ) & ( IR(f) ^ 0xd368d4a5 ) ^ 0xd368d4a5; | ||
560 | //return 1.f / FR ( x ); | ||
561 | |||
562 | #else // no fast math | ||
563 | return 1.f / f; | ||
564 | #endif | ||
565 | } | ||
566 | |||
567 | // calculate: 1 / x | ||
568 | REALINLINE f64 reciprocal ( const f64 f ) | ||
569 | { | ||
570 | return 1.0 / f; | ||
571 | } | ||
572 | |||
573 | |||
574 | // calculate: 1 / x, low precision allowed | ||
575 | REALINLINE f32 reciprocal_approxim ( const f32 f ) | ||
576 | { | ||
577 | #if defined( IRRLICHT_FAST_MATH) | ||
578 | |||
579 | // SSE Newton-Raphson reciprocal estimate, accurate to 23 significant | ||
580 | // bi ts of the mantissa | ||
581 | // One Newtown-Raphson Iteration: | ||
582 | // f(i+1) = 2 * rcpss(f) - f * rcpss(f) * rcpss(f) | ||
583 | f32 rec; | ||
584 | __asm rcpss xmm0, f // xmm0 = rcpss(f) | ||
585 | __asm movss xmm1, f // xmm1 = f | ||
586 | __asm mulss xmm1, xmm0 // xmm1 = f * rcpss(f) | ||
587 | __asm mulss xmm1, xmm0 // xmm2 = f * rcpss(f) * rcpss(f) | ||
588 | __asm addss xmm0, xmm0 // xmm0 = 2 * rcpss(f) | ||
589 | __asm subss xmm0, xmm1 // xmm0 = 2 * rcpss(f) | ||
590 | // - f * rcpss(f) * rcpss(f) | ||
591 | __asm movss rec, xmm0 // return xmm0 | ||
592 | return rec; | ||
593 | |||
594 | |||
595 | /* | ||
596 | // SSE reciprocal estimate, accurate to 12 significant bits of | ||
597 | f32 rec; | ||
598 | __asm rcpss xmm0, f // xmm0 = rcpss(f) | ||
599 | __asm movss rec , xmm0 // return xmm0 | ||
600 | return rec; | ||
601 | */ | ||
602 | /* | ||
603 | register u32 x = 0x7F000000 - IR ( p ); | ||
604 | const f32 r = FR ( x ); | ||
605 | return r * (2.0f - p * r); | ||
606 | */ | ||
607 | #else // no fast math | ||
608 | return 1.f / f; | ||
609 | #endif | ||
610 | } | ||
611 | |||
612 | |||
613 | REALINLINE s32 floor32(f32 x) | ||
614 | { | ||
615 | #ifdef IRRLICHT_FAST_MATH | ||
616 | const f32 h = 0.5f; | ||
617 | |||
618 | s32 t; | ||
619 | |||
620 | #if defined(_MSC_VER) | ||
621 | __asm | ||
622 | { | ||
623 | fld x | ||
624 | fsub h | ||
625 | fistp t | ||
626 | } | ||
627 | #elif defined(__GNUC__) | ||
628 | __asm__ __volatile__ ( | ||
629 | "fsub %2 \n\t" | ||
630 | "fistpl %0" | ||
631 | : "=m" (t) | ||
632 | : "t" (x), "f" (h) | ||
633 | : "st" | ||
634 | ); | ||
635 | #else | ||
636 | # warn IRRLICHT_FAST_MATH not supported. | ||
637 | return (s32) floorf ( x ); | ||
638 | #endif | ||
639 | return t; | ||
640 | #else // no fast math | ||
641 | return (s32) floorf ( x ); | ||
642 | #endif | ||
643 | } | ||
644 | |||
645 | |||
646 | REALINLINE s32 ceil32 ( f32 x ) | ||
647 | { | ||
648 | #ifdef IRRLICHT_FAST_MATH | ||
649 | const f32 h = 0.5f; | ||
650 | |||
651 | s32 t; | ||
652 | |||
653 | #if defined(_MSC_VER) | ||
654 | __asm | ||
655 | { | ||
656 | fld x | ||
657 | fadd h | ||
658 | fistp t | ||
659 | } | ||
660 | #elif defined(__GNUC__) | ||
661 | __asm__ __volatile__ ( | ||
662 | "fadd %2 \n\t" | ||
663 | "fistpl %0 \n\t" | ||
664 | : "=m"(t) | ||
665 | : "t"(x), "f"(h) | ||
666 | : "st" | ||
667 | ); | ||
668 | #else | ||
669 | # warn IRRLICHT_FAST_MATH not supported. | ||
670 | return (s32) ceilf ( x ); | ||
671 | #endif | ||
672 | return t; | ||
673 | #else // not fast math | ||
674 | return (s32) ceilf ( x ); | ||
675 | #endif | ||
676 | } | ||
677 | |||
678 | |||
679 | |||
680 | REALINLINE s32 round32(f32 x) | ||
681 | { | ||
682 | #if defined(IRRLICHT_FAST_MATH) | ||
683 | s32 t; | ||
684 | |||
685 | #if defined(_MSC_VER) | ||
686 | __asm | ||
687 | { | ||
688 | fld x | ||
689 | fistp t | ||
690 | } | ||
691 | #elif defined(__GNUC__) | ||
692 | __asm__ __volatile__ ( | ||
693 | "fistpl %0 \n\t" | ||
694 | : "=m"(t) | ||
695 | : "t"(x) | ||
696 | : "st" | ||
697 | ); | ||
698 | #else | ||
699 | # warn IRRLICHT_FAST_MATH not supported. | ||
700 | return (s32) round_(x); | ||
701 | #endif | ||
702 | return t; | ||
703 | #else // no fast math | ||
704 | return (s32) round_(x); | ||
705 | #endif | ||
706 | } | ||
707 | |||
708 | inline f32 f32_max3(const f32 a, const f32 b, const f32 c) | ||
709 | { | ||
710 | return a > b ? (a > c ? a : c) : (b > c ? b : c); | ||
711 | } | ||
712 | |||
713 | inline f32 f32_min3(const f32 a, const f32 b, const f32 c) | ||
714 | { | ||
715 | return a < b ? (a < c ? a : c) : (b < c ? b : c); | ||
716 | } | ||
717 | |||
718 | inline f32 fract ( f32 x ) | ||
719 | { | ||
720 | return x - floorf ( x ); | ||
721 | } | ||
722 | |||
723 | } // end namespace core | ||
724 | } // end namespace irr | ||
725 | |||
726 | #ifndef IRRLICHT_FAST_MATH | ||
727 | using irr::core::IR; | ||
728 | using irr::core::FR; | ||
729 | #endif | ||
730 | |||
731 | #endif | ||
732 | |||