1 | // |
2 | // Redistribution and use in source and binary forms, with or without |
3 | // modification, are permitted provided that the following conditions |
4 | // are met: |
5 | // * Redistributions of source code must retain the above copyright |
6 | // notice, this list of conditions and the following disclaimer. |
7 | // * Redistributions in binary form must reproduce the above copyright |
8 | // notice, this list of conditions and the following disclaimer in the |
9 | // documentation and/or other materials provided with the distribution. |
10 | // * Neither the name of NVIDIA CORPORATION nor the names of its |
11 | // contributors may be used to endorse or promote products derived |
12 | // from this software without specific prior written permission. |
13 | // |
14 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY |
15 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
18 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 | // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | // |
26 | // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. |
27 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
28 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
29 | |
30 | #ifndef PXFOUNDATION_PXVEC4_H |
31 | #define PXFOUNDATION_PXVEC4_H |
32 | /** \addtogroup foundation |
33 | @{ |
34 | */ |
35 | #include "foundation/PxMath.h" |
36 | #include "foundation/PxVec3.h" |
37 | #include "foundation/PxSharedAssert.h" |
38 | |
39 | /** |
40 | \brief 4 Element vector class. |
41 | |
42 | This is a 4-dimensional vector class with public data members. |
43 | */ |
44 | #if !PX_DOXYGEN |
45 | namespace physx |
46 | { |
47 | #endif |
48 | |
49 | class PxVec4 |
50 | { |
51 | public: |
52 | /** |
53 | \brief default constructor leaves data uninitialized. |
54 | */ |
55 | PX_CUDA_CALLABLE PX_INLINE PxVec4() |
56 | { |
57 | } |
58 | |
59 | /** |
60 | \brief zero constructor. |
61 | */ |
62 | PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4(PxZERO r) : x(0.0f), y(0.0f), z(0.0f), w(0.0f) |
63 | { |
64 | PX_UNUSED(r); |
65 | } |
66 | |
67 | /** |
68 | \brief Assigns scalar parameter to all elements. |
69 | |
70 | Useful to initialize to zero or one. |
71 | |
72 | \param[in] a Value to assign to elements. |
73 | */ |
74 | explicit PX_CUDA_CALLABLE PX_INLINE PxVec4(float a) : x(a), y(a), z(a), w(a) |
75 | { |
76 | } |
77 | |
78 | /** |
79 | \brief Initializes from 3 scalar parameters. |
80 | |
81 | \param[in] nx Value to initialize X component. |
82 | \param[in] ny Value to initialize Y component. |
83 | \param[in] nz Value to initialize Z component. |
84 | \param[in] nw Value to initialize W component. |
85 | */ |
86 | PX_CUDA_CALLABLE PX_INLINE PxVec4(float nx, float ny, float nz, float nw) : x(nx), y(ny), z(nz), w(nw) |
87 | { |
88 | } |
89 | |
90 | /** |
91 | \brief Initializes from 3 scalar parameters. |
92 | |
93 | \param[in] v Value to initialize the X, Y, and Z components. |
94 | \param[in] nw Value to initialize W component. |
95 | */ |
96 | PX_CUDA_CALLABLE PX_INLINE PxVec4(const PxVec3& v, float nw) : x(v.x), y(v.y), z(v.z), w(nw) |
97 | { |
98 | } |
99 | |
100 | /** |
101 | \brief Initializes from an array of scalar parameters. |
102 | |
103 | \param[in] v Value to initialize with. |
104 | */ |
105 | explicit PX_CUDA_CALLABLE PX_INLINE PxVec4(const float v[]) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) |
106 | { |
107 | } |
108 | |
109 | /** |
110 | \brief Copy ctor. |
111 | */ |
112 | PX_CUDA_CALLABLE PX_INLINE PxVec4(const PxVec4& v) : x(v.x), y(v.y), z(v.z), w(v.w) |
113 | { |
114 | } |
115 | |
116 | // Operators |
117 | |
118 | /** |
119 | \brief Assignment operator |
120 | */ |
121 | PX_CUDA_CALLABLE PX_INLINE PxVec4& operator=(const PxVec4& p) |
122 | { |
123 | x = p.x; |
124 | y = p.y; |
125 | z = p.z; |
126 | w = p.w; |
127 | return *this; |
128 | } |
129 | |
130 | /** |
131 | \brief element access |
132 | */ |
133 | PX_CUDA_CALLABLE PX_INLINE float& operator[](unsigned int index) |
134 | { |
135 | PX_SHARED_ASSERT(index <= 3); |
136 | |
137 | return reinterpret_cast<float*>(this)[index]; |
138 | } |
139 | |
140 | /** |
141 | \brief element access |
142 | */ |
143 | PX_CUDA_CALLABLE PX_INLINE const float& operator[](unsigned int index) const |
144 | { |
145 | PX_SHARED_ASSERT(index <= 3); |
146 | |
147 | return reinterpret_cast<const float*>(this)[index]; |
148 | } |
149 | |
150 | /** |
151 | \brief returns true if the two vectors are exactly equal. |
152 | */ |
153 | PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxVec4& v) const |
154 | { |
155 | return x == v.x && y == v.y && z == v.z && w == v.w; |
156 | } |
157 | |
158 | /** |
159 | \brief returns true if the two vectors are not exactly equal. |
160 | */ |
161 | PX_CUDA_CALLABLE PX_INLINE bool operator!=(const PxVec4& v) const |
162 | { |
163 | return x != v.x || y != v.y || z != v.z || w != v.w; |
164 | } |
165 | |
166 | /** |
167 | \brief tests for exact zero vector |
168 | */ |
169 | PX_CUDA_CALLABLE PX_INLINE bool isZero() const |
170 | { |
171 | return x == 0 && y == 0 && z == 0 && w == 0; |
172 | } |
173 | |
174 | /** |
175 | \brief returns true if all 3 elems of the vector are finite (not NAN or INF, etc.) |
176 | */ |
177 | PX_CUDA_CALLABLE PX_INLINE bool isFinite() const |
178 | { |
179 | return PxIsFinite(f: x) && PxIsFinite(f: y) && PxIsFinite(f: z) && PxIsFinite(f: w); |
180 | } |
181 | |
182 | /** |
183 | \brief is normalized - used by API parameter validation |
184 | */ |
185 | PX_CUDA_CALLABLE PX_INLINE bool isNormalized() const |
186 | { |
187 | const float unitTolerance = 1e-4f; |
188 | return isFinite() && PxAbs(a: magnitude() - 1) < unitTolerance; |
189 | } |
190 | |
191 | /** |
192 | \brief returns the squared magnitude |
193 | |
194 | Avoids calling PxSqrt()! |
195 | */ |
196 | PX_CUDA_CALLABLE PX_INLINE float magnitudeSquared() const |
197 | { |
198 | return x * x + y * y + z * z + w * w; |
199 | } |
200 | |
201 | /** |
202 | \brief returns the magnitude |
203 | */ |
204 | PX_CUDA_CALLABLE PX_INLINE float magnitude() const |
205 | { |
206 | return PxSqrt(a: magnitudeSquared()); |
207 | } |
208 | |
209 | /** |
210 | \brief negation |
211 | */ |
212 | PX_CUDA_CALLABLE PX_INLINE PxVec4 operator-() const |
213 | { |
214 | return PxVec4(-x, -y, -z, -w); |
215 | } |
216 | |
217 | /** |
218 | \brief vector addition |
219 | */ |
220 | PX_CUDA_CALLABLE PX_INLINE PxVec4 operator+(const PxVec4& v) const |
221 | { |
222 | return PxVec4(x + v.x, y + v.y, z + v.z, w + v.w); |
223 | } |
224 | |
225 | /** |
226 | \brief vector difference |
227 | */ |
228 | PX_CUDA_CALLABLE PX_INLINE PxVec4 operator-(const PxVec4& v) const |
229 | { |
230 | return PxVec4(x - v.x, y - v.y, z - v.z, w - v.w); |
231 | } |
232 | |
233 | /** |
234 | \brief scalar post-multiplication |
235 | */ |
236 | |
237 | PX_CUDA_CALLABLE PX_INLINE PxVec4 operator*(float f) const |
238 | { |
239 | return PxVec4(x * f, y * f, z * f, w * f); |
240 | } |
241 | |
242 | /** |
243 | \brief scalar division |
244 | */ |
245 | PX_CUDA_CALLABLE PX_INLINE PxVec4 operator/(float f) const |
246 | { |
247 | f = 1.0f / f; |
248 | return PxVec4(x * f, y * f, z * f, w * f); |
249 | } |
250 | |
251 | /** |
252 | \brief vector addition |
253 | */ |
254 | PX_CUDA_CALLABLE PX_INLINE PxVec4& operator+=(const PxVec4& v) |
255 | { |
256 | x += v.x; |
257 | y += v.y; |
258 | z += v.z; |
259 | w += v.w; |
260 | return *this; |
261 | } |
262 | |
263 | /** |
264 | \brief vector difference |
265 | */ |
266 | PX_CUDA_CALLABLE PX_INLINE PxVec4& operator-=(const PxVec4& v) |
267 | { |
268 | x -= v.x; |
269 | y -= v.y; |
270 | z -= v.z; |
271 | w -= v.w; |
272 | return *this; |
273 | } |
274 | |
275 | /** |
276 | \brief scalar multiplication |
277 | */ |
278 | PX_CUDA_CALLABLE PX_INLINE PxVec4& operator*=(float f) |
279 | { |
280 | x *= f; |
281 | y *= f; |
282 | z *= f; |
283 | w *= f; |
284 | return *this; |
285 | } |
286 | /** |
287 | \brief scalar division |
288 | */ |
289 | PX_CUDA_CALLABLE PX_INLINE PxVec4& operator/=(float f) |
290 | { |
291 | f = 1.0f / f; |
292 | x *= f; |
293 | y *= f; |
294 | z *= f; |
295 | w *= f; |
296 | return *this; |
297 | } |
298 | |
299 | /** |
300 | \brief returns the scalar product of this and other. |
301 | */ |
302 | PX_CUDA_CALLABLE PX_INLINE float dot(const PxVec4& v) const |
303 | { |
304 | return x * v.x + y * v.y + z * v.z + w * v.w; |
305 | } |
306 | |
307 | /** return a unit vector */ |
308 | |
309 | PX_CUDA_CALLABLE PX_INLINE PxVec4 getNormalized() const |
310 | { |
311 | float m = magnitudeSquared(); |
312 | return m > 0.0f ? *this * PxRecipSqrt(a: m) : PxVec4(0, 0, 0, 0); |
313 | } |
314 | |
315 | /** |
316 | \brief normalizes the vector in place |
317 | */ |
318 | PX_CUDA_CALLABLE PX_INLINE float normalize() |
319 | { |
320 | float m = magnitude(); |
321 | if(m > 0.0f) |
322 | *this /= m; |
323 | return m; |
324 | } |
325 | |
326 | /** |
327 | \brief a[i] * b[i], for all i. |
328 | */ |
329 | PX_CUDA_CALLABLE PX_INLINE PxVec4 multiply(const PxVec4& a) const |
330 | { |
331 | return PxVec4(x * a.x, y * a.y, z * a.z, w * a.w); |
332 | } |
333 | |
334 | /** |
335 | \brief element-wise minimum |
336 | */ |
337 | PX_CUDA_CALLABLE PX_INLINE PxVec4 minimum(const PxVec4& v) const |
338 | { |
339 | return PxVec4(PxMin(a: x, b: v.x), PxMin(a: y, b: v.y), PxMin(a: z, b: v.z), PxMin(a: w, b: v.w)); |
340 | } |
341 | |
342 | /** |
343 | \brief element-wise maximum |
344 | */ |
345 | PX_CUDA_CALLABLE PX_INLINE PxVec4 maximum(const PxVec4& v) const |
346 | { |
347 | return PxVec4(PxMax(a: x, b: v.x), PxMax(a: y, b: v.y), PxMax(a: z, b: v.z), PxMax(a: w, b: v.w)); |
348 | } |
349 | |
350 | PX_CUDA_CALLABLE PX_INLINE PxVec3 getXYZ() const |
351 | { |
352 | return PxVec3(x, y, z); |
353 | } |
354 | |
355 | /** |
356 | \brief set vector elements to zero |
357 | */ |
358 | PX_CUDA_CALLABLE PX_INLINE void setZero() |
359 | { |
360 | x = y = z = w = 0.0f; |
361 | } |
362 | |
363 | float x, y, z, w; |
364 | }; |
365 | |
366 | PX_CUDA_CALLABLE static PX_INLINE PxVec4 operator*(float f, const PxVec4& v) |
367 | { |
368 | return PxVec4(f * v.x, f * v.y, f * v.z, f * v.w); |
369 | } |
370 | |
371 | #if !PX_DOXYGEN |
372 | } // namespace physx |
373 | #endif |
374 | |
375 | /** @} */ |
376 | #endif // #ifndef PXFOUNDATION_PXVEC4_H |
377 | |