HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImathVec.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5 
6 //
7 // 2D, 3D and 4D point/vector class templates
8 //
9 
10 #ifndef INCLUDED_IMATHVEC_H
11 #define INCLUDED_IMATHVEC_H
12 
13 #ifdef __has_include
14 # if __has_include(<version>)
15 # include <version>
16 # endif
17 #endif
18 
19 #include "ImathExport.h"
20 #include "ImathNamespace.h"
21 #include "ImathTypeTraits.h"
22 
23 #include "ImathMath.h"
24 #include "half.h"
25 
26 #include <iostream>
27 #include <limits>
28 #include <cstdint>
29 #include <stdexcept>
30 
31 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
32 // suppress exception specification warnings
33 # pragma warning(push)
34 # pragma warning(disable : 4290)
35 #endif
36 
37 IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
38 
39 template <class T> class Vec2;
40 template <class T> class Vec3;
41 template <class T> class Vec4;
42 
43 /// Enum for the Vec4 to Vec3 conversion constructor
45 {
46  INF_EXCEPTION
47 };
48 
49 ///
50 /// 2-element vector
51 ///
52 
53 template <class T> class IMATH_EXPORT_TEMPLATE_TYPE Vec2
54 {
55 public:
56  /// @{
57  /// @name Direct access to elements
58 
59  T x, y;
60 
61  /// @}
62 
63  /// Element access by index.
64  ///
65  /// NB: This method of access may use dynamic array accesses which
66  /// can prevent compiler optimizations and force temporaries to be
67  /// stored to the stack and other missed vectorization
68  /// opportunities. Use of direct access to x, y when
69  /// possible should be preferred.
70  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T& operator[] (int i) IMATH_NOEXCEPT;
71 
72  /// Element access by index.
73  ///
74  /// NB: This method of access may use dynamic array accesses which
75  /// can prevent compiler optimizations and force temporaries to be
76  /// stored to the stack and other missed vectorization
77  /// opportunities. Use of direct access to x, y when
78  /// possible should be preferred.
79  IMATH_HOSTDEVICE constexpr const T& operator[] (int i) const IMATH_NOEXCEPT;
80 
81  /// @{
82  /// @name Constructors and Assignment
83 
84  /// Uninitialized by default
86 
87  /// Initialize to a scalar `(a,a)`
88  IMATH_HOSTDEVICE constexpr explicit Vec2 (T a) IMATH_NOEXCEPT;
89 
90  /// Initialize to given elements `(a,b)`
91  IMATH_HOSTDEVICE constexpr Vec2 (T a, T b) IMATH_NOEXCEPT;
92 
93  /// Copy constructor
94  IMATH_HOSTDEVICE constexpr Vec2 (const Vec2& v) IMATH_NOEXCEPT;
95 
96  /// Construct from Vec2 of another base type
97  template <class S>
98  IMATH_HOSTDEVICE constexpr Vec2 (const Vec2<S>& v) IMATH_NOEXCEPT;
99 
100  /// Assignment
101  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2&
102  operator= (const Vec2& v) IMATH_NOEXCEPT;
103 
104  /// Destructor
105  ~Vec2 () IMATH_NOEXCEPT = default;
106 
107  /// @}
108 
109 #if IMATH_FOREIGN_VECTOR_INTEROP
110  /// @{
111  /// @name Interoperability with other vector types
112  ///
113  /// Construction and assignment are allowed from other classes that
114  /// appear to be equivalent vector types, provided that they have either
115  /// a subscripting operator, or data members .x and .y, that are of the
116  /// same type as the elements of this vector, and their size appears to
117  /// be the right number of elements.
118  ///
119  /// This functionality is disabled for gcc 4.x, which seems to have a
120  /// compiler bug that results in spurious errors. It can also be
121  /// disabled by defining IMATH_FOREIGN_VECTOR_INTEROP to be 0 prior to
122  /// including any Imath header files.
123  ///
124 
126  IMATH_HOSTDEVICE explicit constexpr Vec2 (const V& v) IMATH_NOEXCEPT
127  : Vec2 (T (v.x), T (v.y))
128  {}
129 
130  template <
131  typename V,
133  IMATH_HOSTDEVICE explicit Vec2 (const V& v) : Vec2 (T (v[0]), T (v[1]))
134  {}
135 
137  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2&
138  operator= (const V& v) IMATH_NOEXCEPT
139  {
140  x = T (v.x);
141  y = T (v.y);
142  return *this;
143  }
144 
145  template <
146  typename V,
148  IMATH_HOSTDEVICE const Vec2& operator= (const V& v)
149  {
150  x = T (v[0]);
151  y = T (v[1]);
152  return *this;
153  }
154 #endif
155 
156  /// @{
157  /// @name Compatibility with Sb
158 
159  /// Set the value
160  template <class S> IMATH_HOSTDEVICE void setValue (S a, S b) IMATH_NOEXCEPT;
161 
162  /// Set the value
163  template <class S>
164  IMATH_HOSTDEVICE void setValue (const Vec2<S>& v) IMATH_NOEXCEPT;
165 
166  /// Return the value in `a` and `b`
167  template <class S>
168  IMATH_HOSTDEVICE void getValue (S& a, S& b) const IMATH_NOEXCEPT;
169 
170  /// Return the value in `v`
171  template <class S>
173 
174  /// Return a raw pointer to the array of values
175  IMATH_HOSTDEVICE T* getValue () IMATH_NOEXCEPT;
176 
177  /// Return a raw pointer to the array of values
178  IMATH_HOSTDEVICE const T* getValue () const IMATH_NOEXCEPT;
179 
180  /// @}
181 
182  /// @{
183  /// @name Arithmetic and Comparison
184 
185  /// Equality
186  template <class S>
187  IMATH_HOSTDEVICE constexpr bool
188  operator== (const Vec2<S>& v) const IMATH_NOEXCEPT;
189 
190  /// Inequality
191  template <class S>
192  IMATH_HOSTDEVICE constexpr bool
193  operator!= (const Vec2<S>& v) const IMATH_NOEXCEPT;
194 
195  /// Compare two vectors and test if they are "approximately equal":
196  /// @return True if the components of this and `v` are the same
197  /// with an absolute error of no more than e, i.e., for all i:
198  ///
199  /// abs (this[i] - v[i]) <= e
200  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool
201  equalWithAbsError (const Vec2<T>& v, T e) const IMATH_NOEXCEPT;
202 
203  /// Compare two vectors and test if they are "approximately equal":
204  /// @return True if the components of this and `v` are the same with
205  /// a relative error of no more than e, i.e., for all i:
206  ///
207  /// abs (this[i] - v[i]) <= e * abs (this[i])
208  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool
209  equalWithRelError (const Vec2<T>& v, T e) const IMATH_NOEXCEPT;
210 
211  /// Dot product
212  IMATH_HOSTDEVICE constexpr T dot (const Vec2& v) const IMATH_NOEXCEPT;
213 
214  /// Dot product
215  IMATH_HOSTDEVICE constexpr T operator^ (const Vec2& v) const IMATH_NOEXCEPT;
216 
217  /// Right-handed cross product, i.e. z component of
218  /// Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0)
219  IMATH_HOSTDEVICE constexpr T cross (const Vec2& v) const IMATH_NOEXCEPT;
220 
221  /// Right-handed cross product, i.e. z component of
222  /// Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0)
223  IMATH_HOSTDEVICE constexpr T operator% (const Vec2& v) const IMATH_NOEXCEPT;
224 
225  /// Component-wise addition
226  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2&
227  operator+= (const Vec2& v) IMATH_NOEXCEPT;
228 
229  /// Component-wise addition
230  IMATH_HOSTDEVICE constexpr Vec2
231  operator+ (const Vec2& v) const IMATH_NOEXCEPT;
232 
233  /// Component-wise subtraction
234  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2&
235  operator-= (const Vec2& v) IMATH_NOEXCEPT;
236 
237  /// Component-wise subtraction
238  IMATH_HOSTDEVICE constexpr Vec2
239  operator- (const Vec2& v) const IMATH_NOEXCEPT;
240 
241  /// Component-wise multiplication by -1
242  IMATH_HOSTDEVICE constexpr Vec2 operator- () const IMATH_NOEXCEPT;
243 
244  /// Component-wise multiplication by -1
245  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2& negate () IMATH_NOEXCEPT;
246 
247  /// Component-wise multiplication
248  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2&
249  operator*= (const Vec2& v) IMATH_NOEXCEPT;
250 
251  /// Component-wise multiplication
252  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2&
253  operator*= (T a) IMATH_NOEXCEPT;
254 
255  /// Component-wise multiplication
256  IMATH_HOSTDEVICE constexpr Vec2
257  operator* (const Vec2& v) const IMATH_NOEXCEPT;
258 
259  /// Component-wise multiplication
260  IMATH_HOSTDEVICE constexpr Vec2 operator* (T a) const IMATH_NOEXCEPT;
261 
262  /// Component-wise division
263  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2&
264  operator/= (const Vec2& v) IMATH_NOEXCEPT;
265 
266  /// Component-wise division
267  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2&
268  operator/= (T a) IMATH_NOEXCEPT;
269 
270  /// Component-wise division
271  IMATH_HOSTDEVICE constexpr Vec2
272  operator/ (const Vec2& v) const IMATH_NOEXCEPT;
273 
274  /// Component-wise division
275  IMATH_HOSTDEVICE constexpr Vec2 operator/ (T a) const IMATH_NOEXCEPT;
276 
277  /// @}
278 
279  /// @{
280  /// @name Query and Manipulation
281 
282  /// Return the Euclidean norm
283  IMATH_HOSTDEVICE T length () const IMATH_NOEXCEPT;
284 
285  /// Return the square of the Euclidean norm, i.e. the dot product
286  /// with itself.
287  IMATH_HOSTDEVICE constexpr T length2 () const IMATH_NOEXCEPT;
288 
289  /// Normalize in place. If length()==0, return a null vector.
290  IMATH_HOSTDEVICE const Vec2& normalize () IMATH_NOEXCEPT;
291 
292  /// Normalize in place. If length()==0, throw an exception.
293  const Vec2& normalizeExc ();
294 
295  /// Normalize without any checks for length()==0. Slightly faster
296  /// than the other normalization routines, but if v.length() is
297  /// 0.0, the result is undefined.
298  IMATH_HOSTDEVICE const Vec2& normalizeNonNull () IMATH_NOEXCEPT;
299 
300  /// Return a normalized vector. Does not modify *this.
301  IMATH_HOSTDEVICE Vec2<T> normalized () const IMATH_NOEXCEPT;
302 
303  /// Return a normalized vector. Does not modify *this. Throw an
304  /// exception if length()==0.
305  Vec2<T> normalizedExc () const;
306 
307  /// Return a normalized vector. Does not modify *this, and does
308  /// not check for length()==0. Slightly faster than the other
309  /// normalization routines, but if v.length() is 0.0, the result
310  /// is undefined.
311  IMATH_HOSTDEVICE Vec2<T> normalizedNonNull () const IMATH_NOEXCEPT;
312 
313  /// @}
314 
315  /// @{
316  /// @name Numeric Limits
317 
318  /// Largest possible negative value
319  IMATH_HOSTDEVICE constexpr static T baseTypeLowest () IMATH_NOEXCEPT
320  {
321  return std::numeric_limits<T>::lowest ();
322  }
323 
324  /// Largest possible positive value
325  IMATH_HOSTDEVICE constexpr static T baseTypeMax () IMATH_NOEXCEPT
326  {
327  return std::numeric_limits<T>::max ();
328  }
329 
330  /// Smallest possible positive value
331  IMATH_HOSTDEVICE constexpr static T baseTypeSmallest () IMATH_NOEXCEPT
332  {
333  return std::numeric_limits<T>::min ();
334  }
335 
336  /// Smallest possible e for which 1+e != 1
337  IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon () IMATH_NOEXCEPT
338  {
339  return std::numeric_limits<T>::epsilon ();
340  }
341 
342  /// @}
343 
344  /// Return the number of dimensions, i.e. 2
345  IMATH_HOSTDEVICE constexpr static unsigned int dimensions () IMATH_NOEXCEPT
346  {
347  return 2;
348  }
349 
350  /// The base type: In templates that accept a parameter `V`, you
351  /// can refer to `T` as `V::BaseType`
352  typedef T BaseType;
353 
354 private:
355  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T lengthTiny () const IMATH_NOEXCEPT;
356 };
357 
358 ///
359 /// 3-element vector
360 ///
361 
363 {
364 public:
365  /// @{
366  /// @name Direct access to elements
367 
368  T x, y, z;
369 
370  /// @}
371 
372  /// Element access by index.
373  ///
374  /// NB: This method of access uses dynamic array accesses which
375  /// can prevent compiler optimizations and force temporaries to be
376  /// stored to the stack and other missed vectorization
377  /// opportunities. Use of direct access to x, y, z when
378  /// possible should be preferred.
379  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T& operator[] (int i) IMATH_NOEXCEPT;
380 
381  /// Element access by index.
382  ///
383  /// NB: This method of access uses dynamic array accesses which
384  /// can prevent compiler optimizations and force temporaries to be
385  /// stored to the stack and other missed vectorization
386  /// opportunities. Use of direct access to x, y, z when
387  /// possible should be preferred.
388  IMATH_HOSTDEVICE constexpr const T& operator[] (int i) const IMATH_NOEXCEPT;
389 
390  /// @{
391  /// @name Constructors and Assignment
392 
393  /// Uninitialized by default
394  IMATH_HOSTDEVICE Vec3 () IMATH_NOEXCEPT;
395 
396  /// Initialize to a scalar `(a,a,a)`
397  IMATH_HOSTDEVICE constexpr explicit Vec3 (T a) IMATH_NOEXCEPT;
398 
399  /// Initialize to given elements `(a,b,c)`
400  IMATH_HOSTDEVICE constexpr Vec3 (T a, T b, T c) IMATH_NOEXCEPT;
401 
402  /// Copy constructor
403  IMATH_HOSTDEVICE constexpr Vec3 (const Vec3& v) IMATH_NOEXCEPT;
404 
405  /// Construct from Vec3 of another base type
406  template <class S>
407  IMATH_HOSTDEVICE constexpr Vec3 (const Vec3<S>& v) IMATH_NOEXCEPT;
408 
409  /// Vec4 to Vec3 conversion: divide x, y and z by w, even if w is
410  /// 0. The result depends on how the environment handles
411  /// floating-point exceptions.
412  template <class S>
413  IMATH_HOSTDEVICE explicit constexpr Vec3 (const Vec4<S>& v) IMATH_NOEXCEPT;
414 
415  /// Vec4 to Vec3 conversion: divide x, y and z by w. Throws an
416  /// exception if w is zero or if division by w would overflow.
417  template <class S>
418  explicit IMATH_HOSTDEVICE IMATH_CONSTEXPR14
419  Vec3 (const Vec4<S>& v, InfException);
420 
421  /// Assignment
422  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3&
423  operator= (const Vec3& v) IMATH_NOEXCEPT;
424 
425  /// Destructor
426  ~Vec3 () IMATH_NOEXCEPT = default;
427 
428  /// @}
429 
430 #if IMATH_FOREIGN_VECTOR_INTEROP
431  /// @{
432  /// @name Interoperability with other vector types
433  ///
434  /// Construction and assignment are allowed from other classes that
435  /// appear to be equivalent vector types, provided that they have either
436  /// a subscripting operator, or data members .x, .y, .z, that are of the
437  /// same type as the elements of this vector, and their size appears to
438  /// be the right number of elements.
439  ///
440  /// This functionality is disabled for gcc 4.x, which seems to have a
441  /// compiler bug that results in spurious errors. It can also be
442  /// disabled by defining IMATH_FOREIGN_VECTOR_INTEROP to be 0 prior to
443  /// including any Imath header files.
444  ///
445 
447  IMATH_HOSTDEVICE explicit constexpr Vec3 (const V& v) IMATH_NOEXCEPT
448  : Vec3 (T (v.x), T (v.y), T (v.z))
449  {}
450 
451  template <
452  typename V,
455  IMATH_HOSTDEVICE explicit Vec3 (const V& v)
456  : Vec3 (T (v[0]), T (v[1]), T (v[2]))
457  {}
458 
459  /// Interoperability assignment from another type that behaves as if it
460  /// were an equivalent vector.
462  IMATH_HOSTDEVICE const Vec3& operator= (const V& v) IMATH_NOEXCEPT
463  {
464  x = T (v.x);
465  y = T (v.y);
466  z = T (v.z);
467  return *this;
468  }
469 
470  template <
471  typename V,
474  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& operator= (const V& v)
475  {
476  x = T (v[0]);
477  y = T (v[1]);
478  z = T (v[2]);
479  return *this;
480  }
481  /// @}
482 #endif
483 
484  /// @{
485  /// @name Compatibility with Sb
486 
487  /// Set the value
488  template <class S>
489  IMATH_HOSTDEVICE void setValue (S a, S b, S c) IMATH_NOEXCEPT;
490 
491  /// Set the value
492  template <class S>
493  IMATH_HOSTDEVICE void setValue (const Vec3<S>& v) IMATH_NOEXCEPT;
494 
495  /// Return the value in `a`, `b`, and `c`
496  template <class S>
497  IMATH_HOSTDEVICE void getValue (S& a, S& b, S& c) const IMATH_NOEXCEPT;
498 
499  /// Return the value in `v`
500  template <class S>
502 
503  /// Return a raw pointer to the array of values
504  IMATH_HOSTDEVICE T* getValue () IMATH_NOEXCEPT;
505 
506  /// Return a raw pointer to the array of values
507  IMATH_HOSTDEVICE const T* getValue () const IMATH_NOEXCEPT;
508 
509  /// @}
510 
511  /// @{
512  /// @name Arithmetic and Comparison
513 
514  /// Equality
515  template <class S>
516  IMATH_HOSTDEVICE constexpr bool
517  operator== (const Vec3<S>& v) const IMATH_NOEXCEPT;
518 
519  /// Inequality
520  template <class S>
521  IMATH_HOSTDEVICE constexpr bool
522  operator!= (const Vec3<S>& v) const IMATH_NOEXCEPT;
523 
524  /// Compare two vectors and test if they are "approximately equal":
525  /// @return True if the components of this and `v` are the same
526  /// with an absolute error of no more than e, i.e., for all i:
527  ///
528  /// abs (this[i] - v[i]) <= e
529  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool
530  equalWithAbsError (const Vec3<T>& v, T e) const IMATH_NOEXCEPT;
531 
532  /// Compare two vectors and test if they are "approximately equal":
533  /// @return True if the components of this and `v` are the same with
534  /// a relative error of no more than e, i.e., for all i:
535  ///
536  /// abs (this[i] - v[i]) <= e * abs (this[i])
537  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool
538  equalWithRelError (const Vec3<T>& v, T e) const IMATH_NOEXCEPT;
539 
540  /// Dot product
541  IMATH_HOSTDEVICE constexpr T dot (const Vec3& v) const IMATH_NOEXCEPT;
542 
543  /// Dot product
544  IMATH_HOSTDEVICE constexpr T operator^ (const Vec3& v) const IMATH_NOEXCEPT;
545 
546  /// Right-handed cross product
547  IMATH_HOSTDEVICE constexpr Vec3 cross (const Vec3& v) const IMATH_NOEXCEPT;
548 
549  /// Right-handed cross product
550  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3&
551  operator%= (const Vec3& v) IMATH_NOEXCEPT;
552 
553  /// Right-handed cross product
554  IMATH_HOSTDEVICE constexpr Vec3
555  operator% (const Vec3& v) const IMATH_NOEXCEPT;
556 
557  /// Component-wise addition
558  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3&
559  operator+= (const Vec3& v) IMATH_NOEXCEPT;
560 
561  /// Component-wise addition
562  IMATH_HOSTDEVICE constexpr Vec3
563  operator+ (const Vec3& v) const IMATH_NOEXCEPT;
564 
565  /// Component-wise subtraction
566  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3&
567  operator-= (const Vec3& v) IMATH_NOEXCEPT;
568 
569  /// Component-wise subtraction
570  IMATH_HOSTDEVICE constexpr Vec3
571  operator- (const Vec3& v) const IMATH_NOEXCEPT;
572 
573  /// Component-wise multiplication by -1
574  IMATH_HOSTDEVICE constexpr Vec3 operator- () const IMATH_NOEXCEPT;
575 
576  /// Component-wise multiplication by -1
577  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3& negate () IMATH_NOEXCEPT;
578 
579  /// Component-wise multiplication
580  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3&
581  operator*= (const Vec3& v) IMATH_NOEXCEPT;
582 
583  /// Component-wise multiplication
584  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3&
585  operator*= (T a) IMATH_NOEXCEPT;
586 
587  /// Component-wise multiplication
588  IMATH_HOSTDEVICE constexpr Vec3
589  operator* (const Vec3& v) const IMATH_NOEXCEPT;
590 
591  /// Component-wise multiplication
592  IMATH_HOSTDEVICE constexpr Vec3 operator* (T a) const IMATH_NOEXCEPT;
593 
594  /// Component-wise division
595  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3&
596  operator/= (const Vec3& v) IMATH_NOEXCEPT;
597 
598  /// Component-wise division
599  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3&
600  operator/= (T a) IMATH_NOEXCEPT;
601 
602  /// Component-wise division
603  IMATH_HOSTDEVICE constexpr Vec3
604  operator/ (const Vec3& v) const IMATH_NOEXCEPT;
605 
606  /// Component-wise division
607  IMATH_HOSTDEVICE constexpr Vec3 operator/ (T a) const IMATH_NOEXCEPT;
608 
609  /// @}
610 
611  /// @{
612  /// @name Query and Manipulation
613 
614  /// Return the Euclidean norm
615  IMATH_HOSTDEVICE T length () const IMATH_NOEXCEPT;
616 
617  /// Return the square of the Euclidean norm, i.e. the dot product
618  /// with itself.
619  IMATH_HOSTDEVICE constexpr T length2 () const IMATH_NOEXCEPT;
620 
621  /// Normalize in place. If length()==0, return a null vector.
622  IMATH_HOSTDEVICE const Vec3& normalize () IMATH_NOEXCEPT;
623 
624  /// Normalize in place. If length()==0, throw an exception.
625  const Vec3& normalizeExc ();
626 
627  /// Normalize without any checks for length()==0. Slightly faster
628  /// than the other normalization routines, but if v.length() is
629  /// 0.0, the result is undefined.
630  IMATH_HOSTDEVICE const Vec3& normalizeNonNull () IMATH_NOEXCEPT;
631 
632  /// Return a normalized vector. Does not modify *this.
633  IMATH_HOSTDEVICE Vec3<T>
634  normalized () const IMATH_NOEXCEPT; // does not modify *this
635 
636  /// Return a normalized vector. Does not modify *this. Throw an
637  /// exception if length()==0.
638  Vec3<T> normalizedExc () const;
639 
640  /// Return a normalized vector. Does not modify *this, and does
641  /// not check for length()==0. Slightly faster than the other
642  /// normalization routines, but if v.length() is 0.0, the result
643  /// is undefined.
644  IMATH_HOSTDEVICE Vec3<T> normalizedNonNull () const IMATH_NOEXCEPT;
645 
646  /// @}
647 
648  /// @{
649  /// @name Numeric Limits
650 
651  /// Largest possible negative value
652  IMATH_HOSTDEVICE constexpr static T baseTypeLowest () IMATH_NOEXCEPT
653  {
654  return std::numeric_limits<T>::lowest ();
655  }
656 
657  /// Largest possible positive value
658  IMATH_HOSTDEVICE constexpr static T baseTypeMax () IMATH_NOEXCEPT
659  {
660  return std::numeric_limits<T>::max ();
661  }
662 
663  /// Smallest possible positive value
664  IMATH_HOSTDEVICE constexpr static T baseTypeSmallest () IMATH_NOEXCEPT
665  {
666  return std::numeric_limits<T>::min ();
667  }
668 
669  /// Smallest possible e for which 1+e != 1
670  IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon () IMATH_NOEXCEPT
671  {
672  return std::numeric_limits<T>::epsilon ();
673  }
674 
675  /// @}
676 
677  /// Return the number of dimensions, i.e. 3
678  IMATH_HOSTDEVICE constexpr static unsigned int dimensions () IMATH_NOEXCEPT
679  {
680  return 3;
681  }
682 
683  /// The base type: In templates that accept a parameter `V`, you
684  /// can refer to `T` as `V::BaseType`
685  typedef T BaseType;
686 
687 private:
688  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T lengthTiny () const IMATH_NOEXCEPT;
689 };
690 
691 ///
692 /// 4-element vector
693 ///
694 
696 {
697 public:
698  /// @{
699  /// @name Direct access to elements
700 
701  T x, y, z, w;
702 
703  /// @}
704 
705  /// Element access by index.
706  ///
707  /// NB: This method of access uses dynamic array accesses which
708  /// can prevent compiler optimizations and force temporaries to be
709  /// stored to the stack and other missed vectorization
710  /// opportunities. Use of direct access to x, y, z, w when
711  /// possible should be preferred.
712  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T& operator[] (int i) IMATH_NOEXCEPT;
713 
714  /// Element access by index.
715  ///
716  /// NB: This method of access uses dynamic array accesses which
717  /// can prevent compiler optimizations and force temporaries to be
718  /// stored to the stack and other missed vectorization
719  /// opportunities. Use of direct access to x, y, z, w when
720  /// possible should be preferred.
721  IMATH_HOSTDEVICE constexpr const T& operator[] (int i) const IMATH_NOEXCEPT;
722 
723  /// @{
724  /// @name Constructors and Assignment
725 
726  /// Uninitialized by default
727  IMATH_HOSTDEVICE Vec4 () IMATH_NOEXCEPT; // no initialization
728 
729  /// Initialize to a scalar `(a,a,a,a)`
730  IMATH_HOSTDEVICE constexpr explicit Vec4 (T a) IMATH_NOEXCEPT;
731 
732  /// Initialize to given elements `(a,b,c,d)`
733  IMATH_HOSTDEVICE constexpr Vec4 (T a, T b, T c, T d) IMATH_NOEXCEPT;
734 
735  /// Copy constructor
736  IMATH_HOSTDEVICE constexpr Vec4 (const Vec4& v) IMATH_NOEXCEPT;
737 
738  /// Construct from Vec4 of another base type
739  template <class S>
740  IMATH_HOSTDEVICE constexpr Vec4 (const Vec4<S>& v) IMATH_NOEXCEPT;
741 
742  /// Vec3 to Vec4 conversion, sets w to 1.
743  template <class S>
744  IMATH_HOSTDEVICE explicit constexpr Vec4 (const Vec3<S>& v) IMATH_NOEXCEPT;
745 
746  /// Assignment
747  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4&
748  operator= (const Vec4& v) IMATH_NOEXCEPT;
749 
750  /// Destructor
751  ~Vec4 () IMATH_NOEXCEPT = default;
752 
753  /// @}
754 
755 #if IMATH_FOREIGN_VECTOR_INTEROP
756  /// @{
757  /// @name Interoperability with other vector types
758  ///
759  /// Construction and assignment are allowed from other classes that
760  /// appear to be equivalent vector types, provided that they have either
761  /// a subscripting operator, or data members .x, .y, .z, .w that are of
762  /// the same type as the elements of this vector, and their size appears
763  /// to be the right number of elements.
764  ///
765  /// This functionality is disabled for gcc 4.x, which seems to have a
766  /// compiler bug that results in spurious errors. It can also be
767  /// disabled by defining IMATH_FOREIGN_VECTOR_INTEROP to be 0 prior to
768  /// including any Imath header files.
769  ///
770 
772  IMATH_HOSTDEVICE explicit constexpr Vec4 (const V& v) IMATH_NOEXCEPT
773  : Vec4 (T (v.x), T (v.y), T (v.z), T (v.w))
774  {}
775 
776  template <
777  typename V,
780  IMATH_HOSTDEVICE explicit Vec4 (const V& v)
781  : Vec4 (T (v[0]), T (v[1]), T (v[2]), T (v[3]))
782  {}
783 
785  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4&
786  operator= (const V& v) IMATH_NOEXCEPT
787  {
788  x = T (v.x);
789  y = T (v.y);
790  z = T (v.z);
791  w = T (v.w);
792  return *this;
793  }
794 
795  template <
796  typename V,
799  IMATH_HOSTDEVICE const Vec4& operator= (const V& v)
800  {
801  x = T (v[0]);
802  y = T (v[1]);
803  z = T (v[2]);
804  w = T (v[3]);
805  return *this;
806  }
807  /// @}
808 #endif
809 
810  /// @{
811  /// @name Compatibility with Sb
812 
813  /// Set the value
814  template <class S> IMATH_HOSTDEVICE void setValue (S a, S b, S c, S d) IMATH_NOEXCEPT;
815 
816  /// Set the value
817  template <class S>
818  IMATH_HOSTDEVICE void setValue (const Vec4<S>& v) IMATH_NOEXCEPT;
819 
820  /// Return the value in `a` and `b`
821  template <class S>
822  IMATH_HOSTDEVICE void getValue (S& a, S& b, S& c, S& d) const IMATH_NOEXCEPT;
823 
824  /// Return the value in `v`
825  template <class S>
827 
828  /// Return a raw pointer to the array of values
829  IMATH_HOSTDEVICE T* getValue () IMATH_NOEXCEPT;
830 
831  /// Return a raw pointer to the array of values
832  IMATH_HOSTDEVICE const T* getValue () const IMATH_NOEXCEPT;
833 
834  /// @}
835 
836  /// @{
837  /// @name Arithmetic and Comparison
838 
839  /// Equality
840  template <class S>
841  IMATH_HOSTDEVICE constexpr bool
842  operator== (const Vec4<S>& v) const IMATH_NOEXCEPT;
843 
844  /// Inequality
845  template <class S>
846  IMATH_HOSTDEVICE constexpr bool
847  operator!= (const Vec4<S>& v) const IMATH_NOEXCEPT;
848 
849  /// Compare two vectors and test if they are "approximately equal":
850  /// @return True if the components of this and `v` are the same
851  /// with an absolute error of no more than e, i.e., for all i:
852  ///
853  /// abs (this[i] - v[i]) <= e
854  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool
855  equalWithAbsError (const Vec4<T>& v, T e) const IMATH_NOEXCEPT;
856 
857  /// Compare two vectors and test if they are "approximately equal":
858  /// @return True if the components of this and `v` are the same with
859  /// a relative error of no more than e, i.e., for all i:
860  ///
861  /// abs (this[i] - v[i]) <= e * abs (this[i])
862  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool
863  equalWithRelError (const Vec4<T>& v, T e) const IMATH_NOEXCEPT;
864 
865  /// Dot product
866  IMATH_HOSTDEVICE constexpr T dot (const Vec4& v) const IMATH_NOEXCEPT;
867 
868  /// Dot product
869  IMATH_HOSTDEVICE constexpr T operator^ (const Vec4& v) const IMATH_NOEXCEPT;
870 
871  /// Component-wise addition
872  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4&
873  operator+= (const Vec4& v) IMATH_NOEXCEPT;
874 
875  /// Component-wise addition
876  IMATH_HOSTDEVICE constexpr Vec4
877  operator+ (const Vec4& v) const IMATH_NOEXCEPT;
878 
879  /// Component-wise subtraction
880  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4&
881  operator-= (const Vec4& v) IMATH_NOEXCEPT;
882 
883  /// Component-wise subtraction
884  IMATH_HOSTDEVICE constexpr Vec4
885  operator- (const Vec4& v) const IMATH_NOEXCEPT;
886 
887  /// Component-wise multiplication by -1
888  IMATH_HOSTDEVICE constexpr Vec4 operator- () const IMATH_NOEXCEPT;
889 
890  /// Component-wise multiplication by -1
891  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4& negate () IMATH_NOEXCEPT;
892 
893  /// Component-wise multiplication
894  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4&
895  operator*= (const Vec4& v) IMATH_NOEXCEPT;
896 
897  /// Component-wise multiplication
898  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4&
899  operator*= (T a) IMATH_NOEXCEPT;
900 
901  /// Component-wise multiplication
902  IMATH_HOSTDEVICE constexpr Vec4
903  operator* (const Vec4& v) const IMATH_NOEXCEPT;
904 
905  /// Component-wise multiplication
906  IMATH_HOSTDEVICE constexpr Vec4 operator* (T a) const IMATH_NOEXCEPT;
907 
908  /// Component-wise division
909  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4&
910  operator/= (const Vec4& v) IMATH_NOEXCEPT;
911 
912  /// Component-wise division
913  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4&
914  operator/= (T a) IMATH_NOEXCEPT;
915 
916  /// Component-wise division
917  IMATH_HOSTDEVICE constexpr Vec4
918  operator/ (const Vec4& v) const IMATH_NOEXCEPT;
919 
920  /// Component-wise division
921  IMATH_HOSTDEVICE constexpr Vec4 operator/ (T a) const IMATH_NOEXCEPT;
922 
923  /// @}
924 
925  /// @{
926  /// @name Query and Manipulation
927 
928  /// Return the Euclidean norm
929  IMATH_HOSTDEVICE T length () const IMATH_NOEXCEPT;
930 
931  /// Return the square of the Euclidean norm, i.e. the dot product
932  /// with itself.
933  IMATH_HOSTDEVICE constexpr T length2 () const IMATH_NOEXCEPT;
934 
935  /// Normalize in place. If length()==0, return a null vector.
936  IMATH_HOSTDEVICE const Vec4& normalize () IMATH_NOEXCEPT; // modifies *this
937 
938  /// Normalize in place. If length()==0, throw an exception.
939  const Vec4& normalizeExc ();
940 
941  /// Normalize without any checks for length()==0. Slightly faster
942  /// than the other normalization routines, but if v.length() is
943  /// 0.0, the result is undefined.
944  IMATH_HOSTDEVICE const Vec4& normalizeNonNull () IMATH_NOEXCEPT;
945 
946  /// Return a normalized vector. Does not modify *this.
947  IMATH_HOSTDEVICE Vec4<T>
948  normalized () const IMATH_NOEXCEPT; // does not modify *this
949 
950  /// Return a normalized vector. Does not modify *this. Throw an
951  /// exception if length()==0.
952  Vec4<T> normalizedExc () const;
953 
954  /// Return a normalized vector. Does not modify *this, and does
955  /// not check for length()==0. Slightly faster than the other
956  /// normalization routines, but if v.length() is 0.0, the result
957  /// is undefined.
958  IMATH_HOSTDEVICE Vec4<T> normalizedNonNull () const IMATH_NOEXCEPT;
959 
960  /// @}
961 
962  /// @{
963  /// @name Numeric Limits
964 
965  /// Largest possible negative value
966  IMATH_HOSTDEVICE constexpr static T baseTypeLowest () IMATH_NOEXCEPT
967  {
968  return std::numeric_limits<T>::lowest ();
969  }
970 
971  /// Largest possible positive value
972  IMATH_HOSTDEVICE constexpr static T baseTypeMax () IMATH_NOEXCEPT
973  {
974  return std::numeric_limits<T>::max ();
975  }
976 
977  /// Smallest possible positive value
978  IMATH_HOSTDEVICE constexpr static T baseTypeSmallest () IMATH_NOEXCEPT
979  {
980  return std::numeric_limits<T>::min ();
981  }
982 
983  /// Smallest possible e for which 1+e != 1
984  IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon () IMATH_NOEXCEPT
985  {
986  return std::numeric_limits<T>::epsilon ();
987  }
988 
989  /// @}
990 
991  /// Return the number of dimensions, i.e. 4
992  IMATH_HOSTDEVICE constexpr static unsigned int dimensions () IMATH_NOEXCEPT
993  {
994  return 4;
995  }
996 
997  /// The base type: In templates that accept a parameter `V`, you
998  /// can refer to `T` as `V::BaseType`
999  typedef T BaseType;
1000 
1001 private:
1002  IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T lengthTiny () const IMATH_NOEXCEPT;
1003 };
1004 
1005 /// Stream output, as "(x y)"
1006 template <class T> std::ostream& operator<< (std::ostream& s, const Vec2<T>& v);
1007 
1008 /// Stream output, as "(x y z)"
1009 template <class T> std::ostream& operator<< (std::ostream& s, const Vec3<T>& v);
1010 
1011 /// Stream output, as "(x y z w)"
1012 template <class T> std::ostream& operator<< (std::ostream& s, const Vec4<T>& v);
1013 
1014 /// Reverse multiplication: S * Vec2<T>
1015 template <class T>
1016 IMATH_HOSTDEVICE constexpr Vec2<T>
1017 operator* (T a, const Vec2<T>& v) IMATH_NOEXCEPT;
1018 
1019 /// Reverse multiplication: S * Vec3<T>
1020 template <class T>
1021 IMATH_HOSTDEVICE constexpr Vec3<T>
1022 operator* (T a, const Vec3<T>& v) IMATH_NOEXCEPT;
1023 
1024 /// Reverse multiplication: S * Vec4<T>
1025 template <class T>
1026 IMATH_HOSTDEVICE constexpr Vec4<T>
1027 operator* (T a, const Vec4<T>& v) IMATH_NOEXCEPT;
1028 
1029 //-------------------------
1030 // Typedefs for convenience
1031 //-------------------------
1032 
1033 /// Vec2 of half
1034 typedef Vec2<half> V2h;
1035 
1036 /// Vec2 of short
1037 typedef Vec2<short> V2s;
1038 
1039 /// Vec2 of integer
1040 typedef Vec2<int> V2i;
1041 
1042 /// Vec2 of int64_t
1043 typedef Vec2<int64_t> V2i64;
1044 
1045 /// Vec2 of float
1046 typedef Vec2<float> V2f;
1047 
1048 /// Vec2 of double
1049 typedef Vec2<double> V2d;
1050 
1051 /// Vec3 of half
1052 typedef Vec3<half> V3h;
1053 
1054 /// Vec3 of short
1055 typedef Vec3<short> V3s;
1056 
1057 /// Vec3 of integer
1058 typedef Vec3<int> V3i;
1059 
1060 /// Vec3 of int64_t
1061 typedef Vec3<int64_t> V3i64;
1062 
1063 /// Vec3 of float
1064 typedef Vec3<float> V3f;
1065 
1066 /// Vec3 of double
1067 typedef Vec3<double> V3d;
1068 
1069 /// Vec4 of half
1070 typedef Vec4<half> V4h;
1071 
1072 /// Vec4 of short
1073 typedef Vec4<short> V4s;
1074 
1075 /// Vec4 of integer
1076 typedef Vec4<int> V4i;
1077 
1078 /// Vec4 of int64_t
1079 typedef Vec4<int64_t> V4i64;
1080 
1081 /// Vec4 of float
1082 typedef Vec4<float> V4f;
1083 
1084 /// Vec4 of double
1085 typedef Vec4<double> V4d;
1086 
1087 //----------------------------------------------------------------------------
1088 // Specializations for VecN<short>, VecN<int>
1089 //
1090 // Normalize and length don't make sense for integer vectors, so disable them.
1091 //----------------------------------------------------------------------------
1092 
1093 /// @cond Doxygen_Suppress
1094 
1095 // Vec2<short>
1096 template <>
1097 IMATH_HOSTDEVICE short Vec2<short>::length () const IMATH_NOEXCEPT = delete;
1098 template <>
1099 IMATH_HOSTDEVICE const Vec2<short>&
1100  Vec2<short>::normalize () IMATH_NOEXCEPT = delete;
1101 template <> const Vec2<short>& Vec2<short>::normalizeExc () = delete;
1102 template <>
1103 IMATH_HOSTDEVICE const Vec2<short>&
1104  Vec2<short>::normalizeNonNull () IMATH_NOEXCEPT = delete;
1105 template <>
1106 IMATH_HOSTDEVICE Vec2<short>
1107  Vec2<short>::normalized () const IMATH_NOEXCEPT = delete;
1108 template <> Vec2<short> Vec2<short>::normalizedExc () const = delete;
1109 template <>
1110 IMATH_HOSTDEVICE Vec2<short>
1111 Vec2<short>::normalizedNonNull () const IMATH_NOEXCEPT = delete;
1112 
1113 // Vec2<int>
1114 template <>
1115 IMATH_HOSTDEVICE int Vec2<int>::length () const IMATH_NOEXCEPT = delete;
1116 template <>
1117 IMATH_HOSTDEVICE const Vec2<int>&
1118  Vec2<int>::normalize () IMATH_NOEXCEPT = delete;
1119 template <> const Vec2<int>& Vec2<int>::normalizeExc () = delete;
1120 template <>
1121 IMATH_HOSTDEVICE const Vec2<int>&
1122  Vec2<int>::normalizeNonNull () IMATH_NOEXCEPT = delete;
1123 template <>
1125  Vec2<int>::normalized () const IMATH_NOEXCEPT = delete;
1126 template <> Vec2<int> Vec2<int>::normalizedExc () const = delete;
1127 template <>
1129  Vec2<int>::normalizedNonNull () const IMATH_NOEXCEPT = delete;
1130 
1131 // Vec2<int64_t>
1132 template <>
1133 IMATH_HOSTDEVICE int64_t Vec2<int64_t>::length () const IMATH_NOEXCEPT = delete;
1134 template <>
1135 IMATH_HOSTDEVICE const Vec2<int64_t>&
1136  Vec2<int64_t>::normalize () IMATH_NOEXCEPT = delete;
1137 template <> const Vec2<int64_t>& Vec2<int64_t>::normalizeExc () = delete;
1138 template <>
1139 IMATH_HOSTDEVICE const Vec2<int64_t>&
1140 Vec2<int64_t>::normalizeNonNull () IMATH_NOEXCEPT = delete;
1141 template <>
1142 IMATH_HOSTDEVICE Vec2<int64_t>
1143  Vec2<int64_t>::normalized () const IMATH_NOEXCEPT = delete;
1144 template <> Vec2<int64_t> Vec2<int64_t>::normalizedExc () const = delete;
1145 template <>
1146 IMATH_HOSTDEVICE Vec2<int64_t>
1147 Vec2<int64_t>::normalizedNonNull () const IMATH_NOEXCEPT = delete;
1148 
1149 // Vec3<short>
1150 template <>
1151 IMATH_HOSTDEVICE short Vec3<short>::length () const IMATH_NOEXCEPT = delete;
1152 template <>
1153 IMATH_HOSTDEVICE const Vec3<short>&
1154  Vec3<short>::normalize () IMATH_NOEXCEPT = delete;
1155 template <> const Vec3<short>& Vec3<short>::normalizeExc () = delete;
1156 template <>
1157 IMATH_HOSTDEVICE const Vec3<short>&
1158  Vec3<short>::normalizeNonNull () IMATH_NOEXCEPT = delete;
1159 template <>
1160 IMATH_HOSTDEVICE Vec3<short>
1161  Vec3<short>::normalized () const IMATH_NOEXCEPT = delete;
1162 template <> Vec3<short> Vec3<short>::normalizedExc () const = delete;
1163 template <>
1164 IMATH_HOSTDEVICE Vec3<short>
1165 Vec3<short>::normalizedNonNull () const IMATH_NOEXCEPT = delete;
1166 
1167 // Vec3<int>
1168 template <>
1169 IMATH_HOSTDEVICE int Vec3<int>::length () const IMATH_NOEXCEPT = delete;
1170 template <>
1171 IMATH_HOSTDEVICE const Vec3<int>&
1172  Vec3<int>::normalize () IMATH_NOEXCEPT = delete;
1173 template <> const Vec3<int>& Vec3<int>::normalizeExc () = delete;
1174 template <>
1175 IMATH_HOSTDEVICE const Vec3<int>&
1176  Vec3<int>::normalizeNonNull () IMATH_NOEXCEPT = delete;
1177 template <>
1178 IMATH_HOSTDEVICE Vec3<int>
1179  Vec3<int>::normalized () const IMATH_NOEXCEPT = delete;
1180 template <> Vec3<int> Vec3<int>::normalizedExc () const = delete;
1181 template <>
1182 IMATH_HOSTDEVICE Vec3<int>
1183  Vec3<int>::normalizedNonNull () const IMATH_NOEXCEPT = delete;
1184 
1185 // Vec3<int64_t>
1186 template <>
1187 IMATH_HOSTDEVICE int64_t Vec3<int64_t>::length () const IMATH_NOEXCEPT = delete;
1188 template <>
1189 IMATH_HOSTDEVICE const Vec3<int64_t>&
1190  Vec3<int64_t>::normalize () IMATH_NOEXCEPT = delete;
1191 template <> const Vec3<int64_t>& Vec3<int64_t>::normalizeExc () = delete;
1192 template <>
1193 IMATH_HOSTDEVICE const Vec3<int64_t>&
1194 Vec3<int64_t>::normalizeNonNull () IMATH_NOEXCEPT = delete;
1195 template <>
1196 IMATH_HOSTDEVICE Vec3<int64_t>
1197  Vec3<int64_t>::normalized () const IMATH_NOEXCEPT = delete;
1198 template <> Vec3<int64_t> Vec3<int64_t>::normalizedExc () const = delete;
1199 template <>
1200 IMATH_HOSTDEVICE Vec3<int64_t>
1201 Vec3<int64_t>::normalizedNonNull () const IMATH_NOEXCEPT = delete;
1202 
1203 // Vec4<short>
1204 template <>
1205 IMATH_HOSTDEVICE short Vec4<short>::length () const IMATH_NOEXCEPT = delete;
1206 template <>
1207 IMATH_HOSTDEVICE const Vec4<short>&
1208  Vec4<short>::normalize () IMATH_NOEXCEPT = delete;
1209 template <> const Vec4<short>& Vec4<short>::normalizeExc () = delete;
1210 template <>
1211 IMATH_HOSTDEVICE const Vec4<short>&
1212  Vec4<short>::normalizeNonNull () IMATH_NOEXCEPT = delete;
1213 template <>
1214 IMATH_HOSTDEVICE Vec4<short>
1215  Vec4<short>::normalized () const IMATH_NOEXCEPT = delete;
1216 template <> Vec4<short> Vec4<short>::normalizedExc () const = delete;
1217 template <>
1218 IMATH_HOSTDEVICE Vec4<short>
1219 Vec4<short>::normalizedNonNull () const IMATH_NOEXCEPT = delete;
1220 
1221 // Vec4<int>
1222 template <>
1223 IMATH_HOSTDEVICE int Vec4<int>::length () const IMATH_NOEXCEPT = delete;
1224 template <>
1225 IMATH_HOSTDEVICE const Vec4<int>&
1226  Vec4<int>::normalize () IMATH_NOEXCEPT = delete;
1227 template <> const Vec4<int>& Vec4<int>::normalizeExc () = delete;
1228 template <>
1229 IMATH_HOSTDEVICE const Vec4<int>&
1230  Vec4<int>::normalizeNonNull () IMATH_NOEXCEPT = delete;
1231 template <>
1232 IMATH_HOSTDEVICE Vec4<int>
1233  Vec4<int>::normalized () const IMATH_NOEXCEPT = delete;
1234 template <> Vec4<int> Vec4<int>::normalizedExc () const = delete;
1235 template <>
1236 IMATH_HOSTDEVICE Vec4<int>
1237  Vec4<int>::normalizedNonNull () const IMATH_NOEXCEPT = delete;
1238 
1239 // Vec4<int64_t>
1240 template <>
1241 IMATH_HOSTDEVICE int64_t Vec4<int64_t>::length () const IMATH_NOEXCEPT = delete;
1242 template <>
1243 IMATH_HOSTDEVICE const Vec4<int64_t>&
1244  Vec4<int64_t>::normalize () IMATH_NOEXCEPT = delete;
1245 template <> const Vec4<int64_t>& Vec4<int64_t>::normalizeExc () = delete;
1246 template <>
1247 IMATH_HOSTDEVICE const Vec4<int64_t>&
1248 Vec4<int64_t>::normalizeNonNull () IMATH_NOEXCEPT = delete;
1249 template <>
1250 IMATH_HOSTDEVICE Vec4<int64_t>
1251  Vec4<int64_t>::normalized () const IMATH_NOEXCEPT = delete;
1252 template <> Vec4<int64_t> Vec4<int64_t>::normalizedExc () const = delete;
1253 template <>
1254 IMATH_HOSTDEVICE Vec4<int64_t>
1255 Vec4<int64_t>::normalizedNonNull () const IMATH_NOEXCEPT = delete;
1256 
1257 /// @endcond Doxygen_Suppress
1258 
1259 //------------------------
1260 // Implementation of Vec2:
1261 //------------------------
1262 
1263 template <class T>
1264 IMATH_CONSTEXPR14 IMATH_HOSTDEVICE inline T&
1265 Vec2<T>::operator[] (int i) IMATH_NOEXCEPT
1266 {
1267  return reinterpret_cast<T*> (this)[i];
1268 }
1269 
1270 template <class T>
1271 constexpr IMATH_HOSTDEVICE inline const T&
1272 Vec2<T>::operator[] (int i) const IMATH_NOEXCEPT
1273 {
1274 #ifdef __cpp_if_consteval
1275  if consteval
1276  {
1277  return (i == 0) ? x : y;
1278  }
1279  else
1280  {
1281  return reinterpret_cast<const T*> (this)[i];
1282  }
1283 #else
1284  return reinterpret_cast<const T*> (this)[i];
1285 #endif
1286 }
1287 
1288 template <class T> IMATH_HOSTDEVICE inline Vec2<T>::Vec2 () IMATH_NOEXCEPT
1289 {
1290  // empty, and not constexpr because data is uninitialized.
1291 }
1292 
1293 template <class T>
1294 IMATH_HOSTDEVICE constexpr inline Vec2<T>::Vec2 (T a) IMATH_NOEXCEPT : x (a),
1295  y (a)
1296 {}
1297 
1298 template <class T>
1299 IMATH_HOSTDEVICE constexpr inline Vec2<T>::Vec2 (T a, T b) IMATH_NOEXCEPT
1300  : x (a),
1301  y (b)
1302 {}
1303 
1304 template <class T>
1305 IMATH_HOSTDEVICE constexpr inline Vec2<T>::Vec2 (const Vec2& v) IMATH_NOEXCEPT
1306  : x (v.x),
1307  y (v.y)
1308 {}
1309 
1310 template <class T>
1311 template <class S>
1312 IMATH_HOSTDEVICE constexpr inline Vec2<T>::Vec2 (const Vec2<S>& v)
1313  IMATH_NOEXCEPT : x (T (v.x)),
1314  y (T (v.y))
1315 {}
1316 
1317 template <class T>
1318 IMATH_CONSTEXPR14 IMATH_HOSTDEVICE inline const Vec2<T>&
1319 Vec2<T>::operator= (const Vec2& v) IMATH_NOEXCEPT
1320 {
1321  x = v.x;
1322  y = v.y;
1323  return *this;
1324 }
1325 
1326 template <class T>
1327 template <class S>
1328 IMATH_HOSTDEVICE inline void
1329 Vec2<T>::setValue (S a, S b) IMATH_NOEXCEPT
1330 {
1331  x = T (a);
1332  y = T (b);
1333 }
1334 
1335 template <class T>
1336 template <class S>
1337 IMATH_HOSTDEVICE inline void
1338 Vec2<T>::setValue (const Vec2<S>& v) IMATH_NOEXCEPT
1339 {
1340  x = T (v.x);
1341  y = T (v.y);
1342 }
1343 
1344 template <class T>
1345 template <class S>
1346 IMATH_HOSTDEVICE inline void
1347 Vec2<T>::getValue (S& a, S& b) const IMATH_NOEXCEPT
1348 {
1349  a = S (x);
1350  b = S (y);
1351 }
1352 
1353 template <class T>
1354 template <class S>
1355 IMATH_HOSTDEVICE inline void
1356 Vec2<T>::getValue (Vec2<S>& v) const IMATH_NOEXCEPT
1357 {
1358  v.x = S (x);
1359  v.y = S (y);
1360 }
1361 
1362 template <class T>
1363 IMATH_HOSTDEVICE inline T*
1364 Vec2<T>::getValue () IMATH_NOEXCEPT
1365 {
1366  return reinterpret_cast<T*> (this);
1367 }
1368 
1369 template <class T>
1370 IMATH_HOSTDEVICE inline const T*
1371 Vec2<T>::getValue () const IMATH_NOEXCEPT
1372 {
1373  return reinterpret_cast<const T*> (this);
1374 }
1375 
1376 template <class T>
1377 template <class S>
1378 IMATH_HOSTDEVICE constexpr inline bool
1379 Vec2<T>::operator== (const Vec2<S>& v) const IMATH_NOEXCEPT
1380 {
1381  return x == v.x && y == v.y;
1382 }
1383 
1384 template <class T>
1385 template <class S>
1386 IMATH_HOSTDEVICE constexpr inline bool
1387 Vec2<T>::operator!= (const Vec2<S>& v) const IMATH_NOEXCEPT
1388 {
1389  return x != v.x || y != v.y;
1390 }
1391 
1392 template <class T>
1393 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
1394 Vec2<T>::equalWithAbsError (const Vec2<T>& v, T e) const IMATH_NOEXCEPT
1395 {
1397  return false;
1399  return false;
1400 
1401  return true;
1402 }
1403 
1404 template <class T>
1405 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
1406 Vec2<T>::equalWithRelError (const Vec2<T>& v, T e) const IMATH_NOEXCEPT
1407 {
1409  return false;
1411  return false;
1412 
1413  return true;
1414 }
1415 
1416 template <class T>
1417 IMATH_HOSTDEVICE constexpr inline T
1418 Vec2<T>::dot (const Vec2& v) const IMATH_NOEXCEPT
1419 {
1420  return x * v.x + y * v.y;
1421 }
1422 
1423 template <class T>
1424 IMATH_HOSTDEVICE constexpr inline T
1425 Vec2<T>::operator^ (const Vec2& v) const IMATH_NOEXCEPT
1426 {
1427  return dot (v);
1428 }
1429 
1430 template <class T>
1431 IMATH_HOSTDEVICE constexpr inline T
1432 Vec2<T>::cross (const Vec2& v) const IMATH_NOEXCEPT
1433 {
1434  return x * v.y - y * v.x;
1435 }
1436 
1437 template <class T>
1438 IMATH_HOSTDEVICE constexpr inline T
1439 Vec2<T>::operator% (const Vec2& v) const IMATH_NOEXCEPT
1440 {
1441  return x * v.y - y * v.x;
1442 }
1443 
1444 template <class T>
1445 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec2<T>&
1446 Vec2<T>::operator+= (const Vec2& v) IMATH_NOEXCEPT
1447 {
1448  x += v.x;
1449  y += v.y;
1450  return *this;
1451 }
1452 
1453 template <class T>
1454 IMATH_HOSTDEVICE constexpr inline Vec2<T>
1455 Vec2<T>::operator+ (const Vec2& v) const IMATH_NOEXCEPT
1456 {
1457  return Vec2 (x + v.x, y + v.y);
1458 }
1459 
1460 template <class T>
1461 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec2<T>&
1462 Vec2<T>::operator-= (const Vec2& v) IMATH_NOEXCEPT
1463 {
1464  x -= v.x;
1465  y -= v.y;
1466  return *this;
1467 }
1468 
1469 template <class T>
1470 IMATH_HOSTDEVICE constexpr inline Vec2<T>
1471 Vec2<T>::operator- (const Vec2& v) const IMATH_NOEXCEPT
1472 {
1473  return Vec2 (x - v.x, y - v.y);
1474 }
1475 
1476 template <class T>
1477 IMATH_HOSTDEVICE constexpr inline Vec2<T>
1478 Vec2<T>::operator- () const IMATH_NOEXCEPT
1479 {
1480  return Vec2 (-x, -y);
1481 }
1482 
1483 template <class T>
1484 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec2<T>&
1485  Vec2<T>::negate () IMATH_NOEXCEPT
1486 {
1487  x = -x;
1488  y = -y;
1489  return *this;
1490 }
1491 
1492 template <class T>
1493 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec2<T>&
1494 Vec2<T>::operator*= (const Vec2& v) IMATH_NOEXCEPT
1495 {
1496  x *= v.x;
1497  y *= v.y;
1498  return *this;
1499 }
1500 
1501 template <class T>
1502 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec2<T>&
1503 Vec2<T>::operator*= (T a) IMATH_NOEXCEPT
1504 {
1505  x *= a;
1506  y *= a;
1507  return *this;
1508 }
1509 
1510 template <class T>
1511 IMATH_HOSTDEVICE constexpr inline Vec2<T>
1512 Vec2<T>::operator* (const Vec2& v) const IMATH_NOEXCEPT
1513 {
1514  return Vec2 (x * v.x, y * v.y);
1515 }
1516 
1517 template <class T>
1518 IMATH_HOSTDEVICE constexpr inline Vec2<T>
1519 Vec2<T>::operator* (T a) const IMATH_NOEXCEPT
1520 {
1521  return Vec2 (x * a, y * a);
1522 }
1523 
1524 template <class T>
1525 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec2<T>&
1526 Vec2<T>::operator/= (const Vec2& v) IMATH_NOEXCEPT
1527 {
1528  x /= v.x;
1529  y /= v.y;
1530  return *this;
1531 }
1532 
1533 template <class T>
1534 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec2<T>&
1535 Vec2<T>::operator/= (T a) IMATH_NOEXCEPT
1536 {
1537  x /= a;
1538  y /= a;
1539  return *this;
1540 }
1541 
1542 template <class T>
1543 IMATH_HOSTDEVICE constexpr inline Vec2<T>
1544 Vec2<T>::operator/ (const Vec2& v) const IMATH_NOEXCEPT
1545 {
1546  return Vec2 (x / v.x, y / v.y);
1547 }
1548 
1549 template <class T>
1550 IMATH_HOSTDEVICE constexpr inline Vec2<T>
1551 Vec2<T>::operator/ (T a) const IMATH_NOEXCEPT
1552 {
1553  return Vec2 (x / a, y / a);
1554 }
1555 
1556 template <class T>
1557 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T
1558 Vec2<T>::lengthTiny () const IMATH_NOEXCEPT
1559 {
1560  T absX = std::abs (x);
1561  T absY = std::abs (y);
1562 
1563  T max = absX;
1564 
1565  if (max < absY) max = absY;
1566 
1567  if (IMATH_UNLIKELY (max == T (0))) return T (0);
1568 
1569  //
1570  // Do not replace the divisions by max with multiplications by 1/max.
1571  // Computing 1/max can overflow but the divisions below will always
1572  // produce results less than or equal to 1.
1573  //
1574 
1575  absX /= max;
1576  absY /= max;
1577 
1578  return max * std::sqrt (absX * absX + absY * absY);
1579 }
1580 
1581 template <class T>
1582 IMATH_HOSTDEVICE inline T
1583 Vec2<T>::length () const IMATH_NOEXCEPT
1584 {
1585  T length2 = dot (*this);
1586 
1587  if (IMATH_UNLIKELY (length2 < T (2) * std::numeric_limits<T>::min ()))
1588  return lengthTiny ();
1589 
1590  return std::sqrt (length2);
1591 }
1592 
1593 template <class T>
1594 IMATH_HOSTDEVICE constexpr inline T
1595 Vec2<T>::length2 () const IMATH_NOEXCEPT
1596 {
1597  return dot (*this);
1598 }
1599 
1600 template <class T>
1601 IMATH_HOSTDEVICE inline const Vec2<T>&
1602 Vec2<T>::normalize () IMATH_NOEXCEPT
1603 {
1604  T l = length ();
1605 
1606  if (IMATH_LIKELY (l != T (0)))
1607  {
1608  //
1609  // Do not replace the divisions by l with multiplications by 1/l.
1610  // Computing 1/l can overflow but the divisions below will always
1611  // produce results less than or equal to 1.
1612  //
1613 
1614  x /= l;
1615  y /= l;
1616  }
1617 
1618  return *this;
1619 }
1620 
1621 template <class T>
1622 inline const Vec2<T>&
1624 {
1625  T l = length ();
1626 
1627  if (IMATH_UNLIKELY (l == T (0)))
1628  throw std::domain_error ("Cannot normalize null vector.");
1629 
1630  x /= l;
1631  y /= l;
1632  return *this;
1633 }
1634 
1635 template <class T>
1636 IMATH_HOSTDEVICE inline const Vec2<T>&
1637 Vec2<T>::normalizeNonNull () IMATH_NOEXCEPT
1638 {
1639  T l = length ();
1640  x /= l;
1641  y /= l;
1642  return *this;
1643 }
1644 
1645 template <class T>
1647 Vec2<T>::normalized () const IMATH_NOEXCEPT
1648 {
1649  T l = length ();
1650 
1651  if (IMATH_UNLIKELY (l == T (0))) return Vec2 (T (0));
1652 
1653  return Vec2 (x / l, y / l);
1654 }
1655 
1656 template <class T>
1657 inline Vec2<T>
1659 {
1660  T l = length ();
1661 
1662  if (IMATH_UNLIKELY (l == T (0)))
1663  throw std::domain_error ("Cannot normalize null vector.");
1664 
1665  return Vec2 (x / l, y / l);
1666 }
1667 
1668 template <class T>
1670 Vec2<T>::normalizedNonNull () const IMATH_NOEXCEPT
1671 {
1672  T l = length ();
1673  return Vec2 (x / l, y / l);
1674 }
1675 
1676 //-----------------------
1677 // Implementation of Vec3
1678 //-----------------------
1679 
1680 template <class T>
1681 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T&
1682 Vec3<T>::operator[] (int i) IMATH_NOEXCEPT
1683 {
1684  return reinterpret_cast<T*> (this)[i];
1685 }
1686 
1687 template <class T>
1688 constexpr IMATH_HOSTDEVICE inline const T&
1689 Vec3<T>::operator[] (int i) const IMATH_NOEXCEPT
1690 {
1691 #ifdef __cpp_if_consteval
1692  if consteval
1693  {
1694  return (i == 0) ? x : ((i == 1) ? y : z);
1695  }
1696  else
1697  {
1698  return reinterpret_cast<const T*> (this)[i];
1699  }
1700 #else
1701  return reinterpret_cast<const T*> (this)[i];
1702 #endif
1703 }
1704 
1705 template <class T> IMATH_HOSTDEVICE inline Vec3<T>::Vec3 () IMATH_NOEXCEPT
1706 {
1707  // empty, and not constexpr because data is uninitialized.
1708 }
1709 
1710 template <class T>
1711 IMATH_HOSTDEVICE constexpr inline Vec3<T>::Vec3 (T a) IMATH_NOEXCEPT : x (a),
1712  y (a),
1713  z (a)
1714 {}
1715 
1716 template <class T>
1717 IMATH_HOSTDEVICE constexpr inline Vec3<T>::Vec3 (T a, T b, T c) IMATH_NOEXCEPT
1718  : x (a),
1719  y (b),
1720  z (c)
1721 {}
1722 
1723 template <class T>
1724 IMATH_HOSTDEVICE constexpr inline Vec3<T>::Vec3 (const Vec3& v) IMATH_NOEXCEPT
1725  : x (v.x),
1726  y (v.y),
1727  z (v.z)
1728 {}
1729 
1730 template <class T>
1731 template <class S>
1732 IMATH_HOSTDEVICE constexpr inline Vec3<T>::Vec3 (const Vec3<S>& v)
1733  IMATH_NOEXCEPT : x (T (v.x)),
1734  y (T (v.y)),
1735  z (T (v.z))
1736 {}
1737 
1738 template <class T>
1739 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec3<T>&
1740 Vec3<T>::operator= (const Vec3& v) IMATH_NOEXCEPT
1741 {
1742  x = v.x;
1743  y = v.y;
1744  z = v.z;
1745  return *this;
1746 }
1747 
1748 template <class T>
1749 template <class S>
1750 IMATH_HOSTDEVICE constexpr inline Vec3<T>::Vec3 (const Vec4<S>& v)
1751  IMATH_NOEXCEPT : x (T (v.x / v.w)),
1752  y (T (v.y / v.w)),
1753  z (T (v.z / v.w))
1754 {}
1755 
1756 template <class T>
1757 template <class S>
1759  IMATH_CONSTEXPR14 inline Vec3<T>::Vec3 (const Vec4<S>& v, InfException)
1760 {
1761  T vx = T (v.x);
1762  T vy = T (v.y);
1763  T vz = T (v.z);
1764  T vw = T (v.w);
1765 
1766  T absW = (vw >= T (0)) ? vw : -vw;
1767 
1768  if (absW < 1)
1769  {
1770  T m = baseTypeMax () * absW;
1771 
1772  if (vx <= -m || vx >= m || vy <= -m || vy >= m || vz <= -m || vz >= m)
1773  throw std::domain_error ("Cannot normalize point at infinity.");
1774  }
1775 
1776  x = vx / vw;
1777  y = vy / vw;
1778  z = vz / vw;
1779 }
1780 
1781 template <class T>
1782 template <class S>
1783 IMATH_HOSTDEVICE inline void
1784 Vec3<T>::setValue (S a, S b, S c) IMATH_NOEXCEPT
1785 {
1786  x = T (a);
1787  y = T (b);
1788  z = T (c);
1789 }
1790 
1791 template <class T>
1792 template <class S>
1793 IMATH_HOSTDEVICE inline void
1794 Vec3<T>::setValue (const Vec3<S>& v) IMATH_NOEXCEPT
1795 {
1796  x = T (v.x);
1797  y = T (v.y);
1798  z = T (v.z);
1799 }
1800 
1801 template <class T>
1802 template <class S>
1803 IMATH_HOSTDEVICE inline void
1804 Vec3<T>::getValue (S& a, S& b, S& c) const IMATH_NOEXCEPT
1805 {
1806  a = S (x);
1807  b = S (y);
1808  c = S (z);
1809 }
1810 
1811 template <class T>
1812 template <class S>
1813 IMATH_HOSTDEVICE inline void
1814 Vec3<T>::getValue (Vec3<S>& v) const IMATH_NOEXCEPT
1815 {
1816  v.x = S (x);
1817  v.y = S (y);
1818  v.z = S (z);
1819 }
1820 
1821 template <class T>
1822 IMATH_HOSTDEVICE inline T*
1823 Vec3<T>::getValue () IMATH_NOEXCEPT
1824 {
1825  return reinterpret_cast<T*> (this);
1826 }
1827 
1828 template <class T>
1829 IMATH_HOSTDEVICE inline const T*
1830 Vec3<T>::getValue () const IMATH_NOEXCEPT
1831 {
1832  return reinterpret_cast<const T*> (this);
1833 }
1834 
1835 template <class T>
1836 template <class S>
1837 IMATH_HOSTDEVICE constexpr inline bool
1838 Vec3<T>::operator== (const Vec3<S>& v) const IMATH_NOEXCEPT
1839 {
1840  return x == v.x && y == v.y && z == v.z;
1841 }
1842 
1843 template <class T>
1844 template <class S>
1845 IMATH_HOSTDEVICE constexpr inline bool
1846 Vec3<T>::operator!= (const Vec3<S>& v) const IMATH_NOEXCEPT
1847 {
1848  return x != v.x || y != v.y || z != v.z;
1849 }
1850 
1851 template <class T>
1852 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
1853 Vec3<T>::equalWithAbsError (const Vec3<T>& v, T e) const IMATH_NOEXCEPT
1854 {
1855  for (int i = 0; i < 3; i++)
1856  if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
1857  return false;
1858 
1859  return true;
1860 }
1861 
1862 template <class T>
1863 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
1864 Vec3<T>::equalWithRelError (const Vec3<T>& v, T e) const IMATH_NOEXCEPT
1865 {
1866  for (int i = 0; i < 3; i++)
1867  if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
1868  return false;
1869 
1870  return true;
1871 }
1872 
1873 template <class T>
1874 IMATH_HOSTDEVICE constexpr inline T
1875 Vec3<T>::dot (const Vec3& v) const IMATH_NOEXCEPT
1876 {
1877  return x * v.x + y * v.y + z * v.z;
1878 }
1879 
1880 template <class T>
1881 IMATH_HOSTDEVICE constexpr inline T
1882 Vec3<T>::operator^ (const Vec3& v) const IMATH_NOEXCEPT
1883 {
1884  return dot (v);
1885 }
1886 
1887 template <class T>
1888 IMATH_HOSTDEVICE constexpr inline Vec3<T>
1889 Vec3<T>::cross (const Vec3& v) const IMATH_NOEXCEPT
1890 {
1891  return Vec3 (y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
1892 }
1893 
1894 template <class T>
1895 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec3<T>&
1896 Vec3<T>::operator%= (const Vec3& v) IMATH_NOEXCEPT
1897 {
1898  T a = y * v.z - z * v.y;
1899  T b = z * v.x - x * v.z;
1900  T c = x * v.y - y * v.x;
1901  x = a;
1902  y = b;
1903  z = c;
1904  return *this;
1905 }
1906 
1907 template <class T>
1908 IMATH_HOSTDEVICE constexpr inline Vec3<T>
1909 Vec3<T>::operator% (const Vec3& v) const IMATH_NOEXCEPT
1910 {
1911  return Vec3 (y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
1912 }
1913 
1914 template <class T>
1915 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec3<T>&
1916 Vec3<T>::operator+= (const Vec3& v) IMATH_NOEXCEPT
1917 {
1918  x += v.x;
1919  y += v.y;
1920  z += v.z;
1921  return *this;
1922 }
1923 
1924 template <class T>
1925 IMATH_HOSTDEVICE constexpr inline Vec3<T>
1926 Vec3<T>::operator+ (const Vec3& v) const IMATH_NOEXCEPT
1927 {
1928  return Vec3 (x + v.x, y + v.y, z + v.z);
1929 }
1930 
1931 template <class T>
1932 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec3<T>&
1933 Vec3<T>::operator-= (const Vec3& v) IMATH_NOEXCEPT
1934 {
1935  x -= v.x;
1936  y -= v.y;
1937  z -= v.z;
1938  return *this;
1939 }
1940 
1941 template <class T>
1942 IMATH_HOSTDEVICE constexpr inline Vec3<T>
1943 Vec3<T>::operator- (const Vec3& v) const IMATH_NOEXCEPT
1944 {
1945  return Vec3 (x - v.x, y - v.y, z - v.z);
1946 }
1947 
1948 template <class T>
1949 IMATH_HOSTDEVICE constexpr inline Vec3<T>
1950 Vec3<T>::operator- () const IMATH_NOEXCEPT
1951 {
1952  return Vec3 (-x, -y, -z);
1953 }
1954 
1955 template <class T>
1956 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec3<T>&
1957  Vec3<T>::negate () IMATH_NOEXCEPT
1958 {
1959  x = -x;
1960  y = -y;
1961  z = -z;
1962  return *this;
1963 }
1964 
1965 template <class T>
1966 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec3<T>&
1967 Vec3<T>::operator*= (const Vec3& v) IMATH_NOEXCEPT
1968 {
1969  x *= v.x;
1970  y *= v.y;
1971  z *= v.z;
1972  return *this;
1973 }
1974 
1975 template <class T>
1976 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec3<T>&
1977 Vec3<T>::operator*= (T a) IMATH_NOEXCEPT
1978 {
1979  x *= a;
1980  y *= a;
1981  z *= a;
1982  return *this;
1983 }
1984 
1985 template <class T>
1986 IMATH_HOSTDEVICE constexpr inline Vec3<T>
1987 Vec3<T>::operator* (const Vec3& v) const IMATH_NOEXCEPT
1988 {
1989  return Vec3 (x * v.x, y * v.y, z * v.z);
1990 }
1991 
1992 template <class T>
1993 IMATH_HOSTDEVICE constexpr inline Vec3<T>
1994 Vec3<T>::operator* (T a) const IMATH_NOEXCEPT
1995 {
1996  return Vec3 (x * a, y * a, z * a);
1997 }
1998 
1999 template <class T>
2000 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec3<T>&
2001 Vec3<T>::operator/= (const Vec3& v) IMATH_NOEXCEPT
2002 {
2003  x /= v.x;
2004  y /= v.y;
2005  z /= v.z;
2006  return *this;
2007 }
2008 
2009 template <class T>
2010 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec3<T>&
2011 Vec3<T>::operator/= (T a) IMATH_NOEXCEPT
2012 {
2013  x /= a;
2014  y /= a;
2015  z /= a;
2016  return *this;
2017 }
2018 
2019 template <class T>
2020 IMATH_HOSTDEVICE constexpr inline Vec3<T>
2021 Vec3<T>::operator/ (const Vec3& v) const IMATH_NOEXCEPT
2022 {
2023  return Vec3 (x / v.x, y / v.y, z / v.z);
2024 }
2025 
2026 template <class T>
2027 IMATH_HOSTDEVICE constexpr inline Vec3<T>
2028 Vec3<T>::operator/ (T a) const IMATH_NOEXCEPT
2029 {
2030  return Vec3 (x / a, y / a, z / a);
2031 }
2032 
2033 template <class T>
2034 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T
2035 Vec3<T>::lengthTiny () const IMATH_NOEXCEPT
2036 {
2037  T absX = (x >= T (0)) ? x : -x;
2038  T absY = (y >= T (0)) ? y : -y;
2039  T absZ = (z >= T (0)) ? z : -z;
2040 
2041  T max = absX;
2042 
2043  if (max < absY) max = absY;
2044 
2045  if (max < absZ) max = absZ;
2046 
2047  if (IMATH_UNLIKELY (max == T (0))) return T (0);
2048 
2049  //
2050  // Do not replace the divisions by max with multiplications by 1/max.
2051  // Computing 1/max can overflow but the divisions below will always
2052  // produce results less than or equal to 1.
2053  //
2054 
2055  absX /= max;
2056  absY /= max;
2057  absZ /= max;
2058 
2059  return max * std::sqrt (absX * absX + absY * absY + absZ * absZ);
2060 }
2061 
2062 template <class T>
2063 IMATH_HOSTDEVICE inline T
2064 Vec3<T>::length () const IMATH_NOEXCEPT
2065 {
2066  T length2 = dot (*this);
2067 
2068  if (IMATH_UNLIKELY (length2 < T (2) * std::numeric_limits<T>::min ()))
2069  return lengthTiny ();
2070 
2071  return std::sqrt (length2);
2072 }
2073 
2074 template <class T>
2075 IMATH_HOSTDEVICE constexpr inline T
2076 Vec3<T>::length2 () const IMATH_NOEXCEPT
2077 {
2078  return dot (*this);
2079 }
2080 
2081 template <class T>
2082 IMATH_HOSTDEVICE inline const Vec3<T>&
2083 Vec3<T>::normalize () IMATH_NOEXCEPT
2084 {
2085  T l = length ();
2086 
2087  if (IMATH_LIKELY (l != T (0)))
2088  {
2089  //
2090  // Do not replace the divisions by l with multiplications by 1/l.
2091  // Computing 1/l can overflow but the divisions below will always
2092  // produce results less than or equal to 1.
2093  //
2094 
2095  x /= l;
2096  y /= l;
2097  z /= l;
2098  }
2099 
2100  return *this;
2101 }
2102 
2103 template <class T>
2104 inline const Vec3<T>&
2106 {
2107  T l = length ();
2108 
2109  if (IMATH_UNLIKELY (l == T (0)))
2110  throw std::domain_error ("Cannot normalize null vector.");
2111 
2112  x /= l;
2113  y /= l;
2114  z /= l;
2115  return *this;
2116 }
2117 
2118 template <class T>
2119 IMATH_HOSTDEVICE inline const Vec3<T>&
2120 Vec3<T>::normalizeNonNull () IMATH_NOEXCEPT
2121 {
2122  T l = length ();
2123  x /= l;
2124  y /= l;
2125  z /= l;
2126  return *this;
2127 }
2128 
2129 template <class T>
2131 Vec3<T>::normalized () const IMATH_NOEXCEPT
2132 {
2133  T l = length ();
2134 
2135  if (IMATH_UNLIKELY ((l == T (0)))) return Vec3 (T (0));
2136 
2137  return Vec3 (x / l, y / l, z / l);
2138 }
2139 
2140 template <class T>
2141 inline Vec3<T>
2143 {
2144  T l = length ();
2145 
2146  if (IMATH_UNLIKELY (l == T (0)))
2147  throw std::domain_error ("Cannot normalize null vector.");
2148 
2149  return Vec3 (x / l, y / l, z / l);
2150 }
2151 
2152 template <class T>
2154 Vec3<T>::normalizedNonNull () const IMATH_NOEXCEPT
2155 {
2156  T l = length ();
2157  return Vec3 (x / l, y / l, z / l);
2158 }
2159 
2160 //-----------------------
2161 // Implementation of Vec4
2162 //-----------------------
2163 
2164 template <class T>
2165 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T&
2166 Vec4<T>::operator[] (int i) IMATH_NOEXCEPT
2167 {
2168  return reinterpret_cast<T*> (this)[i];
2169 }
2170 
2171 template <class T>
2172 IMATH_HOSTDEVICE constexpr inline const T&
2173 Vec4<T>::operator[] (int i) const IMATH_NOEXCEPT
2174 {
2175 #ifdef __cpp_if_consteval
2176  if consteval
2177  {
2178  return (i == 0) ? x : ((i == 1) ? y : ((i == 2) ? z : w));
2179  }
2180  else
2181  {
2182  return reinterpret_cast<const T*> (this)[i];
2183  }
2184 #else
2185  return reinterpret_cast<const T*> (this)[i];
2186 #endif
2187 }
2188 
2189 template <class T> IMATH_HOSTDEVICE inline Vec4<T>::Vec4 () IMATH_NOEXCEPT
2190 {
2191  // empty, and not constexpr because data is uninitialized.
2192 }
2193 
2194 template <class T>
2195 IMATH_HOSTDEVICE constexpr inline Vec4<T>::Vec4 (T a) IMATH_NOEXCEPT : x (a),
2196  y (a),
2197  z (a),
2198  w (a)
2199 {}
2200 
2201 template <class T>
2202 IMATH_HOSTDEVICE constexpr inline Vec4<T>::Vec4 (T a, T b, T c, T d)
2203  IMATH_NOEXCEPT : x (a),
2204  y (b),
2205  z (c),
2206  w (d)
2207 {}
2208 
2209 template <class T>
2210 IMATH_HOSTDEVICE constexpr inline Vec4<T>::Vec4 (const Vec4& v) IMATH_NOEXCEPT
2211  : x (v.x),
2212  y (v.y),
2213  z (v.z),
2214  w (v.w)
2215 {}
2216 
2217 template <class T>
2218 template <class S>
2219 IMATH_HOSTDEVICE constexpr inline Vec4<T>::Vec4 (const Vec4<S>& v)
2220  IMATH_NOEXCEPT : x (T (v.x)),
2221  y (T (v.y)),
2222  z (T (v.z)),
2223  w (T (v.w))
2224 {}
2225 
2226 template <class T>
2227 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec4<T>&
2228 Vec4<T>::operator= (const Vec4& v) IMATH_NOEXCEPT
2229 {
2230  x = v.x;
2231  y = v.y;
2232  z = v.z;
2233  w = v.w;
2234  return *this;
2235 }
2236 
2237 template <class T>
2238 template <class S>
2239 IMATH_HOSTDEVICE constexpr inline Vec4<T>::Vec4 (const Vec3<S>& v)
2240  IMATH_NOEXCEPT : x (T (v.x)),
2241  y (T (v.y)),
2242  z (T (v.z)),
2243  w (T (1))
2244 {}
2245 
2246 template <class T>
2247 template <class S>
2248 IMATH_HOSTDEVICE inline void
2249 Vec4<T>::setValue (S a, S b, S c, S d) IMATH_NOEXCEPT
2250 {
2251  x = T (a);
2252  y = T (b);
2253  z = T (c);
2254  w = T (d);
2255 }
2256 
2257 template <class T>
2258 template <class S>
2259 IMATH_HOSTDEVICE inline void
2260 Vec4<T>::setValue (const Vec4<S>& v) IMATH_NOEXCEPT
2261 {
2262  x = T (v.x);
2263  y = T (v.y);
2264  z = T (v.z);
2265  w = T (v.w);
2266 }
2267 
2268 template <class T>
2269 template <class S>
2270 IMATH_HOSTDEVICE inline void
2271 Vec4<T>::getValue (S& a, S& b, S& c, S& d) const IMATH_NOEXCEPT
2272 {
2273  a = S (x);
2274  b = S (y);
2275  c = S (z);
2276  d = S (w);
2277 }
2278 
2279 template <class T>
2280 template <class S>
2281 IMATH_HOSTDEVICE inline void
2282 Vec4<T>::getValue (Vec4<S>& v) const IMATH_NOEXCEPT
2283 {
2284  v.x = S (x);
2285  v.y = S (y);
2286  v.z = S (z);
2287  v.w = S (w);
2288 }
2289 
2290 template <class T>
2291 IMATH_HOSTDEVICE inline T*
2292 Vec4<T>::getValue () IMATH_NOEXCEPT
2293 {
2294  return reinterpret_cast<T*> (this);
2295 }
2296 
2297 template <class T>
2298 IMATH_HOSTDEVICE inline const T*
2299 Vec4<T>::getValue () const IMATH_NOEXCEPT
2300 {
2301  return reinterpret_cast<const T*> (this);
2302 }
2303 
2304 template <class T>
2305 template <class S>
2306 IMATH_HOSTDEVICE constexpr inline bool
2307 Vec4<T>::operator== (const Vec4<S>& v) const IMATH_NOEXCEPT
2308 {
2309  return x == v.x && y == v.y && z == v.z && w == v.w;
2310 }
2311 
2312 template <class T>
2313 template <class S>
2314 IMATH_HOSTDEVICE constexpr inline bool
2315 Vec4<T>::operator!= (const Vec4<S>& v) const IMATH_NOEXCEPT
2316 {
2317  return x != v.x || y != v.y || z != v.z || w != v.w;
2318 }
2319 
2320 template <class T>
2321 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
2322 Vec4<T>::equalWithAbsError (const Vec4<T>& v, T e) const IMATH_NOEXCEPT
2323 {
2324  for (int i = 0; i < 4; i++)
2325  if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
2326  return false;
2327 
2328  return true;
2329 }
2330 
2331 template <class T>
2332 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
2333 Vec4<T>::equalWithRelError (const Vec4<T>& v, T e) const IMATH_NOEXCEPT
2334 {
2335  for (int i = 0; i < 4; i++)
2336  if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
2337  return false;
2338 
2339  return true;
2340 }
2341 
2342 template <class T>
2343 IMATH_HOSTDEVICE constexpr inline T
2344 Vec4<T>::dot (const Vec4& v) const IMATH_NOEXCEPT
2345 {
2346  return x * v.x + y * v.y + z * v.z + w * v.w;
2347 }
2348 
2349 template <class T>
2350 IMATH_HOSTDEVICE constexpr inline T
2351 Vec4<T>::operator^ (const Vec4& v) const IMATH_NOEXCEPT
2352 {
2353  return dot (v);
2354 }
2355 
2356 template <class T>
2357 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec4<T>&
2358 Vec4<T>::operator+= (const Vec4& v) IMATH_NOEXCEPT
2359 {
2360  x += v.x;
2361  y += v.y;
2362  z += v.z;
2363  w += v.w;
2364  return *this;
2365 }
2366 
2367 template <class T>
2368 IMATH_HOSTDEVICE constexpr inline Vec4<T>
2369 Vec4<T>::operator+ (const Vec4& v) const IMATH_NOEXCEPT
2370 {
2371  return Vec4 (x + v.x, y + v.y, z + v.z, w + v.w);
2372 }
2373 
2374 template <class T>
2375 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec4<T>&
2376 Vec4<T>::operator-= (const Vec4& v) IMATH_NOEXCEPT
2377 {
2378  x -= v.x;
2379  y -= v.y;
2380  z -= v.z;
2381  w -= v.w;
2382  return *this;
2383 }
2384 
2385 template <class T>
2386 IMATH_HOSTDEVICE constexpr inline Vec4<T>
2387 Vec4<T>::operator- (const Vec4& v) const IMATH_NOEXCEPT
2388 {
2389  return Vec4 (x - v.x, y - v.y, z - v.z, w - v.w);
2390 }
2391 
2392 template <class T>
2393 IMATH_HOSTDEVICE constexpr inline Vec4<T>
2394 Vec4<T>::operator- () const IMATH_NOEXCEPT
2395 {
2396  return Vec4 (-x, -y, -z, -w);
2397 }
2398 
2399 template <class T>
2400 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec4<T>&
2401  Vec4<T>::negate () IMATH_NOEXCEPT
2402 {
2403  x = -x;
2404  y = -y;
2405  z = -z;
2406  w = -w;
2407  return *this;
2408 }
2409 
2410 template <class T>
2411 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec4<T>&
2412 Vec4<T>::operator*= (const Vec4& v) IMATH_NOEXCEPT
2413 {
2414  x *= v.x;
2415  y *= v.y;
2416  z *= v.z;
2417  w *= v.w;
2418  return *this;
2419 }
2420 
2421 template <class T>
2422 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec4<T>&
2423 Vec4<T>::operator*= (T a) IMATH_NOEXCEPT
2424 {
2425  x *= a;
2426  y *= a;
2427  z *= a;
2428  w *= a;
2429  return *this;
2430 }
2431 
2432 template <class T>
2433 IMATH_HOSTDEVICE constexpr inline Vec4<T>
2434 Vec4<T>::operator* (const Vec4& v) const IMATH_NOEXCEPT
2435 {
2436  return Vec4 (x * v.x, y * v.y, z * v.z, w * v.w);
2437 }
2438 
2439 template <class T>
2440 IMATH_HOSTDEVICE constexpr inline Vec4<T>
2441 Vec4<T>::operator* (T a) const IMATH_NOEXCEPT
2442 {
2443  return Vec4 (x * a, y * a, z * a, w * a);
2444 }
2445 
2446 template <class T>
2447 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec4<T>&
2448 Vec4<T>::operator/= (const Vec4& v) IMATH_NOEXCEPT
2449 {
2450  x /= v.x;
2451  y /= v.y;
2452  z /= v.z;
2453  w /= v.w;
2454  return *this;
2455 }
2456 
2457 template <class T>
2458 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Vec4<T>&
2459 Vec4<T>::operator/= (T a) IMATH_NOEXCEPT
2460 {
2461  x /= a;
2462  y /= a;
2463  z /= a;
2464  w /= a;
2465  return *this;
2466 }
2467 
2468 template <class T>
2469 IMATH_HOSTDEVICE constexpr inline Vec4<T>
2470 Vec4<T>::operator/ (const Vec4& v) const IMATH_NOEXCEPT
2471 {
2472  return Vec4 (x / v.x, y / v.y, z / v.z, w / v.w);
2473 }
2474 
2475 template <class T>
2476 IMATH_HOSTDEVICE constexpr inline Vec4<T>
2477 Vec4<T>::operator/ (T a) const IMATH_NOEXCEPT
2478 {
2479  return Vec4 (x / a, y / a, z / a, w / a);
2480 }
2481 
2482 template <class T>
2483 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T
2484 Vec4<T>::lengthTiny () const IMATH_NOEXCEPT
2485 {
2486  T absX = (x >= T (0)) ? x : -x;
2487  T absY = (y >= T (0)) ? y : -y;
2488  T absZ = (z >= T (0)) ? z : -z;
2489  T absW = (w >= T (0)) ? w : -w;
2490 
2491  T max = absX;
2492 
2493  if (max < absY) max = absY;
2494 
2495  if (max < absZ) max = absZ;
2496 
2497  if (max < absW) max = absW;
2498 
2499  if (IMATH_UNLIKELY (max == T (0))) return T (0);
2500 
2501  //
2502  // Do not replace the divisions by max with multiplications by 1/max.
2503  // Computing 1/max can overflow but the divisions below will always
2504  // produce results less than or equal to 1.
2505  //
2506 
2507  absX /= max;
2508  absY /= max;
2509  absZ /= max;
2510  absW /= max;
2511 
2512  return max *
2513  std::sqrt (absX * absX + absY * absY + absZ * absZ + absW * absW);
2514 }
2515 
2516 template <class T>
2517 IMATH_HOSTDEVICE inline T
2518 Vec4<T>::length () const IMATH_NOEXCEPT
2519 {
2520  T length2 = dot (*this);
2521 
2522  if (IMATH_UNLIKELY (length2 < T (2) * std::numeric_limits<T>::min ()))
2523  return lengthTiny ();
2524 
2525  return std::sqrt (length2);
2526 }
2527 
2528 template <class T>
2529 IMATH_HOSTDEVICE constexpr inline T
2530 Vec4<T>::length2 () const IMATH_NOEXCEPT
2531 {
2532  return dot (*this);
2533 }
2534 
2535 template <class T>
2536 IMATH_HOSTDEVICE const inline Vec4<T>&
2537 Vec4<T>::normalize () IMATH_NOEXCEPT
2538 {
2539  T l = length ();
2540 
2541  if (IMATH_LIKELY (l != T (0)))
2542  {
2543  //
2544  // Do not replace the divisions by l with multiplications by 1/l.
2545  // Computing 1/l can overflow but the divisions below will always
2546  // produce results less than or equal to 1.
2547  //
2548 
2549  x /= l;
2550  y /= l;
2551  z /= l;
2552  w /= l;
2553  }
2554 
2555  return *this;
2556 }
2557 
2558 template <class T>
2559 const inline Vec4<T>&
2561 {
2562  T l = length ();
2563 
2564  if (IMATH_UNLIKELY (l == T (0)))
2565  throw std::domain_error ("Cannot normalize null vector.");
2566 
2567  x /= l;
2568  y /= l;
2569  z /= l;
2570  w /= l;
2571  return *this;
2572 }
2573 
2574 template <class T>
2575 IMATH_HOSTDEVICE inline const Vec4<T>&
2576 Vec4<T>::normalizeNonNull () IMATH_NOEXCEPT
2577 {
2578  T l = length ();
2579  x /= l;
2580  y /= l;
2581  z /= l;
2582  w /= l;
2583  return *this;
2584 }
2585 
2586 template <class T>
2588 Vec4<T>::normalized () const IMATH_NOEXCEPT
2589 {
2590  T l = length ();
2591 
2592  if (IMATH_UNLIKELY (l == T (0))) return Vec4 (T (0));
2593 
2594  return Vec4 (x / l, y / l, z / l, w / l);
2595 }
2596 
2597 template <class T>
2598 inline Vec4<T>
2600 {
2601  T l = length ();
2602 
2603  if (IMATH_UNLIKELY (l == T (0)))
2604  throw std::domain_error ("Cannot normalize null vector.");
2605 
2606  return Vec4 (x / l, y / l, z / l, w / l);
2607 }
2608 
2609 template <class T>
2611 Vec4<T>::normalizedNonNull () const IMATH_NOEXCEPT
2612 {
2613  T l = length ();
2614  return Vec4 (x / l, y / l, z / l, w / l);
2615 }
2616 
2617 //-----------------------------
2618 // Stream output implementation
2619 //-----------------------------
2620 
2621 template <class T>
2622 std::ostream&
2623 operator<< (std::ostream& s, const Vec2<T>& v)
2624 {
2625  return s << '(' << v.x << ' ' << v.y << ')';
2626 }
2627 
2628 template <class T>
2629 std::ostream&
2630 operator<< (std::ostream& s, const Vec3<T>& v)
2631 {
2632  return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
2633 }
2634 
2635 template <class T>
2636 std::ostream&
2637 operator<< (std::ostream& s, const Vec4<T>& v)
2638 {
2639  return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ' ' << v.w << ')';
2640 }
2641 
2642 //-----------------------------------------
2643 // Implementation of reverse multiplication
2644 //-----------------------------------------
2645 
2646 template <class T>
2647 IMATH_HOSTDEVICE constexpr inline Vec2<T>
2648 operator* (T a, const Vec2<T>& v) IMATH_NOEXCEPT
2649 {
2650  return Vec2<T> (a * v.x, a * v.y);
2651 }
2652 
2653 template <class T>
2654 IMATH_HOSTDEVICE constexpr inline Vec3<T>
2655 operator* (T a, const Vec3<T>& v) IMATH_NOEXCEPT
2656 {
2657  return Vec3<T> (a * v.x, a * v.y, a * v.z);
2658 }
2659 
2660 template <class T>
2661 IMATH_HOSTDEVICE constexpr inline Vec4<T>
2662 operator* (T a, const Vec4<T>& v) IMATH_NOEXCEPT
2663 {
2664  return Vec4<T> (a * v.x, a * v.y, a * v.z, a * v.w);
2665 }
2666 
2667 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
2668 # pragma warning(pop)
2669 #endif
2670 
2671 IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
2672 
2673 #endif // INCLUDED_IMATHVEC_H
IMATH_HOSTDEVICE static constexpr T baseTypeMax() IMATH_NOEXCEPT
Largest possible positive value.
Definition: ImathVec.h:972
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError(T x1, T x2, T e) IMATH_NOEXCEPT
Definition: ImathMath.h:151
T BaseType
Definition: ImathVec.h:999
IMATH_HOSTDEVICE Vec4(const V &v)
Definition: ImathVec.h:780
IMATH_HOSTDEVICE T * getValue() IMATH_NOEXCEPT
Return a raw pointer to the array of values.
Definition: ImathVec.h:1364
IMATH_HOSTDEVICE Vec4< T > normalized() const IMATH_NOEXCEPT
Return a normalized vector. Does not modify *this.
Definition: ImathVec.h:2588
IMATH_HOSTDEVICE constexpr T length2() const IMATH_NOEXCEPT
Definition: ImathVec.h:2076
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4 & negate() IMATH_NOEXCEPT
Component-wise multiplication by -1.
Definition: ImathVec.h:2401
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2 & operator+=(const Vec2 &v) IMATH_NOEXCEPT
Component-wise addition.
Definition: ImathVec.h:1446
T z
Definition: ImathVec.h:368
IMATH_HOSTDEVICE static constexpr T baseTypeSmallest() IMATH_NOEXCEPT
Smallest possible positive value.
Definition: ImathVec.h:664
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2 & operator*=(const Vec2 &v) IMATH_NOEXCEPT
Component-wise multiplication.
Definition: ImathVec.h:1494
Vec4< T > normalizedExc() const
Definition: ImathVec.h:2599
IMATH_HOSTDEVICE constexpr bool operator==(const Vec4< S > &v) const IMATH_NOEXCEPT
Equality.
Definition: ImathVec.h:2307
#define IMATH_NOEXCEPT
Definition: ImathConfig.h:78
IMATH_HOSTDEVICE const Vec4 & normalizeNonNull() IMATH_NOEXCEPT
Definition: ImathVec.h:2576
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError(const Vec3< T > &v, T e) const IMATH_NOEXCEPT
Definition: ImathVec.h:1864
Definition: ImathVec.h:40
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
Definition: thread.h:632
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2 & operator-=(const Vec2 &v) IMATH_NOEXCEPT
Component-wise subtraction.
Definition: ImathVec.h:1462
imath_half_bits_t half
if we're in a C-only context, alias the half bits type to half
Definition: half.h:268
IMATH_HOSTDEVICE T length() const IMATH_NOEXCEPT
Return the Euclidean norm.
Definition: ImathVec.h:2064
const GLdouble * v
Definition: glcorearb.h:837
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError(T x1, T x2, T e) IMATH_NOEXCEPT
Definition: ImathMath.h:164
GLsizei const GLfloat * value
Definition: glcorearb.h:824
IMATH_HOSTDEVICE const Vec3 & normalizeNonNull() IMATH_NOEXCEPT
Definition: ImathVec.h:2120
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4 & operator+=(const Vec4 &v) IMATH_NOEXCEPT
Component-wise addition.
Definition: ImathVec.h:2358
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2 & negate() IMATH_NOEXCEPT
Component-wise multiplication by -1.
Definition: ImathVec.h:1485
IMATH_HOSTDEVICE constexpr T dot(const Vec4 &v) const IMATH_NOEXCEPT
Dot product.
Definition: ImathVec.h:2344
vfloat4 sqrt(const vfloat4 &a)
Definition: simd.h:7694
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3 & operator*=(const Vec3 &v) IMATH_NOEXCEPT
Component-wise multiplication.
Definition: ImathVec.h:1967
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4 & operator*=(const Vec4 &v) IMATH_NOEXCEPT
Component-wise multiplication.
Definition: ImathVec.h:2412
IMATH_HOSTDEVICE constexpr T operator^(const Vec4 &v) const IMATH_NOEXCEPT
Dot product.
Definition: ImathVec.h:2351
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError(const Vec4< T > &v, T e) const IMATH_NOEXCEPT
Definition: ImathVec.h:2333
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
IMATH_HOSTDEVICE Vec3< T > normalized() const IMATH_NOEXCEPT
Return a normalized vector. Does not modify *this.
Definition: ImathVec.h:2131
has_subscript<T>::value is true if T has a subscript operator.
Definition: type_traits.h:54
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
IMATH_HOSTDEVICE constexpr T dot(const Vec3 &v) const IMATH_NOEXCEPT
Dot product.
Definition: ImathVec.h:1875
IMATH_HOSTDEVICE constexpr T length2() const IMATH_NOEXCEPT
Definition: ImathVec.h:2530
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLint y
Definition: glcorearb.h:103
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3 & operator+=(const Vec3 &v) IMATH_NOEXCEPT
Component-wise addition.
Definition: ImathVec.h:1916
IMATH_HOSTDEVICE constexpr Vec2 operator-() const IMATH_NOEXCEPT
Component-wise multiplication by -1.
Definition: ImathVec.h:1478
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4 & operator=(const Vec4 &v) IMATH_NOEXCEPT
Assignment.
Definition: ImathVec.h:2228
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2 & operator=(const Vec2 &v) IMATH_NOEXCEPT
Assignment.
Definition: ImathVec.h:1319
IMATH_HOSTDEVICE Vec2< T > normalizedNonNull() const IMATH_NOEXCEPT
Definition: ImathVec.h:1670
IMATH_HOSTDEVICE static constexpr T baseTypeEpsilon() IMATH_NOEXCEPT
Smallest possible e for which 1+e != 1.
Definition: ImathVec.h:337
#define IMATH_HOSTDEVICE
Definition: ImathConfig.h:108
IMATH_HOSTDEVICE Vec3(const V &v)
Definition: ImathVec.h:455
IMATH_HOSTDEVICE constexpr Vec2< T > operator*(T a, const Vec2< T > &v) IMATH_NOEXCEPT
Reverse multiplication: S * Vec2<T>
Definition: ImathVec.h:2648
IMATH_HOSTDEVICE Vec2(const V &v)
Definition: ImathVec.h:133
__hostdev__ float getValue(uint32_t i) const
Definition: NanoVDB.h:5578
IMATH_HOSTDEVICE static constexpr T baseTypeSmallest() IMATH_NOEXCEPT
Smallest possible positive value.
Definition: ImathVec.h:978
Vec3< T > normalizedExc() const
Definition: ImathVec.h:2142
IMATH_HOSTDEVICE Vec2< T > normalized() const IMATH_NOEXCEPT
Return a normalized vector. Does not modify *this.
Definition: ImathVec.h:1647
IMATH_HOSTDEVICE Vec2() IMATH_NOEXCEPT
Uninitialized by default.
Definition: ImathVec.h:1288
IMATH_HOSTDEVICE constexpr bool operator!=(const Vec4< S > &v) const IMATH_NOEXCEPT
Inequality.
Definition: ImathVec.h:2315
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError(const Vec4< T > &v, T e) const IMATH_NOEXCEPT
Definition: ImathVec.h:2322
IMATH_HOSTDEVICE constexpr Vec4 operator-() const IMATH_NOEXCEPT
Component-wise multiplication by -1.
Definition: ImathVec.h:2394
T BaseType
Definition: ImathVec.h:685
T z
Definition: ImathVec.h:701
IMATH_HOSTDEVICE constexpr Vec3 operator-() const IMATH_NOEXCEPT
Component-wise multiplication by -1.
Definition: ImathVec.h:1950
T x
Definition: ImathVec.h:59
IMATH_HOSTDEVICE static constexpr unsigned int dimensions() IMATH_NOEXCEPT
Return the number of dimensions, i.e. 4.
Definition: ImathVec.h:992
T x
Definition: ImathVec.h:368
IMATH_HOSTDEVICE T length() const IMATH_NOEXCEPT
Return the Euclidean norm.
Definition: ImathVec.h:2518
IMATH_HOSTDEVICE constexpr T dot(const Vec2 &v) const IMATH_NOEXCEPT
Dot product.
Definition: ImathVec.h:1418
const Vec4 & normalizeExc()
Normalize in place. If length()==0, throw an exception.
Definition: ImathVec.h:2560
IMATH_HOSTDEVICE void setValue(S a, S b, S c) IMATH_NOEXCEPT
Set the value.
Definition: ImathVec.h:1784
T y
Definition: ImathVec.h:59
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
Definition: CE_Vector.h:138
const Vec3 & normalizeExc()
Normalize in place. If length()==0, throw an exception.
Definition: ImathVec.h:2105
IMATH_HOSTDEVICE constexpr bool operator==(const Vec3< S > &v) const IMATH_NOEXCEPT
Equality.
Definition: ImathVec.h:1838
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T & operator[](int i) IMATH_NOEXCEPT
Definition: ImathVec.h:1265
IMATH_HOSTDEVICE constexpr Vec3 operator+(const Vec3 &v) const IMATH_NOEXCEPT
Component-wise addition.
Definition: ImathVec.h:1926
#define IMATH_EXPORT_ENUM
Definition: ImathExport.h:60
IMATH_HOSTDEVICE constexpr Vec4 operator*(const Vec4 &v) const IMATH_NOEXCEPT
Component-wise multiplication.
Definition: ImathVec.h:2434
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3 & negate() IMATH_NOEXCEPT
Component-wise multiplication by -1.
Definition: ImathVec.h:1957
IMATH_HOSTDEVICE constexpr T length2() const IMATH_NOEXCEPT
Definition: ImathVec.h:1595
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec2 & operator/=(const Vec2 &v) IMATH_NOEXCEPT
Component-wise division.
Definition: ImathVec.h:1526
IMATH_HOSTDEVICE Vec3< T > normalizedNonNull() const IMATH_NOEXCEPT
Definition: ImathVec.h:2154
IMATH_HOSTDEVICE constexpr T operator^(const Vec3 &v) const IMATH_NOEXCEPT
Dot product.
Definition: ImathVec.h:1882
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3 & operator%=(const Vec3 &v) IMATH_NOEXCEPT
Right-handed cross product.
Definition: ImathVec.h:1896
GLint GLenum GLboolean normalized
Definition: glcorearb.h:872
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
#define IMATH_ENABLE_IF(...)
IMATH_HOSTDEVICE static constexpr unsigned int dimensions() IMATH_NOEXCEPT
Return the number of dimensions, i.e. 2.
Definition: ImathVec.h:345
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4 & operator-=(const Vec4 &v) IMATH_NOEXCEPT
Component-wise subtraction.
Definition: ImathVec.h:2376
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError(const Vec2< T > &v, T e) const IMATH_NOEXCEPT
Definition: ImathVec.h:1406
IMATH_HOSTDEVICE static constexpr T baseTypeMax() IMATH_NOEXCEPT
Largest possible positive value.
Definition: ImathVec.h:325
IMATH_HOSTDEVICE static constexpr unsigned int dimensions() IMATH_NOEXCEPT
Return the number of dimensions, i.e. 3.
Definition: ImathVec.h:678
IMATH_HOSTDEVICE static constexpr T baseTypeMax() IMATH_NOEXCEPT
Largest possible positive value.
Definition: ImathVec.h:658
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3 & operator-=(const Vec3 &v) IMATH_NOEXCEPT
Component-wise subtraction.
Definition: ImathVec.h:1933
IMATH_HOSTDEVICE constexpr Vec4 operator+(const Vec4 &v) const IMATH_NOEXCEPT
Component-wise addition.
Definition: ImathVec.h:2369
IMATH_HOSTDEVICE Vec4< T > normalizedNonNull() const IMATH_NOEXCEPT
Definition: ImathVec.h:2611
IMATH_HOSTDEVICE constexpr bool operator!=(const Vec2< S > &v) const IMATH_NOEXCEPT
Inequality.
Definition: ImathVec.h:1387
IMATH_HOSTDEVICE constexpr bool operator==(const Vec2< S > &v) const IMATH_NOEXCEPT
Equality.
Definition: ImathVec.h:1379
IMATH_HOSTDEVICE constexpr Vec2 operator*(const Vec2 &v) const IMATH_NOEXCEPT
Component-wise multiplication.
Definition: ImathVec.h:1512
IMATH_HOSTDEVICE static constexpr T baseTypeEpsilon() IMATH_NOEXCEPT
Smallest possible e for which 1+e != 1.
Definition: ImathVec.h:984
IMATH_HOSTDEVICE T * getValue() IMATH_NOEXCEPT
Return a raw pointer to the array of values.
Definition: ImathVec.h:1823
IMATH_HOSTDEVICE constexpr Vec2 operator/(const Vec2 &v) const IMATH_NOEXCEPT
Component-wise division.
Definition: ImathVec.h:1544
#define IMATH_UNLIKELY(x)
Definition: ImathConfig.h:135
Definition: ImathVec.h:39
T x
Definition: ImathVec.h:701
IMATH_HOSTDEVICE constexpr bool operator!=(const Vec3< S > &v) const IMATH_NOEXCEPT
Inequality.
Definition: ImathVec.h:1846
LeafData & operator=(const LeafData &)=delete
IMATH_HOSTDEVICE static constexpr T baseTypeEpsilon() IMATH_NOEXCEPT
Smallest possible e for which 1+e != 1.
Definition: ImathVec.h:670
#define IMATH_EXPORT_TEMPLATE_TYPE
Definition: ImathExport.h:61
IMATH_HOSTDEVICE const Vec2 & normalizeNonNull() IMATH_NOEXCEPT
Definition: ImathVec.h:1637
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
IMATH_HOSTDEVICE void setValue(S a, S b, S c, S d) IMATH_NOEXCEPT
Set the value.
Definition: ImathVec.h:2249
FMT_CONSTEXPR basic_fp< F > normalize(basic_fp< F > value)
Definition: format.h:1701
IMATH_HOSTDEVICE constexpr Vec4 operator/(const Vec4 &v) const IMATH_NOEXCEPT
Component-wise division.
Definition: ImathVec.h:2470
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec4 & operator/=(const Vec4 &v) IMATH_NOEXCEPT
Component-wise division.
Definition: ImathVec.h:2448
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError(const Vec3< T > &v, T e) const IMATH_NOEXCEPT
Definition: ImathVec.h:1853
IMATH_HOSTDEVICE constexpr Vec2 operator+(const Vec2 &v) const IMATH_NOEXCEPT
Component-wise addition.
Definition: ImathVec.h:1455
IMATH_HOSTDEVICE constexpr T cross(const Vec2 &v) const IMATH_NOEXCEPT
Definition: ImathVec.h:1432
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T & operator[](int i) IMATH_NOEXCEPT
Definition: ImathVec.h:1682
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE constexpr T abs(T a) IMATH_NOEXCEPT
Definition: ImathFun.h:26
const Vec2 & normalizeExc()
Normalize in place. If length()==0, throw an exception.
Definition: ImathVec.h:1623
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError(const Vec2< T > &v, T e) const IMATH_NOEXCEPT
Definition: ImathVec.h:1394
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3 & operator=(const Vec3 &v) IMATH_NOEXCEPT
Assignment.
Definition: ImathVec.h:1740
IMATH_HOSTDEVICE Vec4() IMATH_NOEXCEPT
Uninitialized by default.
Definition: ImathVec.h:2189
#define IMATH_LIKELY(x)
Definition: ImathConfig.h:134
IMATH_HOSTDEVICE constexpr T operator%(const Vec2 &v) const IMATH_NOEXCEPT
Definition: ImathVec.h:1439
Definition: ImathVec.h:41
IMATH_HOSTDEVICE constexpr T operator^(const Vec2 &v) const IMATH_NOEXCEPT
Dot product.
Definition: ImathVec.h:1425
T BaseType
Definition: ImathVec.h:352
T w
Definition: ImathVec.h:701
enum IMATH_EXPORT_ENUM InfException
Enum for the Vec4 to Vec3 conversion constructor.
Definition: ImathVec.h:44
IMATH_HOSTDEVICE constexpr Vec3 operator%(const Vec3 &v) const IMATH_NOEXCEPT
Right-handed cross product.
Definition: ImathVec.h:1909
IMATH_HOSTDEVICE static constexpr T baseTypeSmallest() IMATH_NOEXCEPT
Smallest possible positive value.
Definition: ImathVec.h:331
T y
Definition: ImathVec.h:701
IMATH_HOSTDEVICE constexpr Vec3 cross(const Vec3 &v) const IMATH_NOEXCEPT
Right-handed cross product.
Definition: ImathVec.h:1889
IMATH_HOSTDEVICE const Vec3 & normalize() IMATH_NOEXCEPT
Normalize in place. If length()==0, return a null vector.
Definition: ImathVec.h:2083
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Vec3 & operator/=(const Vec3 &v) IMATH_NOEXCEPT
Component-wise division.
Definition: ImathVec.h:2001
SIM_DerVector3 cross(const SIM_DerVector3 &lhs, const SIM_DerVector3 &rhs)
Vec2< T > normalizedExc() const
Definition: ImathVec.h:1658
IMATH_HOSTDEVICE void setValue(S a, S b) IMATH_NOEXCEPT
Set the value.
Definition: ImathVec.h:1329
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T & operator[](int i) IMATH_NOEXCEPT
Definition: ImathVec.h:2166
IMATH_HOSTDEVICE T * getValue() IMATH_NOEXCEPT
Return a raw pointer to the array of values.
Definition: ImathVec.h:2292
IMATH_HOSTDEVICE T length() const IMATH_NOEXCEPT
Return the Euclidean norm.
Definition: ImathVec.h:1583
IMATH_HOSTDEVICE constexpr Vec3 operator*(const Vec3 &v) const IMATH_NOEXCEPT
Component-wise multiplication.
Definition: ImathVec.h:1987
IMATH_HOSTDEVICE const Vec2 & normalize() IMATH_NOEXCEPT
Normalize in place. If length()==0, return a null vector.
Definition: ImathVec.h:1602
IMATH_HOSTDEVICE Vec3() IMATH_NOEXCEPT
Uninitialized by default.
Definition: ImathVec.h:1705
IMATH_HOSTDEVICE const Vec4 & normalize() IMATH_NOEXCEPT
Normalize in place. If length()==0, return a null vector.
Definition: ImathVec.h:2537
IMATH_HOSTDEVICE constexpr Vec3 operator/(const Vec3 &v) const IMATH_NOEXCEPT
Component-wise division.
Definition: ImathVec.h:2021