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