HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_Vector3.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: Utility Library (C++)
7  *
8  * COMMENTS:
9  * This class handles fpreal vectors of dimension 3.
10  *
11  * WARNING:
12  * This class should NOT contain any virtual methods, nor should it
13  * define more member data. The size of UT_Vector3 must always be
14  * 12 bytes (3 floats).
15  */
16 
17 #pragma once
18 
19 #ifndef __UT_Vector3_h__
20 #define __UT_Vector3_h__
21 
22 #include "UT_API.h"
23 #include "UT_Assert.h"
24 #include "UT_FixedVectorTraits.h"
25 #include "UT_Storage.h"
26 #include "UT_FixedArrayMath.h"
27 #include "UT_VectorTypes.h"
28 #include "UT_Vector2.h"
29 #include <SYS/SYS_Deprecated.h>
30 #include <SYS/SYS_Inline.h>
31 #include <SYS/SYS_Math.h>
32 #include <SYS/SYS_TypeTraits.h>
33 #include <iosfwd>
34 #include <limits>
35 
36 class UT_IStream;
37 class UT_JSONWriter;
38 class UT_JSONValue;
39 class UT_JSONParser;
40 
41 // Free floating functions:
42 
43 // Right-multiply operators (M*v) have been removed. They had previously
44 // been defined to return v*M, which was too counterintuitive. Once HDK
45 // etc. users have a chance to update their code (post 7.0) we could
46 // reintroduce a right-multiply operator that does a colVecMult.
47 
48 template <typename T, typename S>
49 inline UT_Vector3T<T> operator*(const UT_Vector3T<T> &v, const UT_Matrix3T<S> &m);
50 template <typename T, typename S>
51 inline UT_Vector3T<T> operator*(const UT_Vector3T<T> &v, const UT_Matrix4T<S> &m);
52 template <typename T>
53 constexpr UT_Vector3T<T> operator+(const UT_Vector3T<T> &a, const UT_Vector3T<T> &b) noexcept;
54 template <typename T>
55 constexpr UT_Vector3T<T> operator-(const UT_Vector3T<T> &a, const UT_Vector3T<T> &b) noexcept;
56 template <typename T, typename S>
57 constexpr UT_Vector3T<T> operator+(const UT_Vector3T<T> &v, S scalar) noexcept;
58 template <typename T, typename S>
59 constexpr UT_Vector3T<T> operator-(const UT_Vector3T<T> &v, S scalar) noexcept;
60 template <typename T, typename S>
61 constexpr UT_Vector3T<T> operator*(const UT_Vector3T<T> &v, S scalar) noexcept;
62 template <typename T, typename S>
63 constexpr UT_Vector3T<T> operator/(const UT_Vector3T<T> &v, S scalar) noexcept;
64 template <typename T, typename S>
65 constexpr UT_Vector3T<T> operator+(S scalar, const UT_Vector3T<T> &v) noexcept;
66 template <typename T, typename S>
67 constexpr UT_Vector3T<T> operator-(S scalar, const UT_Vector3T<T> &v) noexcept;
68 template <typename T, typename S>
69 constexpr UT_Vector3T<T> operator*(S scalar, const UT_Vector3T<T> &v) noexcept;
70 template <typename T, typename S>
71 constexpr UT_Vector3T<T> operator/(S scalar, const UT_Vector3T<T> &v) noexcept;
72 
73 /// The dot and cross products between two vectors (see operator*() too)
74 // @{
75 template <typename T>
76 constexpr auto dot( const UT_Vector3T< T >& a, const UT_Vector3T< T >& b ) noexcept;
77 
78 template <typename T>
79 constexpr UT_Vector3T<T> cross(const UT_Vector3T<T> &a, const UT_Vector3T<T> &b) noexcept;
80 // @}
81 
82 /// The angle between two vectors in radians
83 // @{
84 template <typename T>
86 // @}
87 
88 /// Componentwise min and maximum
89 template <typename T>
91 template <typename T>
93 /// Componentwise equality.
94 template <typename T, typename S>
95 inline bool SYSisEqual(const UT_Vector3T<T> &a, const UT_Vector3T<T> &b, S tol = SYS_FTOLERANCE);
96 
97 /// Componentwise integer test
98 template <typename T>
99 inline bool SYSisInteger(const UT_Vector3T<T> &v1)
100 { return SYSisInteger(v1.x()) && SYSisInteger(v1.y()) && SYSisInteger(v1.z()); }
101 
102 /// Componentwise linear interpolation
103 template <typename T,typename S>
104 inline UT_Vector3T<T> SYSlerp(const UT_Vector3T<T> &v1, const UT_Vector3T<T> &v2, S t);
105 
106 /// Componentwise inverse linear interpolation
107 template <typename T>
109 
110 /// Bilinear interpolation
111 template <typename T,typename S>
112 inline UT_Vector3T<T> SYSbilerp(const UT_Vector3T<T> &u0v0, const UT_Vector3T<T> &u1v0,
113  const UT_Vector3T<T> &u0v1, const UT_Vector3T<T> &u1v1,
114  S u, S v)
115 { return SYSlerp(SYSlerp(u0v0, u0v1, v), SYSlerp(u1v0, u1v1, v), u); }
116 
117 /// Barycentric interpolation
118 template <typename T, typename S>
120  const UT_Vector3T<T> &v1, const UT_Vector3T<T> &v2, S u, S v)
121 { return v0 * (1 - u - v) + v1 * u + v2 *v; }
122 
123 
124 /// Trilinear hat function over kernel widths in s.
125 template <typename T>
126 inline T SYStrihat(const UT_Vector3T<T> &v, const UT_Vector3T<T> &s);
127 
128 /// Gradient of trilinear hat function over kernel widths in s.
129 template <typename T>
131 
132 /// The orthogonal projection of a vector u onto a vector v
133 template <typename T>
134 inline UT_Vector3T<T> project(const UT_Vector3T<T> &u, const UT_Vector3T<T> &v);
135 
136 // TODO: make UT_Vector4 versions of these:
137 
138 /// Compute the distance between two points
139 template <typename T>
140 inline T distance3d(const UT_Vector3T<T> &p1, const UT_Vector3T<T> &p2);
141 /// Compute the distance squared
142 template <typename T>
143 inline T distance2(const UT_Vector3T<T> &p1, const UT_Vector3T<T> &p2);
144 template <typename T>
145 inline T segmentPointDist2(const UT_Vector3T<T> &pos,
146  const UT_Vector3T<T> &pt1,
147  const UT_Vector3T<T> &pt2 );
148 /// Compute the squared minimum distance between a point and a semi-infinite
149 /// ray. Direction vector need not be normalized.
150 template <typename T>
151 inline T rayPointDist2(const UT_Vector3T<T> &pos,
152  const UT_Vector3T<T> &orig,
153  const UT_Vector3T<T> &dir);
154 /// Computes the squared minimum distance between a point and an infinite line.
155 /// Direction vector need not be normalized.
156 template <typename T>
157 inline T linePointDist2(const UT_Vector3T<T> &pos,
158  const UT_Vector3T<T> &orig,
159  const UT_Vector3T<T> &dir);
160 
161 /// Intersect the lines p1 + v1 * t1 and p2 + v2 * t2.
162 /// t1 and t2 are set so that the lines intersect when
163 /// projected to the plane defined by the two lines.
164 /// This function returns a value which indicates how close
165 /// to being parallel the lines are. Closer to zero means
166 /// more parallel. This is done so that the user of this
167 /// function can decide what epsilon they want to use.
168 template <typename T>
169 UT_API double intersectLines(const UT_Vector3T<T> &p1,
170  const UT_Vector3T<T> &v1,
171  const UT_Vector3T<T> &p2,
172  const UT_Vector3T<T> &v2,
173  T &t1, T &t2);
174 
175 /// Returns true if the segments from p0 to p1 and from a to b intersect, and
176 /// t will contain the parametric value of the intersection on the segment a-b.
177 /// Otherwise returns false. Parallel segments will return false. T is
178 /// close to being between 0.0 and 1.0 if this function returns true.
179 /// NOTE: Does not test the actual distance of the projected points
180 /// on each segment, merely that they are parmetrically within the
181 /// segment!
182 template <typename T>
184  const UT_Vector3T<T> &p1,
185  const UT_Vector3T<T> &a,
186  const UT_Vector3T<T> &b, T &t);
187 
188 /// Returns the U coordinates of the closest points on each of the two
189 /// parallel line segments
190 template <typename T>
192  const UT_Vector3T<T> &p1,
193  const UT_Vector3T<T> &a,
194  const UT_Vector3T<T> &b);
195 /// Returns the U coordinates of the closest points on each of the two
196 /// line segments
197 template <typename T>
199  const UT_Vector3T<T> &p1,
200  const UT_Vector3T<T> &a,
201  const UT_Vector3T<T> &b);
202 /// Returns the U coordinate of the point on line segment p0->p1
203 /// that is closest to a.
204 template <typename T>
206  const UT_Vector3T<T> &p0,
207  const UT_Vector3T<T> &p1,
208  const UT_Vector3T<T> &a);
209 
210 /// Returns the squared distance between two line segments: p0-p1 and a-b
211 template <typename T>
212 inline T segmentDistance2(const UT_Vector3T<T> &p0,
213  const UT_Vector3T<T> &p1,
214  const UT_Vector3T<T> &a,
215  const UT_Vector3T<T> &b);
216 /// Returns the distance between two line segments: p0-p1 and a-b
217 template <typename T>
218 inline T segmentDistance(const UT_Vector3T<T> &p0,
219  const UT_Vector3T<T> &p1,
220  const UT_Vector3T<T> &a,
221  const UT_Vector3T<T> &b);
222 
223 /// 3D Vector class.
224 template <typename T>
225 class UT_API UT_Vector3T
226 {
227 public:
228  typedef T value_type;
229  static constexpr int tuple_size = 3;
230 
231  /// Default constructor.
232  /// No data is initialized! Use it for extra speed.
233  SYS_FORCE_INLINE UT_Vector3T() = default;
234 
235  constexpr SYS_FORCE_INLINE UT_Vector3T(const UT_Vector3T<T> &that) = default;
236  constexpr SYS_FORCE_INLINE UT_Vector3T(UT_Vector3T<T> &&that) = default;
237 
238  constexpr SYS_FORCE_INLINE UT_Vector3T(const T vx, const T vy, const T vz) noexcept :
239  vec{ vx, vy, vz }
240  {}
241 
242  constexpr explicit SYS_FORCE_INLINE UT_Vector3T(const T v) noexcept :
243  UT_Vector3T( v, v, v )
244  {}
245 
246  constexpr SYS_FORCE_INLINE UT_Vector3T(const fpreal16 v[tuple_size]) noexcept :
247  UT_Vector3T( v[0], v[1], v[2] )
248  {}
249  constexpr SYS_FORCE_INLINE UT_Vector3T(const fpreal32 v[tuple_size]) noexcept :
250  UT_Vector3T( v[0], v[1], v[2] )
251  {}
252  constexpr SYS_FORCE_INLINE UT_Vector3T(const fpreal64 v[tuple_size]) noexcept :
253  UT_Vector3T( v[0], v[1], v[2] )
254  {}
255  constexpr SYS_FORCE_INLINE UT_Vector3T(const int32 v[tuple_size]) noexcept :
256  UT_Vector3T( v[0], v[1], v[2] )
257  {}
258  constexpr SYS_FORCE_INLINE UT_Vector3T(const int64 v[tuple_size]) noexcept :
259  UT_Vector3T( v[0], v[1], v[2] )
260  {}
261 
262  SYS_FORCE_INLINE explicit UT_Vector3T(const UT_Vector2T<T> &v);
263  SYS_FORCE_INLINE explicit UT_Vector3T(const UT_Vector4T<T> &v);
264 
265  /// Our own type of any given value_type.
266  template <typename S>
267  constexpr SYS_FORCE_INLINE UT_Vector3T(const UT_Vector3T<S>& v) noexcept :
268  UT_Vector3T( v[0], v[1], v[2] )
269  {}
270 
271  constexpr SYS_FORCE_INLINE UT_Vector3T<T> &operator=(const UT_Vector3T<T> &that) = default;
272  constexpr SYS_FORCE_INLINE UT_Vector3T<T> &operator=(UT_Vector3T<T> &&that) = default;
273 
274  template <typename S>
276  { vec[0] = v[0]; vec[1] = v[1]; vec[2] = v[2]; return *this; }
277 
278  constexpr SYS_FORCE_INLINE const T& operator[]( exint i ) const noexcept
279  {
280  UT_ASSERT_P( ( 0 <= i ) && ( i < tuple_size ) );
281 
282  return vec[ i ];
283  }
284 
285  constexpr SYS_FORCE_INLINE T& operator[]( exint i ) noexcept
286  {
287  UT_ASSERT_P( ( 0 <= i ) && ( i < tuple_size ) );
288 
289  return vec[ i ];
290  }
291 
292  constexpr SYS_FORCE_INLINE const T* data() const noexcept
293  {
294  return vec;
295  }
296 
297  constexpr SYS_FORCE_INLINE T* data() noexcept
298  {
299  return vec;
300  }
301 
302  constexpr SYS_FORCE_INLINE UT_Vector3T& operator+=( const UT_Vector3T& a ) noexcept
303  {
304  UT::FA::Add< T, tuple_size >{}( vec, a.vec );
305  return *this;
306  }
307 
308  constexpr SYS_FORCE_INLINE UT_Vector3T& operator-=( const UT_Vector3T& a ) noexcept
309  {
310  UT::FA::Subtract< T, tuple_size >{}( vec, a.vec );
311  return *this;
312  }
313 
314  constexpr SYS_FORCE_INLINE UT_Vector3T& operator+=( const T& a ) noexcept
315  {
317  return *this;
318  }
319 
320  constexpr SYS_FORCE_INLINE UT_Vector3T& operator-=( const T& a ) noexcept
321  {
323  return *this;
324  }
325 
326  constexpr SYS_FORCE_INLINE UT_Vector3T& operator*=( const T& a ) noexcept
327  {
329  return *this;
330  }
331 
332  constexpr SYS_FORCE_INLINE UT_Vector3T& operator/=( const T& a ) noexcept
333  {
334  using MF = UT_StorageMathFloat_t< T >;
335  UT::FA::Scale< T, tuple_size, MF >{}( vec, MF{1} / a );
336  return *this;
337  }
338 
339  constexpr SYS_FORCE_INLINE UT_Vector3T& operator*=( const UT_Vector3T& a ) noexcept
340  {
342  return *this;
343  }
344 
345  constexpr SYS_FORCE_INLINE UT_Vector3T& operator/=( const UT_Vector3T& a ) noexcept
346  {
348  return *this;
349  }
350 
351  constexpr SYS_FORCE_INLINE void negate() noexcept
352  {
354  }
355 
356  constexpr SYS_FORCE_INLINE T length2() const noexcept
357  {
358  return UT::FA::Length2< T, tuple_size >{}( vec );
359  }
360 
361  constexpr SYS_FORCE_INLINE T length() const noexcept
362  {
363  return SYSsqrt( length2() );
364  }
365 
366  constexpr SYS_FORCE_INLINE T distance2( const UT_Vector3T& b ) const noexcept
367  {
368  return UT::FA::Distance2< T, tuple_size >{}( vec, b.vec );
369  }
370 
371  constexpr SYS_FORCE_INLINE T distance( const UT_Vector3T& b ) const noexcept
372  {
373  return SYSsqrt( distance2( b ) );
374  }
375 
377  {
378  using MF = UT_StorageMathFloat_t< T >;
381  }
382 
383  constexpr SYS_FORCE_INLINE bool isNan() const noexcept
384  {
385  return UT::FA::AnyOf< T, tuple_size >{}( vec, [ & ]( const T& a ) { return SYSisNan( a ); } );
386  }
387 
388  constexpr SYS_FORCE_INLINE bool isFinite() const noexcept
389  {
390  return UT::FA::AllOf< T, tuple_size >{}( vec, [ & ]( const T& a ) { return SYSisFinite( a ); } );
391  }
392 
393  constexpr SYS_FORCE_INLINE bool isZero() const noexcept
394  {
396  }
397 
398  constexpr SYS_FORCE_INLINE bool equalZero( const T tolerance = SYS_FTOLERANCE ) const noexcept
399  {
400  return UT::FA::MaxNormIsLEQ< T, tuple_size >{}( vec, tolerance );
401  }
402 
403  constexpr SYS_FORCE_INLINE bool isEqual( const UT_Vector3T& b, const T tolerance = SYS_FTOLERANCE ) const noexcept
404  {
405  return UT::FA::MaxMetricIsLEQ< T, tuple_size >{}( vec, b.vec, tolerance );
406  }
407 
408  constexpr SYS_FORCE_INLINE T maxComponent() const noexcept
409  {
410  return UT::FA::Max< T, tuple_size >{}( vec );
411  }
412 
413  constexpr SYS_FORCE_INLINE T minComponent() const noexcept
414  {
415  return UT::FA::Min< T, tuple_size >{}( vec );
416  }
417 
418  constexpr SYS_FORCE_INLINE T avgComponent() const noexcept
419  {
420  return UT::FA::Sum< T, tuple_size >{}( vec ) / T{ tuple_size };
421  }
422 
423  /// Assignment operator that truncates a V4 to a V3.
424  /// TODO: remove this. This should require an explicit UT_Vector3()
425  /// construction, since it's unsafe.
426  SYS_DEPRECATED_HDK_REPLACE(16.0,explicit UT_Vector3 constructor to avoid implicit conversion from UT_Vector4)
428 
429  constexpr SYS_FORCE_INLINE UT_Vector3T& operator=( const T a ) noexcept;
430 
431  constexpr SYS_FORCE_INLINE UT_Vector3T<T> operator-() const noexcept
432  {
433  return UT_Vector3T<T>(-vec[0], -vec[1], -vec[2]);
434  }
435 
436  void clampZero(T tol = T(0.00001f))
437  {
438  if (vec[0] >= -tol && vec[0] <= tol) vec[0] = 0;
439  if (vec[1] >= -tol && vec[1] <= tol) vec[1] = 0;
440  if (vec[2] >= -tol && vec[2] <= tol) vec[2] = 0;
441  }
442 
445  {
446  vec[0] *= v.vec[0];
447  vec[1] *= v.vec[1];
448  vec[2] *= v.vec[2];
449  }
450 
451  /// If you need a multiplication operator that left multiplies the vector
452  /// by a matrix (M * v), use the following colVecMult() functions. If
453  /// you'd rather not use operator*=() for right-multiplications (v * M),
454  /// use the following rowVecMult() functions. The methods that take a 4x4
455  /// matrix first extend this vector to 4D by adding an element equal to 1.0.
456  /// @internal These are implemented in UT_Matrix3.h and UT_Matrix4.h
457  // @{
458  SYS_FORCE_INLINE void rowVecMult(const UT_Matrix3F &m);
459  SYS_FORCE_INLINE void rowVecMult(const UT_Matrix4F &m);
460  SYS_FORCE_INLINE void rowVecMult(const UT_Matrix3D &m);
461  SYS_FORCE_INLINE void rowVecMult(const UT_Matrix4D &m);
462  SYS_FORCE_INLINE void colVecMult(const UT_Matrix3F &m);
463  SYS_FORCE_INLINE void colVecMult(const UT_Matrix4F &m);
464  SYS_FORCE_INLINE void colVecMult(const UT_Matrix3D &m);
465  SYS_FORCE_INLINE void colVecMult(const UT_Matrix4D &m);
466  // @}
467 
468 
469  /// This multiply will not extend the vector by adding a fourth element.
470  /// Instead, it converts the Matrix4 to a Matrix3. This means that
471  /// the translate component of the matrix is not applied to the vector
472  /// @internal These are implemented in UT_Matrix4.h
473  // @{
478  // @}
479 
480 
481 
482  /// The *=, multiply, multiply3 and multiplyT routines are provided for
483  /// legacy reasons. They all assume that *this is a row vector. Generally,
484  /// the rowVecMult and colVecMult methods are preferred, since they're
485  /// more explicit about the row vector assumption.
486  // @{
487  template <typename S>
489  template <typename S>
491 
492  template <typename S>
493  SYS_FORCE_INLINE void multiply3(const UT_Matrix4T<S> &mat);
494  // @}
495 
496  /// This multiply will multiply the (row) vector by the transpose of the
497  /// matrix instead of the matrix itself. This is faster than
498  /// transposing the matrix, then multiplying (as well there's potentially
499  /// less storage requirements).
500  // @{
501  template <typename S>
502  SYS_FORCE_INLINE void multiplyT(const UT_Matrix3T<S> &mat);
503  template <typename S>
504  SYS_FORCE_INLINE void multiply3T(const UT_Matrix4T<S> &mat);
505  // @}
506 
507  /// The following methods implement multiplies (row) vector by a matrix,
508  /// however, the resulting vector is specified by the dest parameter
509  /// These operations are safe even if "dest" is the same as "this".
510  // @{
511  template <typename S>
512  SYS_FORCE_INLINE void multiply3(UT_Vector3T<T> &dest,
513  const UT_Matrix4T<S> &mat) const;
514  template <typename S>
515  SYS_FORCE_INLINE void multiplyT(UT_Vector3T<T> &dest,
516  const UT_Matrix3T<S> &mat) const;
517  template <typename S>
518  SYS_FORCE_INLINE void multiply3T(UT_Vector3T<T> &dest,
519  const UT_Matrix4T<S> &mat) const;
520  template <typename S>
522  const UT_Matrix4T<S> &mat) const;
523  template <typename S>
525  const UT_Matrix3T<S> &mat) const;
526  // @}
527 
528  constexpr SYS_FORCE_INLINE
529  T dot(const UT_Vector3T& b) const noexcept
530  {
531  return UT::FA::Dot< T, tuple_size >{}( vec, b.vec );
532  }
533 
534  constexpr SYS_FORCE_INLINE void cross(const UT_Vector3T<T> &v) noexcept
535  {
536  operator=(::cross(*this, v));
537  }
538 
540  {
541  vec[0] += (va.vec[2]+vb.vec[2])*(vb.vec[1]-va.vec[1]);
542  vec[1] += (va.vec[0]+vb.vec[0])*(vb.vec[2]-va.vec[2]);
543  vec[2] += (va.vec[1]+vb.vec[1])*(vb.vec[0]-va.vec[0]);
544  }
545 
546  /// Finds an arbitrary perpendicular to v, and sets this to it.
547  void arbitraryPerp(const UT_Vector3T<T> &v);
548  /// Makes this orthogonal to the given vector. If they are colinear,
549  /// does an arbitrary perp
550  void makeOrthonormal(const UT_Vector3T<T> &v);
551 
552  /// These allow you to find out what indices to use for different axes
553  // @{
554  int findMinAbsAxis() const
555  {
556  T ax = SYSabs(x()), ay = SYSabs(y());
557  if (ax < ay)
558  return (SYSabs(z()) < ax) ? 2 : 0;
559  else
560  return (SYSabs(z()) < ay) ? 2 : 1;
561  }
562  int findMaxAbsAxis() const
563  {
564  T ax = SYSabs(x()), ay = SYSabs(y());
565  if (ax >= ay)
566  return (SYSabs(z()) >= ax) ? 2 : 0;
567  else
568  return (SYSabs(z()) >= ay) ? 2 : 1;
569  }
570  // @}
571 
572  /// Given this vector as the z-axis, get a frame of reference such that the
573  /// X and Y vectors are orthonormal to the vector. This vector should be
574  /// normalized.
576  {
577  if (SYSabs(x()) < 0.6F) Y = UT_Vector3T<T>(1, 0, 0);
578  else if (SYSabs(z()) < 0.6F) Y = UT_Vector3T<T>(0, 1, 0);
579  else Y = UT_Vector3T<T>(0, 0, 1);
580  X = ::cross(Y, *this);
581  X.normalize();
582  Y = ::cross(*this, X);
583  }
584 
585  /// Calculates the orthogonal projection of a vector u on the *this vector
586  UT_Vector3T<T> project(const UT_Vector3T<T> &u) const;
587 
588  /// Create a matrix of projection onto this vector: the matrix transforms
589  /// a vector v into its projection on the direction of (*this) vector,
590  /// ie. dot(*this, v) * this->normalize();
591  /// If we need to be normalized, set norm to non-false.
592  template <typename S>
593  UT_Matrix3T<S> project(bool norm=true);
594 
595  /// Vector p (representing a point in 3-space) and vector v define
596  /// a line. This member returns the projection of "this" onto the
597  /// line (the point on the line that is closest to this point).
598  UT_Vector3T<T> projection(const UT_Vector3T<T> &p,
599  const UT_Vector3T<T> &v) const;
600 
601  /// Projects this onto the line segement [a,b]. The returned point
602  /// will lie between a and b.
603  UT_Vector3T<T> projectOnSegment(const UT_Vector3T<T> &va,
604  const UT_Vector3T<T> &vb) const;
605  /// Projects this onto the line segment [a, b]. The fpreal t is set
606  /// to the parametric position of intersection, a being 0 and b being 1.
607  UT_Vector3T<T> projectOnSegment(const UT_Vector3T<T> &va, const UT_Vector3T<T> &vb,
608  T &t) const;
609 
610  /// Create a matrix of symmetry around this vector: the matrix transforms
611  /// a vector v into its symmetry around (*this), ie. two times the
612  /// projection of v onto (*this) minus v.
613  /// If we need to be normalized, set norm to non-false.
614  UT_Matrix3 symmetry(bool norm=true);
615 
616  /// This method stores in (*this) the intersection between two 3D lines,
617  /// p1+t*v1 and p2+u*v2. If the two lines do not actually intersect, we
618  /// shift the 2nd line along the perpendicular on both lines (along the
619  /// line of min distance) and return the shifted intersection point; this
620  /// point thus lies on the 1st line.
621  /// If we find an intersection point (shifted or not) we return 0; if
622  /// the two lines are parallel we return -1; and if they intersect
623  /// behind our back we return -2. When we return -2 there still is a
624  /// valid intersection point in (*this).
625  int lineIntersect(const UT_Vector3T<T> &p1, const UT_Vector3T<T> &v1,
626  const UT_Vector3T<T> &p2, const UT_Vector3T<T> &v2);
627 
628  /// Compute the intersection of vector p2+t*v2 and the line segment between
629  /// points pa and pb. If the two lines do not intersect we shift the
630  /// (p2, v2) line along the line of min distance and return the point
631  /// where it intersects the segment. If we find an intersection point
632  /// along the stretch between pa and pb, we return 0. If the lines are
633  /// parallel we return -1. If they intersect before pa we return -2, and
634  /// if after pb, we return -3. The intersection point is valid with
635  /// return codes 0,-2,-3.
636  int segLineIntersect(const UT_Vector3T<T> &pa, const UT_Vector3T<T> &pb,
637  const UT_Vector3T<T> &p2, const UT_Vector3T<T> &v2);
638 
639  /// Determines whether or not the points p0, p1 and "this" are collinear.
640  /// If they are t contains the parametric value of where "this" is found
641  /// on the segment from p0 to p1 and returns true. Otherwise returns
642  /// false. If p0 and p1 are equal, t is set to
643  /// std::numeric_limits<T>::max() and true is returned.
644  bool areCollinear(const UT_Vector3T<T> &p0, const UT_Vector3T<T> &p1,
645  T *t = 0, T tol = 1e-5) const;
646 
647  /// Compute (homogeneous) barycentric co-ordinates of this point
648  /// relative to the triangle defined by t0, t1 and t2. (The point is
649  /// projected into the triangle's plane.)
650  UT_Vector3T<T> getBary(const UT_Vector3T<T> &t0, const UT_Vector3T<T> &t1,
651  const UT_Vector3T<T> &t2, bool *degen = NULL) const;
652 
653 
654  /// Compute the signed distance from us to a line.
655  T distance(const UT_Vector3T<T> &p1, const UT_Vector3T<T> &v1) const;
656  /// Compute the signed distance between two lines.
657  T distance(const UT_Vector3T<T> &p1, const UT_Vector3T<T> &v1,
658  const UT_Vector3T<T> &p2, const UT_Vector3T<T> &v2) const;
659 
660  /// Return the components of the vector. The () operator does NOT check
661  /// for the boundary condition.
662  /// @{
663  constexpr SYS_FORCE_INLINE T &x() noexcept { return vec[0]; }
664  constexpr SYS_FORCE_INLINE T x() const noexcept { return vec[0]; }
665  constexpr SYS_FORCE_INLINE T &y() noexcept { return vec[1]; }
666  constexpr SYS_FORCE_INLINE T y() const noexcept { return vec[1]; }
667  constexpr SYS_FORCE_INLINE T &z() noexcept { return vec[2]; }
668  constexpr SYS_FORCE_INLINE T z() const noexcept { return vec[2]; }
669  constexpr SYS_FORCE_INLINE T &r() noexcept { return vec[0]; }
670  constexpr SYS_FORCE_INLINE T r() const noexcept { return vec[0]; }
671  constexpr SYS_FORCE_INLINE T &g() noexcept { return vec[1]; }
672  constexpr SYS_FORCE_INLINE T g() const noexcept { return vec[1]; }
673  constexpr SYS_FORCE_INLINE T &b() noexcept { return vec[2]; }
674  constexpr SYS_FORCE_INLINE T b() const noexcept { return vec[2]; }
675 
676  constexpr SYS_FORCE_INLINE T &operator()(unsigned i) noexcept
677  {
678  UT_ASSERT_P(i < tuple_size);
679  return vec[i];
680  }
681  constexpr SYS_FORCE_INLINE T operator()(unsigned i) const noexcept
682  {
683  UT_ASSERT_P( i < tuple_size );
684  return vec[i];
685  }
686  /// @}
687 
688  /// Compute a hash
689  unsigned hash() const { return SYSvector_hash(data(), tuple_size); }
690 
691  // TODO: eliminate these methods. They're redundant, given good inline
692  // constructors.
693  /// Set the values of the vector components
694  void assign(T xx = 0.0f, T yy = 0.0f, T zz = 0.0f)
695  {
696  vec[0] = xx; vec[1] = yy; vec[2] = zz;
697  }
698  /// Set the values of the vector components
699  void assign(const T *v)
700  {
701  vec[0]=v[0]; vec[1]=v[1]; vec[2]=v[2];
702  }
703 
704  /// Express the point in homogeneous coordinates or vice-versa
705  // @{
706  void homogenize()
707  {
708  vec[0] *= vec[2];
709  vec[1] *= vec[2];
710  }
712  {
713  if (vec[2] != 0)
714  {
715  T denom = 1.0f / vec[2];
716  vec[0] *= denom;
717  vec[1] *= denom;
718  }
719  }
720  // @}
721 
722  /// assuming that "this" is a rotation (in radians, of course), the
723  /// equivalent set of rotations which are closest to the "base" rotation
724  /// are found. The equivalent rotations are the same as the original
725  /// rotations +2*n*PI
726  void roundAngles(const UT_Vector3T<T> &base);
727 
728  /// conversion between degrees and radians
729  // @{
730  void degToRad();
731  void radToDeg();
732  // @}
733 
734  /// It seems that given any rotation matrix and transform order,
735  /// there are two distinct triples of rotations that will result in
736  /// the same overall rotation. This method will find the closest of
737  /// the two after finding the closest using the above method.
738  void roundAngles(const UT_Vector3T<T> &b, const UT_XformOrder &o);
739 
740  /// Return the dual of the vector
741  /// The dual is a matrix which acts like the cross product when
742  /// multiplied by other vectors.
743  /// The following are equivalent:
744  /// a.getDual(A); c = colVecMult(A, b)
745  /// c = cross(a, b)
746  template <typename S>
747  void getDual(UT_Matrix3T<S> &dual) const;
748 
749  /// Protected I/O methods
750  // @{
751  void save(std::ostream &os, bool binary = false) const;
752  bool load(UT_IStream &is);
753  // @}
754 
755  /// @{
756  /// Methods to serialize to a JSON stream. The vector is stored as an
757  /// array of 3 reals.
758  bool save(UT_JSONWriter &w) const;
759  bool save(UT_JSONValue &v) const;
760  bool load(UT_JSONParser &p);
761  /// @}
762 
763  /// @{
764  /// Method to return the angle (in radians) between this and another vector
766  {
767  return ::UTangleBetween(*this, v);
768  }
769  /// @}
770 
771  /// Returns the vector size
772  static int entries() { return tuple_size; }
773 
774  T vec[tuple_size];
775 
776 private:
777 
778  friend constexpr bool isZero( const UT_Vector3T& a ) noexcept
779  {
781  }
782 
783  friend constexpr auto length2( const UT_Vector3T& a ) noexcept
784  {
785  return UT::FA::Length2< T, tuple_size >{}( a.vec );
786  }
787 
788  friend constexpr auto distance2( const UT_Vector3T& a, const UT_Vector3T& b ) noexcept
789  {
790  return UT::FA::Distance2< T, tuple_size >{}( a.vec, b.vec );
791  }
792 
793  friend constexpr bool operator==( const UT_Vector3T& a, const UT_Vector3T& b ) noexcept
794  {
795  return UT::FA::AreEqual< T, tuple_size >{}( a.vec, b.vec );
796  }
797 
798  friend constexpr bool operator!=( const UT_Vector3T& a, const UT_Vector3T& b ) noexcept
799  {
800  return ! UT::FA::AreEqual< T, tuple_size >{}( a.vec, b.vec );
801  }
802 
803  /// Lexicographic order comparison operators
804  /// @{
805  friend constexpr bool operator<( const UT_Vector3T& a, const UT_Vector3T& b ) noexcept
806  {
807  return UT::FA::TernaryOrder< T, tuple_size >{}( a.vec, b.vec ) < 0;
808  }
809 
810  friend constexpr bool operator<=( const UT_Vector3T& a, const UT_Vector3T& b ) noexcept
811  {
812  return UT::FA::TernaryOrder< T, tuple_size >{}( a.vec, b.vec ) <= 0;
813  }
814 
815  friend constexpr bool operator>( const UT_Vector3T& a, const UT_Vector3T& b ) noexcept
816  {
817  return UT::FA::TernaryOrder< T, tuple_size >{}( a.vec, b.vec ) > 0;
818  }
819 
820  friend constexpr bool operator>=( const UT_Vector3T& a, const UT_Vector3T& b ) noexcept
821  {
822  return UT::FA::TernaryOrder< T, tuple_size >{}( a.vec, b.vec ) >= 0;
823  }
824  /// @}
825 
826  /// I/O friends
827  // @{
828  friend std::ostream &operator<<(std::ostream &os, const UT_Vector3T<T> &v)
829  {
830  v.save(os);
831  return os;
832  }
833  // @}
834 };
835 
836 // Required for constructor
837 #include "UT_Vector2.h"
838 #include "UT_Vector4.h"
839 
840 template <typename T>
842 {
843  vec[0] = v.x();
844  vec[1] = v.y();
845  vec[2] = T(0);
846 }
847 template <typename T>
849 {
850  vec[0] = v.x();
851  vec[1] = v.y();
852  vec[2] = v.z();
853 }
854 
855 template <typename T>
857 {
858  for ( int i = 0; i != tuple_size; ++i )
859  {
860  vec[i] = a;
861  }
862 
863  return *this;
864 }
865 
866 // Free floating functions:
867 template <typename T>
868 constexpr
870 {
871  return UT_Vector3T<T>(a.vec[0]+b.vec[0], a.vec[1]+b.vec[1], a.vec[2]+b.vec[2]);
872 }
873 
874 template <typename T>
875 constexpr
877 {
878  return UT_Vector3T<T>(a.vec[0]-b.vec[0], a.vec[1]-b.vec[1], a.vec[2]-b.vec[2]);
879 }
880 
881 template <typename T, typename S>
882 constexpr
883 UT_Vector3T<T> operator+(const UT_Vector3T<T> &v, S scalar) noexcept
884 {
885  return UT_Vector3T<T>(v.vec[0]+scalar, v.vec[1]+scalar, v.vec[2]+scalar);
886 }
887 
888 template <typename T>
889 constexpr
891 {
892  return UT_Vector3T<T>(v1.vec[0]*v2.vec[0], v1.vec[1]*v2.vec[1], v1.vec[2]*v2.vec[2]);
893 }
894 
895 template <typename T>
896 constexpr
898 {
899  return UT_Vector3T<T>(v1.vec[0]/v2.vec[0], v1.vec[1]/v2.vec[1], v1.vec[2]/v2.vec[2]);
900 }
901 
902 template <typename T, typename S>
903 constexpr
904 UT_Vector3T<T> operator+(S scalar, const UT_Vector3T<T> &v) noexcept
905 {
906  return UT_Vector3T<T>(v.vec[0]+scalar, v.vec[1]+scalar, v.vec[2]+scalar);
907 }
908 
909 template <typename T, typename S>
910 constexpr
911 UT_Vector3T<T> operator-(const UT_Vector3T<T> &v, S scalar) noexcept
912 {
913  return UT_Vector3T<T>(v.vec[0]-scalar, v.vec[1]-scalar, v.vec[2]-scalar);
914 }
915 
916 template <typename T, typename S>
917 constexpr
918 UT_Vector3T<T> operator-(S scalar, const UT_Vector3T<T> &v) noexcept
919 {
920  return UT_Vector3T<T>(scalar-v.vec[0], scalar-v.vec[1], scalar-v.vec[2]);
921 }
922 
923 template <typename T, typename S>
924 constexpr
925 UT_Vector3T<T> operator*(const UT_Vector3T<T> &v, S scalar) noexcept
926 {
927  return UT_Vector3T<T>(v.vec[0]*scalar, v.vec[1]*scalar, v.vec[2]*scalar);
928 }
929 
930 template <typename T, typename S>
931 constexpr
932 UT_Vector3T<T> operator*(S scalar, const UT_Vector3T<T> &v) noexcept
933 {
934  return UT_Vector3T<T>(v.vec[0]*scalar, v.vec[1]*scalar, v.vec[2]*scalar);
935 }
936 
937 template <typename T, typename S>
938 constexpr
939 UT_Vector3T<T> operator/(const UT_Vector3T<T> &v, S scalar) noexcept
940 {
941  //TODO: in C++17, this can be "if constexpr"
942  if ( SYS_IsFloatingPoint_v< T > )
943  {
944  // This has to be T because S may be int for "v = v/2" code
945  // For the same reason we must cast the 1
946  T inv = T(1) / scalar;
947  return UT_Vector3T<T>(v.vec[0]*inv, v.vec[1]*inv, v.vec[2]*inv);
948  }
949  return UT_Vector3T<T>(v.vec[0]/scalar, v.vec[1]/scalar, v.vec[2]/scalar);
950 }
951 
952 template <typename T, typename S>
953 constexpr
954 UT_Vector3T<T> operator/(S scalar, const UT_Vector3T<T> &v) noexcept
955 {
956  return UT_Vector3T<T>(scalar/v.vec[0], scalar/v.vec[1], scalar/v.vec[2]);
957 }
958 
959 template <typename T>
960 constexpr auto dot( const UT_Vector3T< T >& a, const UT_Vector3T< T >& b ) noexcept
961 {
962  return UT::FA::Dot< T, 3 >{}( a.vec, b.vec );
963 }
964 
965 template <typename T>
966 constexpr
968 {
969  return UT_Vector3T<T>(
970  a.vec[1]*b.vec[2] - a.vec[2]*b.vec[1],
971  a.vec[2]*b.vec[0] - a.vec[0]*b.vec[2],
972  a.vec[0]*b.vec[1] - a.vec[1]*b.vec[0]
973  );
974 }
975 
976 template <typename T>
977 inline
979 {
980  UT_Vector3T<fpreal64> v1crossv2 = cross(v1, v2);
981  fpreal v1dotv2 = dot(v1, v2);
982  return SYSatan2(v1crossv2.length(), v1dotv2);
983 }
984 
985 template <typename T>
986 inline
988 {
989  return UT_Vector3T<T>(SYSabs(v.x()), SYSabs(v.y()), SYSabs(v.z()));
990 }
991 
992 template <typename T>
993 inline
995 {
996  return UT_Vector3T<T>(
997  SYSmin(v1.x(), v2.x()),
998  SYSmin(v1.y(), v2.y()),
999  SYSmin(v1.z(), v2.z())
1000  );
1001 }
1002 
1003 template <typename T>
1004 inline
1006 {
1007  return UT_Vector3T<T>(
1008  SYSmax(v1.x(), v2.x()),
1009  SYSmax(v1.y(), v2.y()),
1010  SYSmax(v1.z(), v2.z())
1011  );
1012 }
1013 
1014 template <typename T, typename S>
1015 inline bool
1017 {
1018  return a.isEqual(b, tol);
1019 }
1020 
1021 template <typename T,typename S>
1022 inline
1024 {
1025  return UT_Vector3T<T>(
1026  SYSlerp(v1.x(), v2.x(), t),
1027  SYSlerp(v1.y(), v2.y(), t),
1028  SYSlerp(v1.z(), v2.z(), t));
1029 }
1030 
1031 template <typename T>
1032 inline
1034  const UT_Vector3T<T> &v2,
1035  const UT_Vector3T<T> &t)
1036 {
1037  return UT_Vector3T<T>(
1038  SYSlerp(v1.x(), v2.x(), t.x()),
1039  SYSlerp(v1.y(), v2.y(), t.y()),
1040  SYSlerp(v1.z(), v2.z(), t.z()));
1041 }
1042 
1043 template <typename T>
1044 inline
1046  const UT_Vector3T<T> &v1,
1047  const UT_Vector3T<T> &v2)
1048 {
1049  return UT_Vector3T<T>(
1050  SYSinvlerp(a.x(), v1.x(), v2.x()),
1051  SYSinvlerp(a.y(), v1.y(), v2.y()),
1052  SYSinvlerp(a.z(), v1.z(), v2.z()));
1053 }
1054 
1055 template <typename T>
1056 inline
1058  const UT_Vector3T<T> &min,
1059  const UT_Vector3T<T> &max)
1060 {
1061  return UT_Vector3T<T>(
1062  SYSclamp(v.x(), min.x(), max.x()),
1063  SYSclamp(v.y(), min.y(), max.y()),
1064  SYSclamp(v.z(), min.z(), max.z()));
1065 }
1066 
1067 template <typename T>
1068 inline
1070 {
1071  return SYSequalZero(v.x()) && SYSequalZero(v.y()) && SYSequalZero(v.z());
1072 }
1073 
1074 template <typename T>
1075 inline
1077 {
1078  return SYSisFinite(v.x()) && SYSisFinite(v.y()) && SYSisFinite(v.z());
1079 }
1080 
1081 template <typename T>
1082 inline
1084 {
1085  return UT_Vector3T<T>(SYSrecip(v[0]), SYSrecip(v[1]), SYSrecip(v[2]));
1086 }
1087 
1088 template <typename T>
1089 inline
1091 {
1092  return SYShat(v.x(), s.x()) * SYShat(v.y(), s.y()) * SYShat(v.z(), s.z());
1093 }
1094 
1095 template <typename T>
1096 inline
1098 {
1099  const T xhat = SYShat(v.x(), s.x());
1100  const T yhat = SYShat(v.y(), s.y());
1101  const T zhat = SYShat(v.z(), s.z());
1102  return UT_Vector3T<T>(SYSdhat(v.x(), s.x()) * yhat * zhat,
1103  xhat * SYSdhat(v.y(), s.y()) * zhat,
1104  xhat * yhat * SYSdhat(v.z(), s.z()));
1105 }
1106 
1107 template <typename T>
1108 inline
1110 {
1111  return dot(u, v) / v.length2() * v;
1112 }
1113 
1114 template <typename T>
1115 inline
1117 {
1118  return (v1 - v2).length();
1119 }
1120 template <typename T>
1121 inline
1123 {
1124  return (v1 - v2).length2();
1125 }
1126 
1127 // calculate distance squared of pos to the line segment defined by pt1 to pt2
1128 template <typename T>
1129 inline
1131  const UT_Vector3T<T> &pt1, const UT_Vector3T<T> &pt2 )
1132 {
1133  UT_Vector3T<T> vec;
1134  T proj_t;
1135  T veclen2;
1136 
1137  vec = pt2 - pt1;
1138  proj_t = vec.dot( pos - pt1 );
1139  veclen2 = vec.length2();
1140 
1141  if( proj_t <= (T)0.0 )
1142  {
1143  // in bottom cap region, calculate distance from pt1
1144  vec = pos - pt1;
1145  }
1146  else if( proj_t >= veclen2 )
1147  {
1148  // in top cap region, calculate distance from pt2
1149  vec = pos - pt2;
1150  }
1151  else
1152  {
1153  // middle region, calculate distance from projected pt
1154  proj_t /= veclen2;
1155  vec = (pt1 + (proj_t * vec)) - pos;
1156  }
1157 
1158  return dot(vec, vec);
1159 }
1160 
1161 template <typename T>
1162 inline
1164  const UT_Vector3T<T> &orig,
1165  const UT_Vector3T<T> &dir)
1166 {
1167  UT_Vector3T<T> dir_hat = dir;
1168  dir_hat.normalize();
1169  UT_Vector3T<T> vec = pos - orig;
1170  T proj = vec.dot(dir_hat);
1171  return distance2(SYSmax(proj, T(0)) * dir_hat, vec);
1172 }
1173 
1174 template <typename T>
1175 inline
1177  const UT_Vector3T<T> &orig,
1178  const UT_Vector3T<T> &dir)
1179 {
1180  UT_Vector3T<T> dir_hat = dir;
1181  dir_hat.normalize();
1182  UT_Vector3T<T> vec = pos - orig;
1183  T proj = vec.dot(dir_hat);
1184  return distance2(proj * dir_hat, vec);
1185 }
1186 
1187 // TODO: review the effiency of the following routine, there is a faster
1188 // way to get just the distance.
1189 template <typename T>
1190 inline
1192  const UT_Vector3T<T> &q0, const UT_Vector3T<T> &q1)
1193 {
1194  UT_Vector2 t = segmentClosest(p0, p1, q0, q1);
1195  UT_Vector3 a = p0 + (p1 - p0) * t[0];
1196  UT_Vector3 b = q0 + (q1 - q0) * t[1];
1197  return distance2(a, b);
1198 }
1199 
1200 template <typename T>
1201 inline
1203  const UT_Vector3T<T> &q0, const UT_Vector3T<T> &q1)
1204 {
1205  return SYSsqrt(segmentDistance2(p0, p1, q0, q1));
1206 }
1207 
1208 /// Given a 3D position, input, and a 3D parallelpiped with corner p0 and
1209 /// directions du, dv, and dw, finds the 0 or 1 locations in the parameter
1210 /// space of that parallelpiped that correspond with the input position.
1211 /// Only a parameter location approximately between 0 and 1
1212 /// is accepted. The return value is the number of accepted parameter locations,
1213 /// i.e. 0 or 1.
1214 template <typename T>
1216  const UT_Vector3T<T> &p0,
1217  const UT_Vector3T<T> &du, const UT_Vector3T<T> &dv, const UT_Vector3T<T> &dw,
1218  UT_Vector3T<T> &output)
1219 {
1220  const UT_Vector3T<T> orig = input - p0;
1221 
1222  const UT_Matrix3T<T> matrix(
1223  du.x(), dv.x(), dw.x(),
1224  du.y(), dv.y(), dw.y(),
1225  du.z(), dv.z(), dw.z()
1226  );
1227 
1228  bool failed = matrix.solve(orig.x(), orig.y(), orig.z(), output);
1229  return !failed &&
1230  SYSisGreaterOrEqual(output.x(), 0) && SYSisLessOrEqual(output.x(), 1) &&
1231  SYSisGreaterOrEqual(output.y(), 0) && SYSisLessOrEqual(output.y(), 1) &&
1232  SYSisGreaterOrEqual(output.z(), 0) && SYSisLessOrEqual(output.z(), 1);
1233 }
1234 
1235 template <typename T>
1236 inline size_t hash_value(const UT_Vector3T<T> &val)
1237 {
1238  return val.hash();
1239 }
1240 
1241 // Overload for custom formatting of UT_Vector3T<T> with UTformat.
1242 template<typename T>
1243 UT_API size_t format(char *buffer, size_t buffer_size, const UT_Vector3T<T> &v);
1244 
1245 template< typename T, exint D >
1246 class UT_FixedVector;
1247 
1248 template<typename T>
1250 {
1252  typedef T DataType;
1253  static const exint TupleSize = 3;
1254  static const bool isVectorType = true;
1255 };
1256 
1257 // UT_Vector3T in the role of a fixed array-like type.
1258 
1259 template< typename T >
1261 
1262 template< typename T >
1264 
1265 template< typename T >
1266 struct SYS_FixedArraySizeNoCVRef< UT_Vector3T< T > > : std::integral_constant< std::size_t, 3 > {};
1267 
1268 
1269 // UT_Vector3TFromUnbounded<T> is a function object that
1270 // creates a UT_Vector2T<T> from an unbounded array-like type 'as'.
1271 // 'as' must have at size at least 3.
1272 template <typename T>
1274 {
1275  template< typename TS >
1276  constexpr SYS_FORCE_INLINE UT_Vector3T<T> operator()(const TS& as) const noexcept
1277  {
1278  return UT_Vector3T<T>( as[0], as[1], as[2] );
1279  }
1280 };
1281 
1282 // UT_FromUnbounded<V> creates a V from an unbounded array-like type
1283 
1284 // Primary
1285 template <typename V >
1286 struct UT_FromUnbounded;
1287 
1288 // Partial specialization for UT_Vector3T
1289 template <typename T>
1291 
1292 
1293 // UT_Vector3TFromFixed<T> is a function object that
1294 // creates a UT_Vector3T<T> from a fixed array-like type TS,
1295 // examples of which include T[3], UT_FixedVector<T,3> and UT_FixedArray<T,3> (AKA std::array<T,3>)
1296 template <typename T>
1298 {
1299  template< typename TS >
1300  constexpr SYS_FORCE_INLINE UT_Vector3T<T> operator()(const TS& as) const noexcept
1301  {
1302  SYS_STATIC_ASSERT( SYS_IsFixedArrayOf_v< TS, T, 3 > );
1303 
1304  return UT_Vector3TFromUnbounded< T >{}( as );
1305  }
1306 };
1307 
1308 // Convert a fixed array-like type TS into a UT_Vector3T< T >.
1309 // This allows conversion to UT_Vector3T without fixing T.
1310 // Instead, the element type of TS determines the type T.
1311 template< typename TS >
1313 UTmakeVector3T( const TS& as ) noexcept
1314 {
1316 
1317  return UT_Vector3TFromFixed< T >{}( as );
1318 }
1319 
1320 // UT_FromFixed<V> creates a V from a flat, fixed array-like representation
1321 
1322 // Primary
1323 template <typename V >
1324 struct UT_FromFixed;
1325 
1326 // Partial specialization for UT_Vector3T
1327 template <typename T>
1329 
1330 // Relocation traits for UT_Vector3T are defined in UT_VectorTypes.h
1331 
1332 #endif
UT_Vector3T< T > rowVecMult(const UT_Vector3T< T > &v, const UT_Matrix3T< S > &m)
Definition: UT_Matrix3.h:1516
UT_Vector3T< T > SYSlerp(const UT_Vector3T< T > &v1, const UT_Vector3T< T > &v2, S t)
Componentwise linear interpolation.
Definition: UT_Vector3.h:1023
constexpr SYS_FORCE_INLINE T length2() const noexcept
Definition: UT_Vector3.h:356
constexpr SYS_FORCE_INLINE T operator()(unsigned i) const noexcept
Definition: UT_Vector3.h:681
UT_API double intersectLines(const UT_Vector3T< T > &p1, const UT_Vector3T< T > &v1, const UT_Vector3T< T > &p2, const UT_Vector3T< T > &v2, T &t1, T &t2)
Mat3< typename promote< S, T >::type > operator*(S scalar, const Mat3< T > &m)
Multiply each element of the given matrix by scalar and return the result.
Definition: Mat3.h:561
constexpr UT_Vector3T< T > cross(const UT_Vector3T< T > &a, const UT_Vector3T< T > &b) noexcept
The dot and cross products between two vectors (see operator*() too)
Definition: UT_Vector3.h:967
constexpr SYS_FORCE_INLINE UT_Vector3T(const int32 v[tuple_size]) noexcept
Definition: UT_Vector3.h:255
constexpr SYS_FORCE_INLINE T dot(const UT_Vector3T &b) const noexcept
Definition: UT_Vector3.h:529
typename UT_StorageNum< T >::MathFloat UT_StorageMathFloat_t
Definition: UT_Storage.h:176
constexpr SYS_FORCE_INLINE UT_Vector3T(const fpreal32 v[tuple_size]) noexcept
Definition: UT_Vector3.h:249
#define SYS_STATIC_ASSERT(expr)
int findMaxAbsAxis() const
These allow you to find out what indices to use for different axes.
Definition: UT_Vector3.h:562
friend constexpr bool isZero(const UT_Vector3T &a) noexcept
Definition: UT_Vector3.h:778
UT_Vector3T< T > SYSrecip(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:1083
int int32
Definition: SYS_Types.h:39
constexpr SYS_FORCE_INLINE UT_Vector3T< T > operator()(const TS &as) const noexcept
Definition: UT_Vector3.h:1300
UT_FromUnbounded creates a V from an unbounded array-like type.
Definition: UT_Vector2.h:795
UT_Vector3T< T > SYSbilerp(const UT_Vector3T< T > &u0v0, const UT_Vector3T< T > &u1v0, const UT_Vector3T< T > &u0v1, const UT_Vector3T< T > &u1v1, S u, S v)
Bilinear interpolation.
Definition: UT_Vector3.h:112
T distance2(const UT_Vector3T< T > &p1, const UT_Vector3T< T > &p2)
Compute the distance squared.
Definition: UT_Vector3.h:1122
T distance3d(const UT_Vector3T< T > &p1, const UT_Vector3T< T > &p2)
Compute the distance between two points.
Definition: UT_Vector3.h:1116
constexpr SYS_FORCE_INLINE T y() const noexcept
Definition: UT_Vector3.h:666
GLboolean * data
Definition: glcorearb.h:131
int UTinverseTrilerpFlat(const UT_Vector3T< T > &input, const UT_Vector3T< T > &p0, const UT_Vector3T< T > &du, const UT_Vector3T< T > &dv, const UT_Vector3T< T > &dw, UT_Vector3T< T > &output)
Definition: UT_Vector3.h:1215
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector4.h:493
UT_Vector3T< T > SYSabs(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:987
const GLdouble * v
Definition: glcorearb.h:837
constexpr SYS_FORCE_INLINE UT_Vector3T(const int64 v[tuple_size]) noexcept
Definition: UT_Vector3.h:258
Transformation order of scales, rotates, and translates.
Definition: UT_XformOrder.h:23
void assign(const T *v)
Set the values of the vector components.
Definition: UT_Vector3.h:699
Mat3< typename promote< T0, T1 >::type > operator+(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Add corresponding elements of m0 and m1 and return the result.
Definition: Mat3.h:577
T vec[tuple_size]
Definition: UT_Vector3.h:774
#define SYS_DEPRECATED_HDK_REPLACE(__V__, __R__)
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
friend constexpr auto length2(const UT_Vector3T &a) noexcept
Definition: UT_Vector3.h:783
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
typename SYS_FixedArrayElement< T >::type SYS_FixedArrayElement_t
fpreal64 UTangleBetween(const UT_Vector3T< T > &v1, const UT_Vector3T< T > &v2)
The angle between two vectors in radians.
Definition: UT_Vector3.h:978
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector3.h:667
int64 exint
Definition: SYS_Types.h:125
UT_Vector3T< T > SYSmin(const UT_Vector3T< T > &v1, const UT_Vector3T< T > &v2)
Componentwise min and maximum.
Definition: UT_Vector3.h:994
constexpr bool SYSisNan(const F f)
Definition: SYS_Math.h:184
T segmentDistance(const UT_Vector3T< T > &p0, const UT_Vector3T< T > &p1, const UT_Vector3T< T > &a, const UT_Vector3T< T > &b)
Returns the distance between two line segments: p0-p1 and a-b.
Definition: UT_Vector3.h:1202
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
constexpr SYS_FORCE_INLINE UT_Vector3T & operator-=(const T &a) noexcept
Definition: UT_Vector3.h:320
unsigned hash() const
Compute a hash.
Definition: UT_Vector3.h:689
constexpr SYS_FORCE_INLINE T b() const noexcept
Definition: UT_Vector3.h:674
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:87
#define UT_API
Definition: UT_API.h:14
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
constexpr SYS_FORCE_INLINE UT_Vector3T< T > operator()(const TS &as) const noexcept
Definition: UT_Vector3.h:1276
GLint y
Definition: glcorearb.h:103
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
constexpr SYS_FORCE_INLINE T length() const noexcept
Definition: UT_Vector3.h:361
static const exint TupleSize
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:818
constexpr auto dot(const UT_Vector3T< T > &a, const UT_Vector3T< T > &b) noexcept
The dot and cross products between two vectors (see operator*() too)
Definition: UT_Vector3.h:960
UT_Vector3T< T > SYStrihatgrad(const UT_Vector3T< T > &v, const UT_Vector3T< T > &s)
Gradient of trilinear hat function over kernel widths in s.
Definition: UT_Vector3.h:1097
T SYStrihat(const UT_Vector3T< T > &v, const UT_Vector3T< T > &s)
Trilinear hat function over kernel widths in s.
Definition: UT_Vector3.h:1090
3D Vector class.
4D Vector class.
Definition: UT_Vector4.h:174
constexpr SYS_FORCE_INLINE UT_Vector3T & operator*=(const T &a) noexcept
Definition: UT_Vector3.h:326
2D Vector class.
Definition: UT_Vector2.h:159
float fpreal32
Definition: SYS_Types.h:200
constexpr SYS_FORCE_INLINE UT_Vector3T(const T v) noexcept
Definition: UT_Vector3.h:242
constexpr SYS_FORCE_INLINE T & operator()(unsigned i) noexcept
Definition: UT_Vector3.h:676
constexpr SYS_FORCE_INLINE const T * data() const noexcept
Definition: UT_Vector3.h:292
constexpr SYS_FORCE_INLINE UT_Vector3T(const fpreal16 v[tuple_size]) noexcept
Definition: UT_Vector3.h:246
friend constexpr bool operator>(const UT_Vector3T &a, const UT_Vector3T &b) noexcept
Definition: UT_Vector3.h:815
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector4.h:491
constexpr SYS_FORCE_INLINE T avgComponent() const noexcept
Definition: UT_Vector3.h:418
T segmentPointDist2(const UT_Vector3T< T > &pos, const UT_Vector3T< T > &pt1, const UT_Vector3T< T > &pt2)
Definition: UT_Vector3.h:1130
double fpreal64
Definition: SYS_Types.h:201
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector2.h:423
constexpr SYS_FORCE_INLINE T minComponent() const noexcept
Definition: UT_Vector3.h:413
void getFrameOfReference(UT_Vector3T< T > &X, UT_Vector3T< T > &Y) const
Definition: UT_Vector3.h:575
constexpr SYS_FORCE_INLINE void cross(const UT_Vector3T< T > &v) noexcept
Definition: UT_Vector3.h:534
GLfloat f
Definition: glcorearb.h:1926
constexpr SYS_FORCE_INLINE T & operator[](exint i) noexcept
Definition: UT_Vector3.h:285
Definition: core.h:760
constexpr SYS_FORCE_INLINE UT_Vector3T(const UT_Vector3T< S > &v) noexcept
Our own type of any given value_type.
Definition: UT_Vector3.h:267
constexpr UT_Vector3T< T > operator/(const UT_Vector3T< T > &v, S scalar) noexcept
Definition: UT_Vector3.h:939
Mat3< typename promote< T0, T1 >::type > operator-(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Subtract corresponding elements of m0 and m1 and return the result.
Definition: Mat3.h:587
UT_API UT_Vector2T< T > segmentClosest(const UT_Vector3T< T > &p0, const UT_Vector3T< T > &p1, const UT_Vector3T< T > &a, const UT_Vector3T< T > &b)
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector4.h:495
void clampZero(T tol=T(0.00001f))
Definition: UT_Vector3.h:436
typename UT_StorageAtLeast32Bit< T0, T1 >::type UT_StorageAtLeast32Bit_t
Definition: UT_Storage.h:265
constexpr SYS_FORCE_INLINE void negate() noexcept
Definition: UT_Vector3.h:351
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
constexpr SYS_FORCE_INLINE const T & operator[](exint i) const noexcept
Definition: UT_Vector3.h:278
friend constexpr bool operator<(const UT_Vector3T &a, const UT_Vector3T &b) noexcept
Definition: UT_Vector3.h:805
constexpr SYS_FORCE_INLINE UT_Vector3T & operator-=(const UT_Vector3T &a) noexcept
Definition: UT_Vector3.h:308
size_t hash_value(const UT_Vector3T< T > &val)
Definition: UT_Vector3.h:1236
constexpr SYS_FORCE_INLINE T x() const noexcept
Definition: UT_Vector3.h:664
static const bool isVectorType
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
UT_Vector3T< T > SYSclamp(const UT_Vector3T< T > &v, const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
Definition: UT_Vector3.h:1057
static int entries()
Returns the vector size.
Definition: UT_Vector3.h:772
constexpr SYS_FORCE_INLINE UT_Vector3T & operator+=(const T &a) noexcept
Definition: UT_Vector3.h:314
constexpr SYS_FORCE_INLINE UT_Vector3T(const T vx, const T vy, const T vz) noexcept
Definition: UT_Vector3.h:238
UT_Vector3T< T > SYSmax(const UT_Vector3T< T > &v1, const UT_Vector3T< T > &v2)
Definition: UT_Vector3.h:1005
constexpr SYS_FORCE_INLINE T & r() noexcept
Definition: UT_Vector3.h:669
UT_Vector3T< T > SYSbarycentric(const UT_Vector3T< T > &v0, const UT_Vector3T< T > &v1, const UT_Vector3T< T > &v2, S u, S v)
Barycentric interpolation.
Definition: UT_Vector3.h:119
class UT_API UT_Vector3T
long long int64
Definition: SYS_Types.h:116
UT_API UT_Vector2T< T > segmentClosestParallel(const UT_Vector3T< T > &p0, const UT_Vector3T< T > &p1, const UT_Vector3T< T > &a, const UT_Vector3T< T > &b)
friend constexpr bool operator==(const UT_Vector3T &a, const UT_Vector3T &b) noexcept
Definition: UT_Vector3.h:793
T segmentDistance2(const UT_Vector3T< T > &p0, const UT_Vector3T< T > &p1, const UT_Vector3T< T > &a, const UT_Vector3T< T > &b)
Returns the squared distance between two line segments: p0-p1 and a-b.
Definition: UT_Vector3.h:1191
T rayPointDist2(const UT_Vector3T< T > &pos, const UT_Vector3T< T > &orig, const UT_Vector3T< T > &dir)
Definition: UT_Vector3.h:1163
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
constexpr SYS_FORCE_INLINE T & g() noexcept
Definition: UT_Vector3.h:671
UT_Vector3T< T > colVecMult3(const UT_Matrix4T< S > &m, const UT_Vector3T< T > &v)
Definition: UT_Matrix4.h:1948
GLint GLenum GLint x
Definition: glcorearb.h:409
constexpr SYS_FORCE_INLINE UT_Vector3T & operator*=(const UT_Vector3T &a) noexcept
Definition: UT_Vector3.h:339
constexpr SYS_FORCE_INLINE UT_Vector3T(const fpreal64 v[tuple_size]) noexcept
Definition: UT_Vector3.h:252
IMATH_HOSTDEVICE const Vec2< S > & operator*=(Vec2< S > &v, const Matrix22< T > &m) IMATH_NOEXCEPT
Vector-matrix multiplication: v *= m.
Definition: ImathMatrix.h:4660
constexpr SYS_FORCE_INLINE UT_Vector3T & operator/=(const UT_Vector3T &a) noexcept
Definition: UT_Vector3.h:345
constexpr SYS_FORCE_INLINE bool isNan() const noexcept
Definition: UT_Vector3.h:383
GLdouble t
Definition: glad.h:2397
int solve(T cx, T cy, T cz, UT_Vector3T< S > &result) const
GLfloat v0
Definition: glcorearb.h:816
constexpr SYS_FORCE_INLINE T g() const noexcept
Definition: UT_Vector3.h:672
void dehomogenize()
Express the point in homogeneous coordinates or vice-versa.
Definition: UT_Vector3.h:711
bool SYSisFinite(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:1076
bool SYSequalZero(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:1069
void assign(T xx=0.0f, T yy=0.0f, T zz=0.0f)
Set the values of the vector components.
Definition: UT_Vector3.h:694
SYS_FORCE_INLINE UT_Vector3T< T > & operator=(const UT_Vector3T< S > &v)
Definition: UT_Vector3.h:275
void homogenize()
Express the point in homogeneous coordinates or vice-versa.
Definition: UT_Vector3.h:706
UT_Vector3T< T > SYSinvlerp(const UT_Vector3T< T > &a, const UT_Vector3T< T > &v1, const UT_Vector3T< T > &v2)
Componentwise inverse linear interpolation.
Definition: UT_Vector3.h:1045
constexpr SYS_FORCE_INLINE T r() const noexcept
Definition: UT_Vector3.h:670
friend constexpr auto distance2(const UT_Vector3T &a, const UT_Vector3T &b) noexcept
Compute the distance squared.
Definition: UT_Vector3.h:788
bool SYSisInteger(const UT_Vector3T< T > &v1)
Componentwise integer test.
Definition: UT_Vector3.h:99
UT_API bool intersectSegments(const UT_Vector3T< T > &p0, const UT_Vector3T< T > &p1, const UT_Vector3T< T > &a, const UT_Vector3T< T > &b, T &t)
constexpr SYS_FORCE_INLINE UT_Vector3T< T > operator-() const noexcept
Definition: UT_Vector3.h:431
constexpr SYS_FORCE_INLINE T distance2(const UT_Vector3T &b) const noexcept
Definition: UT_Vector3.h:366
UT_Vector3T< T > rowVecMult3(const UT_Vector3T< T > &v, const UT_Matrix4T< S > &m)
Definition: UT_Matrix4.h:1926
constexpr UT_Vector3T< SYS_FixedArrayElement_t< TS > > UTmakeVector3T(const TS &as) noexcept
Definition: UT_Vector3.h:1313
constexpr SYS_FORCE_INLINE T & b() noexcept
Definition: UT_Vector3.h:673
fpreal64 fpreal
Definition: SYS_Types.h:277
constexpr SYS_FORCE_INLINE UT_Vector3T & operator+=(const UT_Vector3T &a) noexcept
Definition: UT_Vector3.h:302
UT_FixedVector< T, 3 > FixedVectorType
Definition: UT_Vector3.h:1251
LeafData & operator=(const LeafData &)=delete
constexpr SYS_FORCE_INLINE UT_Vector3T< T > & operator=(const UT_Vector3T< T > &that)=default
constexpr SYS_FORCE_INLINE bool isEqual(const UT_Vector3T &b, const T tolerance=SYS_FTOLERANCE) const noexcept
Definition: UT_Vector3.h:403
constexpr SYS_FORCE_INLINE bool isZero() const noexcept
Definition: UT_Vector3.h:393
bool SYSisEqual(const UT_Vector3T< T > &a, const UT_Vector3T< T > &b, S tol=SYS_FTOLERANCE)
Componentwise equality.
Definition: UT_Vector3.h:1016
UT_Vector3T< T > colVecMult(const UT_Matrix3T< S > &m, const UT_Vector3T< T > &v)
Definition: UT_Matrix3.h:1534
GLfloat GLfloat v1
Definition: glcorearb.h:817
GLuint GLfloat * val
Definition: glcorearb.h:1608
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
constexpr SYS_FORCE_INLINE bool isFinite() const noexcept
Definition: UT_Vector3.h:388
constexpr SYS_FORCE_INLINE T distance(const UT_Vector3T &b) const noexcept
Definition: UT_Vector3.h:371
#define SYS_FTOLERANCE
Definition: SYS_Types.h:208
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
constexpr SYS_FORCE_INLINE UT_Vector3T & operator/=(const T &a) noexcept
Definition: UT_Vector3.h:332
SYS_FORCE_INLINE UT_StorageMathFloat_t< T > normalize() noexcept
Definition: UT_Vector3.h:376
SYS_FORCE_INLINE UT_Vector3T()=default
friend constexpr bool operator<=(const UT_Vector3T &a, const UT_Vector3T &b) noexcept
Definition: UT_Vector3.h:810
friend constexpr bool operator>=(const UT_Vector3T &a, const UT_Vector3T &b) noexcept
Definition: UT_Vector3.h:820
UT_Vector3T< T > project(const UT_Vector3T< T > &u, const UT_Vector3T< T > &v)
The orthogonal projection of a vector u onto a vector v.
Definition: UT_Vector3.h:1109
constexpr SYS_FORCE_INLINE T z() const noexcept
Definition: UT_Vector3.h:668
SIM_API const UT_StringHolder distance
SYS_FORCE_INLINE void normal(const UT_Vector3T< T > &va, const UT_Vector3T< T > &vb)
Definition: UT_Vector3.h:539
constexpr SYS_FORCE_INLINE T * data() noexcept
Definition: UT_Vector3.h:297
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:665
SYS_FORCE_INLINE void multiplyComponents(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:444
constexpr SYS_FORCE_INLINE T maxComponent() const noexcept
Definition: UT_Vector3.h:408
constexpr SYS_FORCE_INLINE bool equalZero(const T tolerance=SYS_FTOLERANCE) const noexcept
Definition: UT_Vector3.h:398
friend constexpr bool operator!=(const UT_Vector3T &a, const UT_Vector3T &b) noexcept
Definition: UT_Vector3.h:798
uint64_t multiply(uint64_t lhs, uint64_t rhs)
Definition: format-inl.h:258
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector2.h:425
UT_API size_t format(char *buffer, size_t buffer_size, const UT_Vector3T< T > &v)
fpreal64 angleTo(const UT_Vector3T< T > &v) const
Definition: UT_Vector3.h:765
int findMinAbsAxis() const
These allow you to find out what indices to use for different axes.
Definition: UT_Vector3.h:554
T linePointDist2(const UT_Vector3T< T > &pos, const UT_Vector3T< T > &orig, const UT_Vector3T< T > &dir)
Definition: UT_Vector3.h:1176
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:663