| 1 | /* |
| 2 | * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. |
| 3 | * |
| 4 | * NVIDIA CORPORATION and its licensors retain all intellectual property |
| 5 | * and proprietary rights in and to this software, related documentation |
| 6 | * and any modifications thereto. Any use, reproduction, disclosure or |
| 7 | * distribution of this software and related documentation without an express |
| 8 | * license agreement from NVIDIA CORPORATION is strictly prohibited. |
| 9 | */ |
| 10 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
| 11 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
| 12 | |
| 13 | |
| 14 | #ifndef PX_FOUNDATION_PX_MATH_H |
| 15 | #define PX_FOUNDATION_PX_MATH_H |
| 16 | |
| 17 | /** \addtogroup foundation |
| 18 | @{ |
| 19 | */ |
| 20 | |
| 21 | #include "foundation/PxPreprocessor.h" |
| 22 | |
| 23 | #ifdef PX_VC |
| 24 | #pragma warning(push) |
| 25 | #pragma warning( disable : 4985 ) // 'symbol name': attributes not present on previous declaration |
| 26 | #endif |
| 27 | #include <math.h> |
| 28 | #ifdef PX_VC |
| 29 | #pragma warning(pop) |
| 30 | #endif |
| 31 | |
| 32 | #include <float.h> |
| 33 | #include "foundation/PxIntrinsics.h" |
| 34 | #include "foundation/PxAssert.h" |
| 35 | |
| 36 | |
| 37 | #ifndef PX_DOXYGEN |
| 38 | namespace physx |
| 39 | { |
| 40 | #endif |
| 41 | |
| 42 | /** enum for zero constructor tag for vectors and matrices */ |
| 43 | enum PxZERO { PxZero }; |
| 44 | |
| 45 | /** enum for identity constructor flag for quaternions, transforms, and matrices */ |
| 46 | enum PxIDENTITY { PxIdentity }; |
| 47 | |
| 48 | |
| 49 | // constants |
| 50 | static const PxReal PxPi = PxReal(3.141592653589793); |
| 51 | static const PxReal PxHalfPi = PxReal(1.57079632679489661923); |
| 52 | static const PxReal PxTwoPi = PxReal(6.28318530717958647692); |
| 53 | static const PxReal PxInvPi = PxReal(0.31830988618379067154); |
| 54 | static const PxReal PxInvTwoPi = PxReal(0.15915494309189533577); |
| 55 | static const PxReal PxPiDivTwo = PxReal(1.57079632679489661923); |
| 56 | static const PxReal PxPiDivFour = PxReal(0.78539816339744830962); |
| 57 | |
| 58 | |
| 59 | /** |
| 60 | \brief The return value is the greater of the two specified values. |
| 61 | */ |
| 62 | template<class T> |
| 63 | PX_CUDA_CALLABLE PX_FORCE_INLINE T PxMax(T a, T b) { return a<b ? b : a; } |
| 64 | |
| 65 | //! overload for float to use fsel on xbox |
| 66 | template<> |
| 67 | PX_CUDA_CALLABLE PX_FORCE_INLINE float PxMax(float a, float b) { return intrinsics::selectMax(a, b); } |
| 68 | |
| 69 | /** |
| 70 | \brief The return value is the lesser of the two specified values. |
| 71 | */ |
| 72 | template<class T> |
| 73 | PX_CUDA_CALLABLE PX_FORCE_INLINE T PxMin(T a, T b) { return a<b ? a : b; } |
| 74 | |
| 75 | template<> |
| 76 | //! overload for float to use fsel on xbox |
| 77 | PX_CUDA_CALLABLE PX_FORCE_INLINE float PxMin(float a, float b) { return intrinsics::selectMin(a, b); } |
| 78 | |
| 79 | /* |
| 80 | Many of these are just implemented as PX_CUDA_CALLABLE PX_FORCE_INLINE calls to the C lib right now, |
| 81 | but later we could replace some of them with some approximations or more |
| 82 | clever stuff. |
| 83 | */ |
| 84 | |
| 85 | /** |
| 86 | \brief abs returns the absolute value of its argument. |
| 87 | */ |
| 88 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxAbs(PxF32 a) { return intrinsics::abs(a); } |
| 89 | |
| 90 | PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxEquals(PxF32 a, PxF32 b,PxF32 eps) { return (PxAbs(a - b) < eps); } |
| 91 | |
| 92 | /** |
| 93 | \brief abs returns the absolute value of its argument. |
| 94 | */ |
| 95 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF64 PxAbs(PxF64 a) { return ::fabs(a); } |
| 96 | |
| 97 | /** |
| 98 | \brief abs returns the absolute value of its argument. |
| 99 | */ |
| 100 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxI32 PxAbs(PxI32 a) { return ::abs(a); } |
| 101 | |
| 102 | /** |
| 103 | \brief Clamps v to the range [hi,lo] |
| 104 | */ |
| 105 | template<class T> |
| 106 | PX_CUDA_CALLABLE PX_FORCE_INLINE T PxClamp(T v, T lo, T hi) { PX_ASSERT(lo<=hi); return PxMin(hi, PxMax(lo, v)); } |
| 107 | |
| 108 | //! \brief Square root. |
| 109 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxSqrt(PxF32 a) { return intrinsics::sqrt(a); } |
| 110 | |
| 111 | //! \brief Square root. |
| 112 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF64 PxSqrt(PxF64 a) { return ::sqrt(a); } |
| 113 | |
| 114 | //! \brief reciprocal square root. |
| 115 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxRecipSqrt(PxF32 a) { return intrinsics::recipSqrt(a); } |
| 116 | |
| 117 | //! \brief reciprocal square root. |
| 118 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF64 PxRecipSqrt(PxF64 a) { return 1/::sqrt(a); } |
| 119 | |
| 120 | //!trigonometry -- all angles are in radians. |
| 121 | |
| 122 | //! \brief Sine of an angle ( <b>Unit:</b> Radians ) |
| 123 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxSin(PxF32 a) { return intrinsics::sin(a); } |
| 124 | |
| 125 | //! \brief Sine of an angle ( <b>Unit:</b> Radians ) |
| 126 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF64 PxSin(PxF64 a) { return ::sin(a); } |
| 127 | |
| 128 | //! \brief Cosine of an angle (<b>Unit:</b> Radians) |
| 129 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxCos(PxF32 a) { return intrinsics::cos(a); } |
| 130 | |
| 131 | //! \brief Cosine of an angle (<b>Unit:</b> Radians) |
| 132 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF64 PxCos(PxF64 a) { return ::cos(a); } |
| 133 | |
| 134 | /** |
| 135 | \brief Tangent of an angle. |
| 136 | <b>Unit:</b> Radians |
| 137 | */ |
| 138 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxTan(PxF32 a) { return ::tanf(a); } |
| 139 | |
| 140 | /** |
| 141 | \brief Tangent of an angle. |
| 142 | <b>Unit:</b> Radians |
| 143 | */ |
| 144 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF64 PxTan(PxF64 a) { return ::tan(a); } |
| 145 | |
| 146 | /** |
| 147 | \brief Arcsine. |
| 148 | Returns angle between -PI/2 and PI/2 in radians |
| 149 | <b>Unit:</b> Radians |
| 150 | */ |
| 151 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxAsin(PxF32 f) { return ::asinf(PxClamp(f,-1.0f,1.0f)); } |
| 152 | |
| 153 | /** |
| 154 | \brief Arcsine. |
| 155 | Returns angle between -PI/2 and PI/2 in radians |
| 156 | <b>Unit:</b> Radians |
| 157 | */ |
| 158 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF64 PxAsin(PxF64 f) { return ::asin(PxClamp(f,-1.0,1.0)); } |
| 159 | |
| 160 | /** |
| 161 | \brief Arccosine. |
| 162 | Returns angle between 0 and PI in radians |
| 163 | <b>Unit:</b> Radians |
| 164 | */ |
| 165 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxAcos(PxF32 f) { return ::acosf(PxClamp(f,-1.0f,1.0f)); } |
| 166 | |
| 167 | /** |
| 168 | \brief Arccosine. |
| 169 | Returns angle between 0 and PI in radians |
| 170 | <b>Unit:</b> Radians |
| 171 | */ |
| 172 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF64 PxAcos(PxF64 f) { return ::acos(PxClamp(f,-1.0,1.0)); } |
| 173 | |
| 174 | /** |
| 175 | \brief ArcTangent. |
| 176 | Returns angle between -PI/2 and PI/2 in radians |
| 177 | <b>Unit:</b> Radians |
| 178 | */ |
| 179 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxAtan(PxF32 a) { return ::atanf(a); } |
| 180 | |
| 181 | /** |
| 182 | \brief ArcTangent. |
| 183 | Returns angle between -PI/2 and PI/2 in radians |
| 184 | <b>Unit:</b> Radians |
| 185 | */ |
| 186 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF64 PxAtan(PxF64 a) { return ::atan(a); } |
| 187 | |
| 188 | /** |
| 189 | \brief Arctangent of (x/y) with correct sign. |
| 190 | Returns angle between -PI and PI in radians |
| 191 | <b>Unit:</b> Radians |
| 192 | */ |
| 193 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxAtan2(PxF32 x, PxF32 y) { return ::atan2f(x,y); } |
| 194 | |
| 195 | /** |
| 196 | \brief Arctangent of (x/y) with correct sign. |
| 197 | Returns angle between -PI and PI in radians |
| 198 | <b>Unit:</b> Radians |
| 199 | */ |
| 200 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF64 PxAtan2(PxF64 x, PxF64 y) { return ::atan2(x,y); } |
| 201 | |
| 202 | //! \brief returns true if the passed number is a finite floating point number as opposed to INF, NAN, etc. |
| 203 | PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxIsFinite(PxF32 f) { return intrinsics::isFinite(f); } |
| 204 | |
| 205 | //! \brief returns true if the passed number is a finite floating point number as opposed to INF, NAN, etc. |
| 206 | PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxIsFinite(PxF64 f) { return intrinsics::isFinite(f); } |
| 207 | |
| 208 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxFloor(PxF32 a) { return ::floorf(a); } |
| 209 | |
| 210 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxExp(PxF32 a) { return ::expf(a); } |
| 211 | |
| 212 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxCeil(PxF32 a) { return ::ceilf(a); } |
| 213 | |
| 214 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxSign(PxF32 a) { return physx::intrinsics::sign(a); } |
| 215 | |
| 216 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxPow(PxF32 x,PxF32 y) { return ::powf(x,y); } |
| 217 | |
| 218 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxLog(PxF32 x) { return ::logf(x); } |
| 219 | |
| 220 | #ifndef PX_DOXYGEN |
| 221 | } // namespace physx |
| 222 | #endif |
| 223 | |
| 224 | /** @} */ |
| 225 | #endif // PX_FOUNDATION_PX_MATH_H |
| 226 | |