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