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