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
24namespace physx
25{
26#endif
27
28
29/**
30\brief 3 Element vector class.
31
32This is a 3-dimensional vector class with public data members.
33*/
34class PxVec3
35{
36public:
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
355PX_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