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 | |