HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_Vector4.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 4.
10  *
11  * WARNING:
12  * This class should NOT contain any virtual methods, nor should it
13  * define more member data. The size of UT_Vector4 must always be
14  * 16 bytes (4 floats).
15  *
16  */
17 
18 #pragma once
19 
20 #ifndef __UT_Vector4_h__
21 #define __UT_Vector4_h__
22 
23 #include "UT_API.h"
24 #include "UT_Assert.h"
25 #include "UT_FixedVector.h"
26 #include "UT_VectorTypes.h"
27 #include <SYS/SYS_Deprecated.h>
28 #include <SYS/SYS_Inline.h>
29 #include <SYS/SYS_Math.h>
30 #include <iosfwd>
31 #include <limits>
32 
33 #ifndef UT_DISABLE_VECTORIZE_MATRIX
34 #include <VM/VM_SIMD.h>
35 #endif
36 
37 class UT_IStream;
38 class UT_JSONWriter;
39 class UT_JSONValue;
40 class UT_JSONParser;
41 
42 // Free floating functions:
43 
44 // Right-multiply operators (M*v) have been removed. They had previously
45 // been defined to return v*M, which was too counterintuitive. Once HDK
46 // etc. users have a chance to update their code (post 7.0) we could
47 // reintroduce a right-multiply operator that does a colVecMult.
48 
49 template <typename T, typename S>
51 template <typename T>
53 template <typename T>
55 template <typename T, typename S>
56 inline UT_Vector4T<T> operator+(const UT_Vector4T<T> &v, S scalar);
57 template <typename T, typename S>
58 inline UT_Vector4T<T> operator-(const UT_Vector4T<T> &v, S scalar);
59 template <typename T, typename S>
60 inline UT_Vector4T<T> operator*(const UT_Vector4T<T> &v, S scalar);
61 template <typename T, typename S>
62 inline UT_Vector4T<T> operator/(const UT_Vector4T<T> &v, S scalar);
63 template <typename T, typename S>
64 inline UT_Vector4T<T> operator+(S scalar, const UT_Vector4T<T> &v);
65 template <typename T, typename S>
66 inline UT_Vector4T<T> operator-(S scalar, const UT_Vector4T<T> &v);
67 template <typename T, typename S>
68 inline UT_Vector4T<T> operator*(S scalar, const UT_Vector4T<T> &v);
69 template <typename T, typename S>
70 inline UT_Vector4T<T> operator/(S scalar, const UT_Vector4T<T> &v);
71 
72 /// Although the cross product is undefined for 4D vectors, we believe it's
73 /// useful in practice to define a function that takes two 4D vectors and
74 /// computes the cross-product of their first 3 components
75 template <typename T>
77 template <typename T>
79 template <typename T>
81 
82 /// The dot product between two vectors
83 // @{
84 template <typename T>
85 inline T dot(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2);
86 template <typename T>
87 inline T dot(const UT_Vector4T<T> &v1, const UT_Vector3T<T> &v2);
88 template <typename T>
89 inline T dot(const UT_Vector3T<T> &v1, const UT_Vector4T<T> &v2);
90 // @}
91 
92 /// Componentwise min and maximum
93 template <typename T>
94 inline UT_Vector4T<T> SYSmin (const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2);
95 template <typename T>
96 inline UT_Vector4T<T> SYSmax (const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2);
97 
98 /// Componentwise linear interpolation
99 template <typename T,typename S>
100 inline UT_Vector4T<T> SYSlerp(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2, S t);
101 
102 template <typename T>
104 
105 /// Bilinear interpolation
106 template <typename T,typename S>
107 inline UT_Vector4T<T> SYSbilerp(const UT_Vector4T<T> &u0v0, const UT_Vector4T<T> &u1v0,
108  const UT_Vector4T<T> &u0v1, const UT_Vector4T<T> &u1v1,
109  S u, S v)
110 { return SYSlerp(SYSlerp(u0v0, u0v1, v), SYSlerp(u1v0, u1v1, v), u); }
111 
112 /// Barycentric interpolation
113 template <typename T, typename S>
115  const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2, S u, S v)
116 { return v0 * (1 - u - v) + v1 * u + v2 *v; }
117 
118 
119 /// Multiplication of a row or column vector by a matrix (ie. right vs. left
120 /// multiplication respectively). The operator*() declared above is an alias
121 /// for rowVecMult().
122 // @{
123 //
124 // Notes on optimisation of matrix/vector multiplies:
125 // - multiply(dest, mat) functions have been deprecated in favour of
126 // rowVecMult/colVecMult routines, which produce temporaries. For these to
127 // offer comparable performance, the compiler has to optimize away the
128 // temporary, but most modern compilers can do this. Performance tests with
129 // gcc3.3 indicate that this is a realistic expectation for modern
130 // compilers.
131 // - since matrix/vector multiplies cannot be done without temporary data,
132 // the "primary" functions are the global matrix/vector
133 // rowVecMult/colVecMult routines, rather than the member functions.
134 // - inlining is explicitly requested only for functions involving the
135 // native types (UT_Vector4 and UT_Matrix4)
136 template <typename T, typename S>
138 template <typename T, typename S>
140 
141 template <typename T, typename S>
143 template <typename T, typename S>
145 // @}
146 
147 /// Compute the distance between two points
148 // @{
149 template <typename T>
150 inline T distance4(const UT_Vector4T<T> &p1, const UT_Vector4T<T> &p2);
151 template <typename T>
152 inline T distance3(const UT_Vector4T<T> &p1, const UT_Vector4T<T> &p2);
153 template <typename T>
154 inline T distance3d(const UT_Vector4T<T> &p1, const UT_Vector4T<T> &p2)
155 { return distance3(p1, p2); }
156 template <typename T>
157 inline T distance3d(const UT_Vector3T<T> &p1, const UT_Vector4T<T> &p2)
158 { return distance3d(p1, UT_Vector3T<T>(p2)); }
159 template <typename T>
160 inline T distance3d(const UT_Vector4T<T> &p1, const UT_Vector3T<T> &p2)
161 { return distance3d(UT_Vector3T<T>(p1), p2); }
162 // @}
163 
164 /// 4D Vector class.
165 template <typename T>
166 class UT_API UT_Vector4T : public UT_FixedVector<T,4,true>
167 {
168 public:
170 
171  // These "using" statements are needed for operator= and operator*=
172  // so that the ones in UT_FixedVector aren't hidden by the additional
173  // ones here.
174  using Base::operator=;
175  using Base::operator*=;
176 
177  // These "using" statements are needed for GCC and Clang, because
178  // otherwise, they ignore all members of UT_FixedVector when
179  // checking validity of code in functions in this class.
180 private:
181  using Base::vec;
182 public:
183  using Base::data;
184  typedef T value_type;
185  static const int tuple_size = 4;
186 
187  /// Default constructor.
188  /// No data is initialized! Use it for extra speed.
189  SYS_FORCE_INLINE UT_Vector4T() = default;
190 
191  SYS_FORCE_INLINE UT_Vector4T(const UT_Vector4T<T> &that) = default;
192  SYS_FORCE_INLINE UT_Vector4T(UT_Vector4T<T> &&that) = default;
193 
194  SYS_FORCE_INLINE UT_Vector4T(T vx, T vy, T vz, T vw = 1.0f)
195  {
196  vec[0] = vx;
197  vec[1] = vy;
198  vec[2] = vz;
199  vec[3] = vw;
200  }
202  : Base(v)
203  {}
205  : Base(v)
206  {}
207  SYS_FORCE_INLINE UT_Vector4T(const int32 v[tuple_size])
208  : Base(v)
209  {}
210  SYS_FORCE_INLINE UT_Vector4T(const int64 v[tuple_size])
211  : Base(v)
212  {}
213 
214  // Initialises the vector as [x,y,0,1]
216  explicit UT_Vector4T(const UT_Vector2T<T> &v);
218  explicit UT_Vector4T(const UT_Vector3T<T> &v, T w = 1.f);
219 
220  /// Our own type of any given value_type.
221  template <typename S>
223  : Base(v)
224  {}
225 
226  /// Arbitrary UT_FixedVector of the same size
227  template <typename S,bool S_INSTANTIATED>
229  : Base(v)
230  {}
231 
234 
235  template <typename S>
237  { vec[0] = v[0]; vec[1] = v[1]; vec[2] = v[2]; vec[3] = v[3];
238  return *this; }
239 
240 
241  // TODO: We could remove this. It's not as error-prone as some other
242  // conversions, but it might still be better to force the user to do
243  // an explicit cast i.e., v4 = UT_Vector4(v3)
244 
245  /// Assignment operator that creates a V4 from a V3 by adding a '1'
246  /// element.
247  SYS_DEPRECATED_HDK_REPLACE(16.0,explicit UT_Vector4 constructor to avoid implicit conversion from UT_Vector3)
249 
250  int equalZero3(T tol = 0.00001f) const
251  {
252  return (vec[0] >= -tol && vec[0] <= tol) &&
253  (vec[1] >= -tol && vec[1] <= tol) &&
254  (vec[2] >= -tol && vec[2] <= tol);
255  }
256 
257  void clampZero(T tol = 0.00001f)
258  {
259  if (vec[0] >= -tol && vec[0] <= tol) vec[0] = 0;
260  if (vec[1] >= -tol && vec[1] <= tol) vec[1] = 0;
261  if (vec[2] >= -tol && vec[2] <= tol) vec[2] = 0;
262  if (vec[3] >= -tol && vec[3] <= tol) vec[3] = 0;
263  }
264 
265  void clampZero3(T tol = 0.00001f)
266  {
267  if (vec[0] >= -tol && vec[0] <= tol) vec[0] = 0;
268  if (vec[1] >= -tol && vec[1] <= tol) vec[1] = 0;
269  if (vec[2] >= -tol && vec[2] <= tol) vec[2] = 0;
270  }
271 
272  void negate3()
273  { vec[0]= -vec[0]; vec[1]= -vec[1]; vec[2]= -vec[2]; }
274 
276  {
277  vec[0] *= v.vec[0];
278  vec[1] *= v.vec[1];
279  vec[2] *= v.vec[2];
280  vec[3] *= v.vec[3];
281  }
282 
283  using Base::isEqual;
284 
285  SYS_DEPRECATED_HDK_REPLACE(16.0,explicit conversion to UT_Vector3 followed by isEqual)
286  inline int isEqual(const UT_Vector3T<T> &vect, T tol = 0.00001f) const;
287 
288  /// If you need a multiplication operator that left multiplies the vector
289  /// by a matrix (M * v), use the following colVecMult() functions. If
290  /// you'd rather not use operator*=() for right-multiplications (v * M),
291  /// use the following rowVecMult() functions.
292  // @{
293  template <typename S>
294  inline void rowVecMult(const UT_Matrix4T<S> &m)
295  { operator=(::rowVecMult(*this, m)); }
296  template <typename S>
297  inline void colVecMult(const UT_Matrix4T<S> &m)
298  { operator=(::colVecMult(m, *this)); }
299  // @}
300 
301  /// This multiply will ignore the 4th component both in the vector an in
302  /// the matrix. This helps when you want to avoid affecting the 'w'
303  /// component. This in turns annihilates the translation components (row 4)
304  /// in mat, so be careful.
305  // @{
306  template <typename S>
308  { operator=(::rowVecMult3(*this, m)); }
309  // @}
310 
311  // The *= and multiply3 routines are provided for
312  // legacy reasons. They all assume that *this is a row vector. Generally,
313  // the rowVecMult and colVecMult methods are preferred, since they're
314  // more explicit about the row vector assumption.
315  // @{
316  template <typename S>
317  inline
319  { rowVecMult(mat); return *this; }
320 
321  template <typename S>
322  inline void multiply3(const UT_Matrix4T<S> &mat)
323  { rowVecMult3(mat); }
324  template <typename S>
325  inline void multiply3(UT_Vector4T<T> &dest, const UT_Matrix4T<S> &mat) const
326  { dest = ::rowVecMult3(*this, mat); }
327  // @}
328 
329  /// These allow you to find out what indices to use for different axes
330  // @{
331  int findMinAbsAxis() const
332  {
333  if (SYSabs(x()) < SYSabs(y()))
334  if (SYSabs(z()) < SYSabs(x()))
335  if (SYSabs(w()) < SYSabs(z()))
336  return 3;
337  else
338  return 2;
339  else
340  if (SYSabs(w()) < SYSabs(x()))
341  return 3;
342  else
343  return 0;
344  else
345  if (SYSabs(z()) < SYSabs(y()))
346  if (SYSabs(w()) < SYSabs(z()))
347  return 3;
348  else
349  return 2;
350  else
351  if (SYSabs(w()) < SYSabs(y()))
352  return 3;
353  else
354  return 1;
355  }
356  int findMaxAbsAxis() const
357  {
358  if (SYSabs(x()) >= SYSabs(y()))
359  if (SYSabs(z()) >= SYSabs(x()))
360  if (SYSabs(w()) >= SYSabs(z()))
361  return 3;
362  else
363  return 2;
364  else
365  if (SYSabs(w()) >= SYSabs(x()))
366  return 3;
367  else
368  return 0;
369  else
370  if (SYSabs(z()) >= SYSabs(y()))
371  if (SYSabs(w()) >= SYSabs(z()))
372  return 3;
373  else
374  return 2;
375  else
376  if (SYSabs(w()) >= SYSabs(y()))
377  return 3;
378  else
379  return 1;
380  }
381  // @}
382 
383  /// Return the components of the vector. The () operator does NOT check
384  /// for the boundary condition.
385  // @{
386  inline T &x() { return vec[0]; }
387  inline T x() const { return vec[0]; }
388  inline T &y() { return vec[1]; }
389  inline T y() const { return vec[1]; }
390  inline T &z() { return vec[2]; }
391  inline T z() const { return vec[2]; }
392  inline T &w() { return vec[3]; }
393  inline T w() const { return vec[3]; }
394  inline T &operator()(unsigned i)
395  {
396  UT_ASSERT_P(i < tuple_size);
397  return vec[i];
398  }
399  inline T operator()(unsigned i) const
400  {
401  UT_ASSERT_P(i < tuple_size);
402  return vec[i];
403  }
404  // @}
405 
406  /// Compute a hash
407  unsigned hash() const { return SYSvector_hash(data(), tuple_size); }
408 
409  // TODO: eliminate these methods. They're redundant, given good inline
410  // constructors.
411  /// Set the values of the vector components
412  void assign(T xx = 0.0f, T yy = 0.0f, T zz = 0.0f,
413  T ww = 1.0f)
414  {
415  vec[0] = xx; vec[1] = yy; vec[2] = zz; vec[3] = ww;
416  }
417  /// Set the values of the vector components
418  void assign(const T *v, int size = tuple_size)
419  {
420  vec[0] = v[0];
421  vec[1] = v[1];
422  vec[2] = v[2];
423  if (size == tuple_size) vec[3] = v[3];
424  }
425 
426  /// Express the point in homogeneous coordinates or vice-versa
427  // @{
428  void homogenize()
429  {
430  vec[0] *= vec[3];
431  vec[1] *= vec[3];
432  vec[2] *= vec[3];
433  }
435  {
436  if (vec[3] != 0)
437  {
438  T denom = 1.0f / vec[3];
439  vec[0] *= denom;
440  vec[1] *= denom;
441  vec[2] *= denom;
442  }
443  }
444  // @}
445 
446  void save(std::ostream &os, int binary=0) const;
447  bool load(UT_IStream &is);
448 
449  /// @{
450  /// Methods to serialize to a JSON stream. The vector is stored as an
451  /// array of 4 reals.
452  bool save(UT_JSONWriter &w) const;
453  bool save(UT_JSONValue &v) const;
454  bool load(UT_JSONParser &p);
455  /// @}
456 
457  /// Returns the vector size
458  static int entries() { return tuple_size; }
459 
460 private:
461  /// I/O friends
462  // @{
463  friend std::ostream &operator<<(std::ostream &os, const UT_Vector4T<T> &v)
464  {
465  v.save(os);
466  return os;
467  }
468  // @}
469 
470  /// The negate operator is not provided, because of potentially
471  /// unintuitive behaviour: you very rarely actually want to negate the
472  /// w component.
473  UT_Vector4T<T> operator-() const
474  {
475  UT_ASSERT(0);
476  UT_Vector4T a(*this);
477  a.negate();
478  return a;
479  }
480 };
481 
482 #include "UT_Vector2.h"
483 #include "UT_Vector3.h"
484 
485 template <typename T>
487 {
488  vec[0] = v.x();
489  vec[1] = v.y();
490  vec[2] = T(0);
491  vec[3] = T(1);
492 }
493 template <typename T>
495 {
496  vec[0] = v.x();
497  vec[1] = v.y();
498  vec[2] = v.z();
499  vec[3] = vw;
500 }
501 
502 #ifndef UT_DISABLE_VECTORIZE_MATRIX
503 template <> inline void
505 {
506  v4uf l(this->data());
507  const v4uf r(v.data());
508  l *= r;
509 
510  vm_store(this->data(), l.vector);
511 }
512 #endif
513 
514 template <typename T>
515 inline int
516 UT_Vector4T<T>::isEqual(const UT_Vector3T<T> &vect, T tol) const
517 {
518  return ((vec[0]>=vect.x()-tol) && (vec[0]<=vect.x()+tol) &&
519  (vec[1]>=vect.y()-tol) && (vec[1]<=vect.y()+tol) &&
520  (vec[2]>=vect.z()-tol) && (vec[2]<=vect.z()+tol));
521 }
522 
523 // Free floating functions:
524 template <typename T>
526 {
527  return UT_Vector4T<T>(v1.x()+v2.x(), v1.y()+v2.y(),
528  v1.z()+v2.z(), v1.w()+v2.w());
529 }
530 template <typename T>
532 {
533  return UT_Vector3T<T>(v1.x()+v2.x(), v1.y()+v2.y(),
534  v1.z()+v2.z());
535 }
536 template <typename T>
538 {
539  return UT_Vector3T<T>(v1.x()+v2.x(), v1.y()+v2.y(),
540  v1.z()+v2.z());
541 }
542 template <typename T>
544 {
545  return UT_Vector4T<T>(v1.x()-v2.x(), v1.y()-v2.y(),
546  v1.z()-v2.z(), v1.w()-v2.w());
547 }
548 template <typename T>
550 {
551  return UT_Vector3T<T>(v1.x()-v2.x(), v1.y()-v2.y(),
552  v1.z()-v2.z());
553 }
554 template <typename T>
556 {
557  return UT_Vector3T<T>(v1.x()-v2.x(), v1.y()-v2.y(),
558  v1.z()-v2.z());
559 }
560 template <typename T>
562 {
563  return UT_Vector4T<T>(v1.x()*v2.x(), v1.y()*v2.y(), v1.z()*v2.z(), v1.w()*v2.w());
564 }
565 
566 template <typename T>
568 {
569  return UT_Vector4T<T>(v1.x()/v2.x(), v1.y()/v2.y(), v1.z()/v2.z(), v1.w()/v2.w());
570 }
571 #ifndef UT_DISABLE_VECTORIZE_MATRIX
572 template <>
574 {
575  const v4uf l(v1.data());
576  const v4uf r(v2.data());
577  const v4uf result = l * r;
578  return UT_Vector4T<float>((float*) &result);
579 }
580 template <>
582 {
583  const v4uf l(v1.data());
584  const v4uf r(v2.data());
585  const v4uf result = l / r;
586  return UT_Vector4T<float>((float*) &result);
587 }
588 #endif
589 
590 template <typename T, typename S>
591 inline UT_Vector4T<T> operator+(const UT_Vector4T<T> &v, S scalar)
592 {
593  return UT_Vector4T<T>(v.x()+scalar, v.y()+scalar, v.z()+scalar, v.w()+scalar);
594 }
595 template <typename T, typename S>
596 inline UT_Vector4T<T> operator+(S scalar, const UT_Vector4T<T> &v)
597 {
598  return UT_Vector4T<T>(v.x()+scalar, v.y()+scalar, v.z()+scalar, v.w()+scalar);
599 }
600 template <typename T, typename S>
601 inline UT_Vector4T<T> operator-(const UT_Vector4T<T> &v, S scalar)
602 {
603  return UT_Vector4T<T>(v.x()-scalar, v.y()-scalar, v.z()-scalar, v.w()-scalar);
604 }
605 template <typename T, typename S>
606 inline UT_Vector4T<T> operator-(S scalar, const UT_Vector4T<T> &v)
607 {
608  return UT_Vector4T<T>(scalar-v.x(), scalar-v.y(), scalar-v.z(), v.w()-scalar);
609 }
610 template <typename T, typename S>
611 inline UT_Vector4T<T> operator*(const UT_Vector4T<T> &v, S scalar)
612 {
613  return UT_Vector4T<T>(v.x()*scalar, v.y()*scalar, v.z()*scalar, v.w()*scalar);
614 }
615 template <typename T, typename S>
616 inline UT_Vector4T<T> operator*(S scalar, const UT_Vector4T<T> &v)
617 {
618  return UT_Vector4T<T>(v.x()*scalar, v.y()*scalar, v.z()*scalar, v.w()*scalar);
619 }
620 template <typename T, typename S>
621 inline UT_Vector4T<T> operator/(const UT_Vector4T<T> &v, S scalar)
622 {
623  // This has to be T because S may be int for "v = v/2" code
624  // For the same reason we must cast the 1
625  T inv = ((T)1) / scalar;
626  return UT_Vector4T<T>(v.x()*inv, v.y()*inv, v.z()*inv, v.w()*inv);
627 }
628 template <typename T, typename S>
629 inline UT_Vector4T<T> operator/(S scalar, const UT_Vector4T<T> &v)
630 {
631  return UT_Vector4T<T>(scalar/v.x(), scalar/v.y(), scalar/v.z(), scalar/v.w());
632 }
633 template <typename T>
634 inline T dot(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2)
635 {
636  return v1.x()*v2.x() + v1.y()*v2.y() + v1.z()*v2.z() + v1.w()*v2.w();
637 }
638 #ifndef UT_DISABLE_VECTORIZE_MATRIX
639 template <>
640 inline float dot(const UT_Vector4T<float> &v1, const UT_Vector4T<float> &v2)
641 {
642  return dot4(v4uf(v1.data()), v4uf(v2.data()));
643 }
644 #endif
645 
646 template <typename T>
647 inline T dot(const UT_Vector4T<T> &v1, const UT_Vector3T<T> &v2)
648 {
649  return v1.x()*v2.x() + v1.y()*v2.y() + v1.z()*v2.z();
650 }
651 template <typename T>
652 inline T dot(const UT_Vector3T<T> &v1, const UT_Vector4T<T> &v2)
653 {
654  return v1.x()*v2.x() + v1.y()*v2.y() + v1.z()*v2.z();
655 }
656 template <typename T>
657 inline
659 {
660  return UT_Vector4T<T>(
661  SYSabs(v.x()),
662  SYSabs(v.y()),
663  SYSabs(v.z()),
664  SYSabs(v.w())
665  );
666 }
667 
668 template <typename T>
669 inline
671 {
672  return UT_Vector4T<T>(
673  SYSmin(v1.x(), v2.x()),
674  SYSmin(v1.y(), v2.y()),
675  SYSmin(v1.z(), v2.z()),
676  SYSmin(v1.w(), v2.w())
677  );
678 }
679 
680 template <typename T>
681 inline
683 {
684  return UT_Vector4T<T>(
685  SYSmax(v1.x(), v2.x()),
686  SYSmax(v1.y(), v2.y()),
687  SYSmax(v1.z(), v2.z()),
688  SYSmax(v1.w(), v2.w())
689  );
690 }
691 
692 template <typename T,typename S>
693 inline
695 {
696  return UT_Vector4T<T>(
697  SYSlerp(v1.x(), v2.x(), t),
698  SYSlerp(v1.y(), v2.y(), t),
699  SYSlerp(v1.z(), v2.z(), t),
700  SYSlerp(v1.w(), v2.w(), t));
701 }
702 #ifndef UT_DISABLE_VECTORIZE_MATRIX
703 template <>
704 inline
706 {
707  const v4uf l(v1.data());
708  const v4uf r(v2.data());
709  const v4uf result = SYSlerp(l, r, t);
710  return UT_Vector4T<float>((float*) &result);
711 }
712 #endif
713 
714 template <typename T>
715 inline
717  const UT_Vector4T<T> &v1,
718  const UT_Vector4T<T> &v2)
719 {
720  return UT_Vector4T<T>(
721  SYSinvlerp(a.x(), v1.x(), v2.x()),
722  SYSinvlerp(a.y(), v1.y(), v2.y()),
723  SYSinvlerp(a.z(), v1.z(), v2.z()),
724  SYSinvlerp(a.w(), v1.w(), v2.w()));
725 }
726 
727 
728 template <typename T, typename S>
730 {
731  return rowVecMult(v, m);
732 }
733 template <typename T>
734 inline T distance(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2)
735 {
736  T x = v1.x()-v2.x();
737  T y = v1.y()-v2.y();
738  T z = v1.z()-v2.z();
739  T w = v1.w()-v2.w();
740  return SYSsqrt(x*x + y*y + z*z + w*w);
741 }
742 template <typename T>
744 {
745  T x = v1.x()-v2.x();
746  T y = v1.y()-v2.y();
747  T z = v1.z()-v2.z();
748  return SYSsqrt(x*x + y*y + z*z);
749 }
750 
751 #ifndef UT_DISABLE_VECTORIZE_MATRIX
752 template <>
753 inline float distance(const UT_Vector4T<float> &v1, const UT_Vector4T<float> &v2)
754 {
755  const v4uf l(v1.data());
756  const v4uf r(v2.data());
757  v4uf result = l - r;
758  result *= result;
759 
760  return SYSsqrt(result[0] + result[1] + result[2] + result[3]);
761 }
762 template <>
764 {
765  const v4uf l(v1.data());
766  const v4uf r(v2.data());
767  v4uf result = l - r;
768  result *= result;
769 
770  return SYSsqrt(result[0] + result[1] + result[2]);
771 }
772 #endif
773 
774 template <typename T>
775 inline size_t hash_value(const UT_Vector4T<T> &val)
776 {
777  return val.hash();
778 }
779 
780 // Overload for custom formatting of UT_Vector4T<T> with UTformat.
781 template<typename T>
782 UT_API size_t format(char *buffer, size_t buffer_size, const UT_Vector4T<T> &v);
783 
784 
785 template<typename T>
787 {
789  typedef T DataType;
790  static const exint TupleSize = 4;
791  static const bool isVectorType = true;
792 };
793 
794 #endif
SYS_FORCE_INLINE constexpr const T * data() const noexcept
SYS_FORCE_INLINE UT_FixedVector< T, SIZE > operator-() const
UT_API size_t format(char *buffer, size_t buffer_size, const UT_Vector4T< T > &v)
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:582
UT_Vector4T< T > operator/(const UT_Vector4T< T > &v, S scalar)
Definition: UT_Vector4.h:621
GLsizeiptr size
Definition: glew.h:1681
class UT_API UT_Vector4T
int int32
Definition: SYS_Types.h:39
UT_Vector4T< T > SYSlerp(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2, S t)
Componentwise linear interpolation.
Definition: UT_Vector4.h:694
UT_Vector4T< T > SYSmin(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Componentwise min and maximum.
Definition: UT_Vector4.h:670
unsigned hash() const
Compute a hash.
Definition: UT_Vector4.h:407
T operator()(unsigned i) const
Definition: UT_Vector4.h:399
SYS_FORCE_INLINE UT_Vector4T(const UT_FixedVector< S, tuple_size, S_INSTANTIATED > &v)
Arbitrary UT_FixedVector of the same size.
Definition: UT_Vector4.h:228
void multiplyComponents(const UT_Vector4T< T > &v)
Definition: UT_Vector4.h:275
SYS_FORCE_INLINE ThisType & operator=(const ThisType &that)=default
GLuint const GLfloat * val
Definition: glew.h:2794
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:598
void homogenize()
Express the point in homogeneous coordinates or vice-versa.
Definition: UT_Vector4.h:428
SYS_FORCE_INLINE UT_Vector4T(const UT_Vector4T< S > &v)
Our own type of any given value_type.
Definition: UT_Vector4.h:222
#define SYS_DEPRECATED_HDK_REPLACE(__V__, __R__)
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
void colVecMult(const UT_Matrix4T< S > &m)
Definition: UT_Vector4.h:297
int64 exint
Definition: SYS_Types.h:125
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:76
#define UT_API
Definition: UT_API.h:13
const GLdouble * m
Definition: glew.h:9124
GLdouble l
Definition: glew.h:9122
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:34
const GLdouble * v
Definition: glew.h:1391
int isEqual(const UT_Vector3T< T > &vect, T tol=0.00001f) const
Definition: UT_Vector4.h:516
static const exint TupleSize
size_t hash_value(const UT_Vector4T< T > &val)
Definition: UT_Vector4.h:775
3D Vector class.
4D Vector class.
Definition: UT_Vector4.h:166
2D Vector class.
Definition: UT_Vector2.h:149
float fpreal32
Definition: SYS_Types.h:200
SYS_FORCE_INLINE UT_Vector4T(const fpreal64 v[tuple_size])
Definition: UT_Vector4.h:204
SYS_FORCE_INLINE UT_Vector4T()=default
void negate3()
Definition: UT_Vector4.h:272
GLdouble GLdouble z
Definition: glew.h:1559
double fpreal64
Definition: SYS_Types.h:201
UT_Vector4T< T > SYSmax(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:682
GLfloat GLfloat GLfloat v2
Definition: glew.h:1856
UT_API UT_Vector4T< T > colVecMult3(const UT_Matrix4T< S > &m, const UT_Vector4T< T > &v)
SYS_FORCE_INLINE T & y()
Definition: UT_Vector3.h:513
UT_API UT_Vector4T< T > rowVecMult3(const UT_Vector4T< T > &v, const UT_Matrix4T< S > &m)
GLclampf f
Definition: glew.h:3499
void clampZero(T tol=0.00001f)
Definition: UT_Vector4.h:257
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1252
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:608
T distance(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:734
GLuint buffer
Definition: glew.h:1680
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:134
const GLuint GLenum const void * binary
Definition: glew.h:3502
T y() const
Definition: UT_Vector4.h:389
static const bool isVectorType
void multiply3(UT_Vector4T< T > &dest, const UT_Matrix4T< S > &mat) const
Definition: UT_Vector4.h:325
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
SYS_FORCE_INLINE T & z()
Definition: UT_Vector3.h:515
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1890
UT_Vector4T< T > SYSinvlerp(const UT_Vector4T< T > &a, const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:716
Definition: VM_SIMD.h:186
SYS_FORCE_INLINE UT_Vector4T(const int64 v[tuple_size])
Definition: UT_Vector4.h:210
long long int64
Definition: SYS_Types.h:116
UT_API UT_Vector3T< T > cross(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
UT_API UT_Vector4T< T > colVecMult(const UT_Matrix4T< S > &m, const UT_Vector4T< T > &v)
T & operator()(unsigned i)
Definition: UT_Vector4.h:394
T z() const
Definition: UT_Vector4.h:391
int findMinAbsAxis() const
These allow you to find out what indices to use for different axes.
Definition: UT_Vector4.h:331
UT_Vector4T< T > & operator*=(const UT_Matrix4T< S > &mat)
Definition: UT_Vector4.h:318
T distance4(const UT_Vector4T< T > &p1, const UT_Vector4T< T > &p2)
Compute the distance between two points.
T x() const
Definition: UT_Vector4.h:387
GLfloat GLfloat p
Definition: glew.h:16321
SYS_FORCE_INLINE UT_Vector4T< T > & operator=(const UT_Vector4T< S > &v)
Definition: UT_Vector4.h:236
void assign(T xx=0.0f, T yy=0.0f, T zz=0.0f, T ww=1.0f)
Set the values of the vector components.
Definition: UT_Vector4.h:412
int findMaxAbsAxis() const
These allow you to find out what indices to use for different axes.
Definition: UT_Vector4.h:356
UT_Vector4T< T > SYSbilerp(const UT_Vector4T< T > &u0v0, const UT_Vector4T< T > &u1v0, const UT_Vector4T< T > &u0v1, const UT_Vector4T< T > &u1v1, S u, S v)
Bilinear interpolation.
Definition: UT_Vector4.h:107
UT_FixedVector< T, 4 > FixedVectorType
Definition: UT_Vector4.h:788
void rowVecMult(const UT_Matrix4T< S > &m)
Definition: UT_Vector4.h:294
SYS_FORCE_INLINE bool isEqual(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that, S tol=S(SYS_FTOLERANCE)) const
static int entries()
Returns the vector size.
Definition: UT_Vector4.h:458
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
UT_API UT_Vector4T< T > rowVecMult(const UT_Vector4T< T > &v, const UT_Matrix4T< S > &m)
UT_Vector4T< T > SYSabs(const UT_Vector4T< T > &v)
Definition: UT_Vector4.h:658
void assign(const T *v, int size=tuple_size)
Set the values of the vector components.
Definition: UT_Vector4.h:418
GLfloat v0
Definition: glew.h:1848
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:77
SYS_FORCE_INLINE T & x()
Definition: UT_Vector3.h:511
void multiply3(const UT_Matrix4T< S > &mat)
Definition: UT_Vector4.h:322
GLuint64EXT * result
Definition: glew.h:14007
UT_Vector4T< T > SYSbarycentric(const UT_Vector4T< T > &v0, const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2, S u, S v)
Barycentric interpolation.
Definition: UT_Vector4.h:114
SYS_FORCE_INLINE UT_Vector4T(const fpreal32 v[tuple_size])
Definition: UT_Vector4.h:201
T distance3d(const UT_Vector4T< T > &p1, const UT_Vector4T< T > &p2)
Compute the distance between two points.
Definition: UT_Vector4.h:154
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:135
T dot(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
The dot product between two vectors.
Definition: UT_Vector4.h:634
SYS_FORCE_INLINE UT_Vector4T(const int32 v[tuple_size])
Definition: UT_Vector4.h:207
void dehomogenize()
Express the point in homogeneous coordinates or vice-versa.
Definition: UT_Vector4.h:434
void clampZero3(T tol=0.00001f)
Definition: UT_Vector4.h:265
int equalZero3(T tol=0.00001f) const
Definition: UT_Vector4.h:250
SYS_FORCE_INLINE UT_Vector4T(T vx, T vy, T vz, T vw=1.0f)
Definition: UT_Vector4.h:194
void rowVecMult3(const UT_Matrix4T< S > &m)
Definition: UT_Vector4.h:307
GLdouble GLdouble t
Definition: glew.h:1398
GLfloat GLfloat v1
Definition: glew.h:1852
T w() const
Definition: UT_Vector4.h:393
T distance3(const UT_Vector4T< T > &p1, const UT_Vector4T< T > &p2)
Compute the distance between two points.
Definition: UT_Vector4.h:743
UT_FixedVector< T, 4, true > Base
Definition: UT_Vector4.h:169