Panda3D

cmath.I

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 }
 All Classes Functions Variables Enumerations