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_VEC3_H |
15 | #define PX_FOUNDATION_PX_VEC3_H |
16 | |
17 | /** \addtogroup foundation |
18 | @{ |
19 | */ |
20 | |
21 | #include "foundation/PxMath.h" |
22 | |
23 | #ifndef PX_DOXYGEN |
24 | namespace physx |
25 | { |
26 | #endif |
27 | |
28 | |
29 | /** |
30 | \brief 3 Element vector class. |
31 | |
32 | This is a 3-dimensional vector class with public data members. |
33 | */ |
34 | class PxVec3 |
35 | { |
36 | public: |
37 | |
38 | /** |
39 | \brief default constructor leaves data uninitialized. |
40 | */ |
41 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3() {} |
42 | |
43 | /** |
44 | \brief zero constructor. |
45 | */ |
46 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3(PxZERO r): x(0.0f), y(0.0f), z(0.0f) |
47 | { |
48 | PX_UNUSED(r); |
49 | } |
50 | |
51 | |
52 | /** |
53 | \brief Assigns scalar parameter to all elements. |
54 | |
55 | Useful to initialize to zero or one. |
56 | |
57 | \param[in] a Value to assign to elements. |
58 | */ |
59 | explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3(PxReal a): x(a), y(a), z(a) {} |
60 | |
61 | /** |
62 | \brief Initializes from 3 scalar parameters. |
63 | |
64 | \param[in] nx Value to initialize X component. |
65 | \param[in] ny Value to initialize Y component. |
66 | \param[in] nz Value to initialize Z component. |
67 | */ |
68 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3(PxReal nx, PxReal ny, PxReal nz): x(nx), y(ny), z(nz) {} |
69 | |
70 | /** |
71 | \brief Copy ctor. |
72 | */ |
73 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3(const PxVec3& v): x(v.x), y(v.y), z(v.z) {} |
74 | |
75 | //Operators |
76 | |
77 | /** |
78 | \brief Assignment operator |
79 | */ |
80 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator=(const PxVec3& p) { x = p.x; y = p.y; z = p.z; return *this; } |
81 | |
82 | /** |
83 | \brief element access |
84 | */ |
85 | PX_DEPRECATED PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal& operator[](int index) |
86 | { |
87 | PX_ASSERT(index>=0 && index<=2); |
88 | |
89 | return reinterpret_cast<PxReal*>(this)[index]; |
90 | } |
91 | |
92 | /** |
93 | \brief element access |
94 | */ |
95 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal& operator[](unsigned int index) |
96 | { |
97 | PX_ASSERT(index<=2); |
98 | |
99 | return reinterpret_cast<PxReal*>(this)[index]; |
100 | } |
101 | |
102 | /** |
103 | \brief element access |
104 | */ |
105 | PX_DEPRECATED PX_CUDA_CALLABLE PX_FORCE_INLINE const PxReal& operator[](int index) const |
106 | { |
107 | PX_ASSERT(index>=0 && index<=2); |
108 | |
109 | return reinterpret_cast<const PxReal*>(this)[index]; |
110 | } |
111 | |
112 | /** |
113 | \brief element access |
114 | */ |
115 | PX_CUDA_CALLABLE PX_FORCE_INLINE const PxReal& operator[](unsigned int index) const |
116 | { |
117 | PX_ASSERT(index<=2); |
118 | |
119 | return reinterpret_cast<const PxReal*>(this)[index]; |
120 | } |
121 | /** |
122 | \brief returns true if the two vectors are exactly equal. |
123 | */ |
124 | PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator==(const PxVec3&v) const { return x == v.x && y == v.y && z == v.z; } |
125 | |
126 | /** |
127 | \brief returns true if the two vectors are not exactly equal. |
128 | */ |
129 | PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator!=(const PxVec3&v) const { return x != v.x || y != v.y || z != v.z; } |
130 | |
131 | /** |
132 | \brief tests for exact zero vector |
133 | */ |
134 | PX_CUDA_CALLABLE PX_FORCE_INLINE bool isZero() const { return x==0.0f && y==0.0f && z == 0.0f; } |
135 | |
136 | /** |
137 | \brief returns true if all 3 elems of the vector are finite (not NAN or INF, etc.) |
138 | */ |
139 | PX_CUDA_CALLABLE PX_INLINE bool isFinite() const |
140 | { |
141 | return PxIsFinite(x) && PxIsFinite(y) && PxIsFinite(z); |
142 | } |
143 | |
144 | /** |
145 | \brief is normalized - used by API parameter validation |
146 | */ |
147 | PX_CUDA_CALLABLE PX_FORCE_INLINE bool isNormalized() const |
148 | { |
149 | const float unitTolerance = 1e-4f; |
150 | return isFinite() && PxAbs(magnitude()-1)<unitTolerance; |
151 | } |
152 | |
153 | /** |
154 | \brief returns the squared magnitude |
155 | |
156 | Avoids calling PxSqrt()! |
157 | */ |
158 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal magnitudeSquared() const { return x * x + y * y + z * z; } |
159 | |
160 | /** |
161 | \brief returns the magnitude |
162 | */ |
163 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal magnitude() const { return PxSqrt(magnitudeSquared()); } |
164 | |
165 | /** |
166 | \brief negation |
167 | */ |
168 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 operator -() const |
169 | { |
170 | return PxVec3(-x, -y, -z); |
171 | } |
172 | |
173 | /** |
174 | \brief vector addition |
175 | */ |
176 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 operator +(const PxVec3& v) const { return PxVec3(x + v.x, y + v.y, z + v.z); } |
177 | |
178 | /** |
179 | \brief vector difference |
180 | */ |
181 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 operator -(const PxVec3& v) const { return PxVec3(x - v.x, y - v.y, z - v.z); } |
182 | |
183 | /** |
184 | \brief scalar post-multiplication |
185 | */ |
186 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 operator *(PxReal f) const { return PxVec3(x * f, y * f, z * f); } |
187 | |
188 | /** |
189 | \brief scalar division |
190 | */ |
191 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 operator /(PxReal f) const |
192 | { |
193 | f = 1.0f / f; |
194 | return PxVec3(x * f, y * f, z * f); |
195 | } |
196 | |
197 | /** |
198 | \brief vector addition |
199 | */ |
200 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator +=(const PxVec3& v) |
201 | { |
202 | x += v.x; |
203 | y += v.y; |
204 | z += v.z; |
205 | return *this; |
206 | } |
207 | |
208 | /** |
209 | \brief vector difference |
210 | */ |
211 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator -=(const PxVec3& v) |
212 | { |
213 | x -= v.x; |
214 | y -= v.y; |
215 | z -= v.z; |
216 | return *this; |
217 | } |
218 | |
219 | /** |
220 | \brief scalar multiplication |
221 | */ |
222 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator *=(PxReal f) |
223 | { |
224 | x *= f; |
225 | y *= f; |
226 | z *= f; |
227 | return *this; |
228 | } |
229 | /** |
230 | \brief scalar division |
231 | */ |
232 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator /=(PxReal f) |
233 | { |
234 | f = 1.0f/f; |
235 | x *= f; |
236 | y *= f; |
237 | z *= f; |
238 | return *this; |
239 | } |
240 | |
241 | /** |
242 | \brief returns the scalar product of this and other. |
243 | */ |
244 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal dot(const PxVec3& v) const |
245 | { |
246 | return x * v.x + y * v.y + z * v.z; |
247 | } |
248 | |
249 | /** |
250 | \brief cross product |
251 | */ |
252 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 cross(const PxVec3& v) const |
253 | { |
254 | return PxVec3(y * v.z - z * v.y, |
255 | z * v.x - x * v.z, |
256 | x * v.y - y * v.x); |
257 | } |
258 | |
259 | /** return a unit vector */ |
260 | |
261 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getNormalized() const |
262 | { |
263 | const PxReal m = magnitudeSquared(); |
264 | return m>0.0f ? *this * PxRecipSqrt(m) : PxVec3(0,0,0); |
265 | } |
266 | |
267 | /** |
268 | \brief normalizes the vector in place |
269 | */ |
270 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal normalize() |
271 | { |
272 | const PxReal m = magnitude(); |
273 | if (m>0.0f) |
274 | *this /= m; |
275 | return m; |
276 | } |
277 | |
278 | /** |
279 | \brief normalizes the vector in place. Does nothing if vector magnitude is under PX_NORMALIZATION_EPSILON. |
280 | Returns vector magnitude if >= PX_NORMALIZATION_EPSILON and 0.0f otherwise. |
281 | */ |
282 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal normalizeSafe() |
283 | { |
284 | const PxReal mag = magnitude(); |
285 | if (mag < PX_NORMALIZATION_EPSILON) |
286 | return 0.0f; |
287 | *this *= 1.0f / mag; |
288 | return mag; |
289 | } |
290 | |
291 | /** |
292 | \brief normalizes the vector in place. Asserts if vector magnitude is under PX_NORMALIZATION_EPSILON. |
293 | returns vector magnitude. |
294 | */ |
295 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal normalizeFast() |
296 | { |
297 | const PxReal mag = magnitude(); |
298 | PX_ASSERT(mag >= PX_NORMALIZATION_EPSILON); |
299 | *this *= 1.0f / mag; |
300 | return mag; |
301 | } |
302 | |
303 | /** |
304 | \brief a[i] * b[i], for all i. |
305 | */ |
306 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 multiply(const PxVec3& a) const |
307 | { |
308 | return PxVec3(x*a.x, y*a.y, z*a.z); |
309 | } |
310 | |
311 | /** |
312 | \brief element-wise minimum |
313 | */ |
314 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 minimum(const PxVec3& v) const |
315 | { |
316 | return PxVec3(PxMin(x, v.x), PxMin(y,v.y), PxMin(z,v.z)); |
317 | } |
318 | |
319 | /** |
320 | \brief returns MIN(x, y, z); |
321 | */ |
322 | PX_CUDA_CALLABLE PX_FORCE_INLINE float minElement() const |
323 | { |
324 | return PxMin(x, PxMin(y, z)); |
325 | } |
326 | |
327 | /** |
328 | \brief element-wise maximum |
329 | */ |
330 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 maximum(const PxVec3& v) const |
331 | { |
332 | return PxVec3(PxMax(x, v.x), PxMax(y,v.y), PxMax(z,v.z)); |
333 | } |
334 | |
335 | /** |
336 | \brief returns MAX(x, y, z); |
337 | */ |
338 | PX_CUDA_CALLABLE PX_FORCE_INLINE float maxElement() const |
339 | { |
340 | return PxMax(x, PxMax(y, z)); |
341 | } |
342 | |
343 | /** |
344 | \brief returns absolute values of components; |
345 | */ |
346 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 abs() const |
347 | { |
348 | return PxVec3(PxAbs(x), PxAbs(y), PxAbs(z)); |
349 | } |
350 | |
351 | |
352 | PxReal x,y,z; |
353 | }; |
354 | |
355 | PX_CUDA_CALLABLE static PX_FORCE_INLINE PxVec3 operator *(PxReal f, const PxVec3& v) |
356 | { |
357 | return PxVec3(f * v.x, f * v.y, f * v.z); |
358 | } |
359 | |
360 | #ifndef PX_DOXYGEN |
361 | } // namespace physx |
362 | #endif |
363 | |
364 | /** @} */ |
365 | #endif // PX_FOUNDATION_PX_VEC3_H |
366 | |