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