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