Panda3D
|
00001 // Filename: cmath.I 00002 // Created by: drose (19May00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifdef __APPLE__ 00016 #ifndef isnan 00017 #define isnan(x) \ 00018 ((sizeof(x) == sizeof(double)) ? \ 00019 __isnand(x) : \ 00020 (sizeof(x) == sizeof(float)) ? __isnanf(x) : __isnan(x)) 00021 #endif 00022 #endif 00023 00024 #ifdef __INTEL_COMPILER 00025 // see float.h 00026 #define FPU_CONTROLWORD_WRITEMASK 0xFFFFF // if you look at defn of _CW_DEFAULT, all settings fall within 0xFFFFF 00027 #define FPU_CONTROLWORD_NEW_SETTING _CW_DEFAULT 00028 #endif 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: csqrt 00032 // Description: 00033 //////////////////////////////////////////////////////////////////// 00034 INLINE float 00035 csqrt(float v) { 00036 return sqrtf(v); 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: csin 00041 // Description: 00042 //////////////////////////////////////////////////////////////////// 00043 INLINE float 00044 csin(float v) { 00045 return sinf(v); 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: ccos 00050 // Description: 00051 //////////////////////////////////////////////////////////////////// 00052 INLINE float 00053 ccos(float v) { 00054 return cosf(v); 00055 } 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: ctan 00059 // Description: 00060 //////////////////////////////////////////////////////////////////// 00061 INLINE float ctan(float v) { 00062 return tanf(v); 00063 } 00064 00065 //////////////////////////////////////////////////////////////////// 00066 // Function: csincos 00067 // Description: 00068 //////////////////////////////////////////////////////////////////// 00069 INLINE void 00070 csincos(float v, float *sin_result, float *cos_result) { 00071 // MS VC defines _M_IX86 for x86. gcc should define _X86_ 00072 #if defined(_M_IX86) || defined(_X86_) 00073 //#define fsincos_opcode __asm _emit 0xd9 __asm _emit 0xfb 00074 __asm { 00075 mov eax, sin_result 00076 mov edx, cos_result 00077 fld v 00078 fsincos 00079 fstp DWORD ptr [edx] 00080 fstp DWORD ptr [eax] 00081 } 00082 #else //!_X86_ 00083 *sin_result = sinf(v); 00084 *cos_result = cosf(v); 00085 #endif //!_X86_ 00086 } 00087 00088 //////////////////////////////////////////////////////////////////// 00089 // Function: csin_over_x 00090 // Description: Computes sin(x) / x, well-behaved as x approaches 0. 00091 //////////////////////////////////////////////////////////////////// 00092 INLINE float 00093 csin_over_x(float v) { 00094 if (1.0f + v * v == 1.0f) { 00095 return 1.0f; 00096 } else { 00097 return csin(v) / v; 00098 } 00099 } 00100 00101 //////////////////////////////////////////////////////////////////// 00102 // Function: cabs 00103 // Description: 00104 //////////////////////////////////////////////////////////////////// 00105 INLINE float 00106 cabs(float v) { 00107 return fabs(v); 00108 } 00109 00110 //////////////////////////////////////////////////////////////////// 00111 // Function: catan 00112 // Description: 00113 //////////////////////////////////////////////////////////////////// 00114 INLINE float 00115 catan(float v) { 00116 return atanf(v); 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: catan2 00121 // Description: 00122 //////////////////////////////////////////////////////////////////// 00123 INLINE float 00124 catan2(float y, float x) { 00125 return atan2f(y, x); 00126 } 00127 00128 //////////////////////////////////////////////////////////////////// 00129 // Function: casin 00130 // Description: 00131 //////////////////////////////////////////////////////////////////// 00132 INLINE float 00133 casin(float v) { 00134 return asinf(v); 00135 } 00136 00137 //////////////////////////////////////////////////////////////////// 00138 // Function: cacos 00139 // Description: 00140 //////////////////////////////////////////////////////////////////// 00141 INLINE float 00142 cacos(float v) { 00143 return acosf(v); 00144 } 00145 00146 //////////////////////////////////////////////////////////////////// 00147 // Function: cmod 00148 // Description: This is similar to fmod(), but it behaves properly 00149 // when x is negative: that is, it always returns a 00150 // value in the range [0, y), assuming y is positive. 00151 //////////////////////////////////////////////////////////////////// 00152 INLINE float 00153 cmod(float x, float y) { 00154 return x - cfloor(x / y) * y; 00155 } 00156 00157 //////////////////////////////////////////////////////////////////// 00158 // Function: cfloor 00159 // Description: 00160 //////////////////////////////////////////////////////////////////// 00161 INLINE double 00162 cfloor(double f) { 00163 #ifdef __INTEL_COMPILER 00164 // intel floor doesnt work right if fpu mode is not double, so make double-prec mode is on 00165 unsigned int saved_fpu_control_word=_controlfp(0x0,0x0); 00166 _controlfp(FPU_CONTROLWORD_NEW_SETTING,FPU_CONTROLWORD_WRITEMASK); 00167 double retval=floor(f); 00168 _controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK); 00169 return retval; 00170 #else 00171 return floor(f); 00172 #endif 00173 } 00174 00175 //////////////////////////////////////////////////////////////////// 00176 // Function: cceil 00177 // Description: 00178 //////////////////////////////////////////////////////////////////// 00179 INLINE double 00180 cceil(double f) { 00181 #ifdef __INTEL_COMPILER 00182 // intel ceil doesnt work right if fpu mode is not double, so make double-prec mode is on 00183 unsigned int saved_fpu_control_word=_controlfp(0x0,0x0); 00184 _controlfp(FPU_CONTROLWORD_NEW_SETTING,FPU_CONTROLWORD_WRITEMASK); 00185 double retval=ceil(f); 00186 _controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK); 00187 return retval; 00188 #else 00189 return ceil(f); 00190 #endif 00191 } 00192 00193 //////////////////////////////////////////////////////////////////// 00194 // Function: cfrac 00195 // Description: Returns the fractional component of f: f - cfloor(f). 00196 //////////////////////////////////////////////////////////////////// 00197 INLINE double 00198 cfrac(double f) { 00199 return f - cfloor(f); 00200 } 00201 00202 //////////////////////////////////////////////////////////////////// 00203 // Function: csqrt 00204 // Description: 00205 //////////////////////////////////////////////////////////////////// 00206 INLINE double 00207 csqrt(double v) { 00208 return sqrt(v); 00209 } 00210 00211 //////////////////////////////////////////////////////////////////// 00212 // Function: csin 00213 // Description: 00214 //////////////////////////////////////////////////////////////////// 00215 INLINE double 00216 csin(double v) { 00217 return sin(v); 00218 } 00219 00220 //////////////////////////////////////////////////////////////////// 00221 // Function: ccos 00222 // Description: 00223 //////////////////////////////////////////////////////////////////// 00224 INLINE double 00225 ccos(double v) { 00226 return cos(v); 00227 } 00228 00229 //////////////////////////////////////////////////////////////////// 00230 // Function: ctan 00231 // Description: 00232 //////////////////////////////////////////////////////////////////// 00233 INLINE double 00234 ctan(double v) { 00235 return tan(v); 00236 } 00237 00238 //////////////////////////////////////////////////////////////////// 00239 // Function: csincos 00240 // Description: 00241 //////////////////////////////////////////////////////////////////// 00242 INLINE void 00243 csincos(double v, double *sin_result, double *cos_result) { 00244 #if defined(_M_IX86) || defined(_X86_) 00245 //#define fsincos_opcode __asm _emit 0xd9 __asm _emit 0xfb 00246 __asm { 00247 mov eax, sin_result 00248 mov edx, cos_result 00249 fld v 00250 fsincos 00251 fstp QWORD ptr [edx] 00252 fstp QWORD ptr [eax] 00253 } 00254 #else //!_X86_ 00255 *sin_result = sin(v); 00256 *cos_result = cos(v); 00257 #endif //!_X86_ 00258 } 00259 00260 //////////////////////////////////////////////////////////////////// 00261 // Function: csin_over_x 00262 // Description: Computes sin(x) / x, well-behaved as x approaches 0. 00263 //////////////////////////////////////////////////////////////////// 00264 INLINE double 00265 csin_over_x(double v) { 00266 if (1.0 + v * v == 1.0) { 00267 return 1.0; 00268 } else { 00269 return csin(v) / v; 00270 } 00271 } 00272 00273 //////////////////////////////////////////////////////////////////// 00274 // Function: cabs 00275 // Description: 00276 //////////////////////////////////////////////////////////////////// 00277 INLINE double 00278 cabs(double v) { 00279 return fabs(v); 00280 } 00281 00282 //////////////////////////////////////////////////////////////////// 00283 // Function: catan 00284 // Description: 00285 //////////////////////////////////////////////////////////////////// 00286 INLINE double 00287 catan(double v) { 00288 return atan(v); 00289 } 00290 00291 //////////////////////////////////////////////////////////////////// 00292 // Function: catan2 00293 // Description: 00294 //////////////////////////////////////////////////////////////////// 00295 INLINE double 00296 catan2(double y, double x) { 00297 return atan2(y, x); 00298 } 00299 00300 //////////////////////////////////////////////////////////////////// 00301 // Function: casin 00302 // Description: 00303 //////////////////////////////////////////////////////////////////// 00304 INLINE double 00305 casin(double v) { 00306 return asin(v); 00307 } 00308 00309 //////////////////////////////////////////////////////////////////// 00310 // Function: cacos 00311 // Description: 00312 //////////////////////////////////////////////////////////////////// 00313 INLINE double 00314 cacos(double v) { 00315 return acos(v); 00316 } 00317 00318 //////////////////////////////////////////////////////////////////// 00319 // Function: cmod 00320 // Description: This is similar to fmod(), but it behaves properly 00321 // when x is negative: that is, it always returns a 00322 // value in the range [0, y), assuming y is positive. 00323 //////////////////////////////////////////////////////////////////// 00324 INLINE double 00325 cmod(double x, double y) { 00326 return x - cfloor(x / y) * y; 00327 } 00328 00329 //////////////////////////////////////////////////////////////////// 00330 // Function: cnan 00331 // Description: 00332 //////////////////////////////////////////////////////////////////// 00333 INLINE bool 00334 cnan(double v) { 00335 #ifndef _WIN32 00336 return (isnan(v) != 0); 00337 #else 00338 return (_isnan(v) != 0); 00339 #endif 00340 } 00341 00342 00343 //////////////////////////////////////////////////////////////////// 00344 // Function: cmod 00345 // Description: This is similar to fmod(), but it behaves properly 00346 // when x is negative: that is, it always returns a 00347 // value in the range [0, y), assuming y is positive. 00348 // 00349 // This integer-valued function is provided since the 00350 // built-in modulo operator % does not work properly for 00351 // negative x. 00352 //////////////////////////////////////////////////////////////////// 00353 INLINE int 00354 cmod(int x, int y) { 00355 if (x < 0) { 00356 return y - 1 - ((-x - 1) % y); 00357 } else { 00358 return x % y; 00359 } 00360 }