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
27This is a 4-dimensional vector class with public data members.
28*/
29#ifndef PX_DOXYGEN
30namespace physx
31{
32#endif
33
34class PxVec4
35{
36public:
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
331PX_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