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