HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UT_FixedVector.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: UT_FixedVector.h (UT Library, C++)
7  *
8  * COMMENTS: A vector class templated on its size and data type.
9  */
10 
11 #pragma once
12 
13 #ifndef __UT_FixedVector__
14 #define __UT_FixedVector__
15 
16 #include "UT_Assert.h"
17 #include "UT_Storage.h"
18 #include <SYS/SYS_Inline.h>
19 #include <SYS/SYS_Math.h>
20 #include <SYS/SYS_Types.h>
21 #include <SYS/SYS_TypeTraits.h>
22 
23 template<typename T,exint SIZE,bool INSTANTIATED=false>
25 {
26 public:
28  typedef T value_type;
29  typedef T theType;
30  static const exint theSize = SIZE;
31 
33 
34  SYS_FORCE_INLINE UT_FixedVector() = default;
35 
36  /// Initializes every component to the same value
37  SYS_FORCE_INLINE explicit UT_FixedVector(T that) noexcept
38  {
39  for (exint i = 0; i < SIZE; ++i)
40  vec[i] = that;
41  }
42 
43  SYS_FORCE_INLINE UT_FixedVector(const ThisType &that) = default;
44  SYS_FORCE_INLINE UT_FixedVector(ThisType &&that) = default;
45 
46  /// Converts vector of S into vector of T,
47  /// or just copies if same type.
48  template<typename S,bool S_INSTANTIATED>
50  {
51  for (exint i = 0; i < SIZE; ++i)
52  vec[i] = that[i];
53  }
54 
55  template<typename S>
56  SYS_FORCE_INLINE UT_FixedVector(const S that[SIZE]) noexcept
57  {
58  for (exint i = 0; i < SIZE; ++i)
59  vec[i] = that[i];
60  }
61 
62  SYS_FORCE_INLINE const T &operator[](exint i) const noexcept
63  {
64  UT_ASSERT_P(i >= 0 && i < SIZE);
65  return vec[i];
66  }
68  {
69  UT_ASSERT_P(i >= 0 && i < SIZE);
70  return vec[i];
71  }
72 
73  SYS_FORCE_INLINE constexpr const T *data() const noexcept
74  {
75  return vec;
76  }
77  SYS_FORCE_INLINE T *data() noexcept
78  {
79  return vec;
80  }
81 
82  SYS_FORCE_INLINE ThisType &operator=(const ThisType &that) = default;
83  SYS_FORCE_INLINE ThisType &operator=(ThisType &&that) = default;
84 
85  template <typename S,bool S_INSTANTIATED>
87  {
88  for (exint i = 0; i < SIZE; ++i)
89  vec[i] = that[i];
90  return *this;
91  }
92  SYS_FORCE_INLINE const ThisType &operator=(T that) noexcept
93  {
94  for (exint i = 0; i < SIZE; ++i)
95  vec[i] = that;
96  return *this;
97  }
98  template<typename S,bool S_INSTANTIATED>
100  {
101  for (exint i = 0; i < SIZE; ++i)
102  vec[i] += that[i];
103  }
105  {
106  for (exint i = 0; i < SIZE; ++i)
107  vec[i] += that;
108  }
109  template<typename S,bool S_INSTANTIATED>
111  {
112  typedef typename UT_StorageBetter<T,S>::Type Type;
114  for (exint i = 0; i < SIZE; ++i)
115  result[i] = vec[i] + that[i];
116  return result;
117  }
118  template<typename S,bool S_INSTANTIATED>
120  {
121  for (exint i = 0; i < SIZE; ++i)
122  vec[i] -= that[i];
123  }
125  {
126  for (exint i = 0; i < SIZE; ++i)
127  vec[i] -= that;
128  }
129  template<typename S,bool S_INSTANTIATED>
131  {
132  typedef typename UT_StorageBetter<T,S>::Type Type;
134  for (exint i = 0; i < SIZE; ++i)
135  result[i] = vec[i] - that[i];
136  return result;
137  }
138  template<typename S,bool S_INSTANTIATED>
140  {
141  for (exint i = 0; i < SIZE; ++i)
142  vec[i] *= that[i];
143  }
144  template<typename S,bool S_INSTANTIATED>
146  {
147  typedef typename UT_StorageBetter<T,S>::Type Type;
149  for (exint i = 0; i < SIZE; ++i)
150  result[i] = vec[i] * that[i];
151  return result;
152  }
154  {
155  for (exint i = 0; i < SIZE; ++i)
156  vec[i] *= that;
157  }
158  /// NOTE: Strictly speaking, this should use UT_StorageBetter<T,S>::Type,
159  /// but in the interests of avoiding accidental precision escalation,
160  /// it uses T.
162  {
163  UT_FixedVector<T,SIZE> result;
164  for (exint i = 0; i < SIZE; ++i)
165  result[i] = vec[i] * that;
166  return result;
167  }
168  template<typename S,bool S_INSTANTIATED>
170  {
171  for (exint i = 0; i < SIZE; ++i)
172  vec[i] /= that[i];
173  }
174  template<typename S,bool S_INSTANTIATED>
176  {
177  typedef typename UT_StorageBetter<T,S>::Type Type;
179  for (exint i = 0; i < SIZE; ++i)
180  result[i] = vec[i] / that[i];
181  return result;
182  }
183 
185  {
186  typename Storage::MathFloat t(that);
187  t = typename Storage::MathFloat(1)/t;
188  for (exint i = 0; i < SIZE; ++i)
189  vec[i] *= t;
190  }
191  /// NOTE: Strictly speaking, this should use UT_StorageBetter<T,S>::Type,
192  /// but in the interests of avoiding accidental precision escalation,
193  /// it uses T.
195  {
196  typename Storage::MathFloat t(that);
197  t = typename Storage::MathFloat(1)/t;
198  UT_FixedVector<T,SIZE> result;
199  for (exint i = 0; i < SIZE; ++i)
200  result[i] = vec[i] * t;
201  return result;
202  }
204  {
205  for (exint i = 0; i < SIZE; ++i)
206  vec[i] = -vec[i];
207  }
208 
210  {
211  UT_FixedVector<T,SIZE> result;
212  for (exint i = 0; i < SIZE; ++i)
213  result[i] = -vec[i];
214  return result;
215  }
216 
217  template<typename S,bool S_INSTANTIATED>
219  {
220  for (exint i = 0; i < SIZE; ++i)
221  {
222  if (vec[i] != T(that[i]))
223  return false;
224  }
225  return true;
226  }
227  template<typename S,bool S_INSTANTIATED>
229  {
230  return !(*this==that);
231  }
232  SYS_FORCE_INLINE bool isNan() const
233  {
234  for (exint i = 0; i < SIZE; ++i)
235  {
236  if (SYSisNan(vec[i]))
237  return true;
238  }
239  return false;
240  }
241  SYS_FORCE_INLINE bool isZero() const noexcept
242  {
243  for (exint i = 0; i < SIZE; ++i)
244  {
245  if (vec[i] != T(0))
246  return false;
247  }
248  return true;
249  }
251  {
252  for (exint i = 0; i < SIZE; ++i)
253  {
254  if (vec[i] < -tol || vec[i] > tol)
255  return false;
256  }
257  return true;
258  }
259  template<typename S,bool S_INSTANTIATED>
261  {
262  for (exint i = 0; i < SIZE; ++i)
263  {
264  if (vec[i] < that[i]-tol || vec[i] > that[i]+tol)
265  return false;
266  }
267  return true;
268  }
270  {
271  T v = vec[0];
272  for (exint i = 1; i < SIZE; ++i)
273  v = (vec[i] > v) ? vec[i] : v;
274  return v;
275  }
277  {
278  T v = vec[0];
279  for (exint i = 1; i < SIZE; ++i)
280  v = (vec[i] < v) ? vec[i] : v;
281  return v;
282  }
284  {
285  T v = vec[0];
286  for (exint i = 1; i < SIZE; ++i)
287  v += vec[i];
288  return v / SIZE;
289  }
290 
292  {
293  typedef typename Storage::AtLeast32Bit TheType;
294  TheType a0(vec[0]);
295  TheType result(a0*a0);
296  for (exint i = 1; i < SIZE; ++i)
297  {
298  TheType ai(vec[i]);
299  result += ai*ai;
300  }
301  return result;
302  }
304  {
305  typename Storage::MathFloat len2(length2());
306  return SYSsqrt(len2);
307  }
308  template<typename S,bool S_INSTANTIATED>
310  {
311  typedef typename UT_StorageNum<typename UT_StorageBetter<T,S>::Type>::AtLeast32Bit TheType;
312  TheType result(TheType(vec[0])*TheType(that[0]));
313  for (exint i = 1; i < SIZE; ++i)
314  result += TheType(vec[i])*TheType(that[i]);
315  return result;
316  }
317  template<typename S,bool S_INSTANTIATED>
319  {
320  typedef typename UT_StorageNum<typename UT_StorageBetter<T,S>::Type>::AtLeast32Bit TheType;
321  TheType v(TheType(vec[0]) - TheType(that[0]));
322  TheType result(v*v);
323  for (exint i = 1; i < SIZE; ++i)
324  {
325  v = TheType(vec[i]) - TheType(that[i]);
326  result += v*v;
327  }
328  return result;
329  }
330  template<typename S,bool S_INSTANTIATED>
332  {
333  typename UT_StorageNum<typename UT_StorageBetter<T,S>::Type>::MathFloat dist2(distance2(that));
334  return SYSsqrt(dist2);
335  }
336 
338  {
339  typename Storage::AtLeast32Bit len2 = length2();
341  return typename Storage::MathFloat(0);
342  if (len2 == typename Storage::AtLeast32Bit(1))
343  return typename Storage::MathFloat(1);
344  typename Storage::MathFloat len = SYSsqrt(typename Storage::MathFloat(len2));
345  // Check if the square root is equal 1. sqrt(1+dx) ~ 1+dx/2,
346  // so it may get rounded to 1 when it wasn't 1 before.
347  if (len != typename Storage::MathFloat(1))
348  (*this) /= len;
349  return len;
350  }
351 
352 public:
354 };
355 
356 /// NOTE: Strictly speaking, this should use UT_StorageBetter<T,S>::Type,
357 /// but in the interests of avoiding accidental precision escalation,
358 /// it uses T.
359 template<typename T,exint SIZE,bool INSTANTIATED,typename S>
361 {
362  T t(that);
363  UT_FixedVector<T,SIZE> result;
364  for (exint i = 0; i < SIZE; ++i)
365  result[i] = t * a[i];
366  return result;
367 }
368 
369 template<typename T, exint SIZE, bool INSTANTIATED, typename S, bool S_INSTANTIATED>
372 {
373  return a.dot(b);
374 }
375 
376 template<typename T>
378 {
380  typedef T DataType;
381  static const exint TupleSize = 1;
382  static const bool isVectorType = false;
383 };
384 
385 template<typename T,exint SIZE,bool INSTANTIATED>
387 {
389  typedef T DataType;
390  static const exint TupleSize = SIZE;
391  static const bool isVectorType = true;
392 };
393 
394 #endif
SYS_FORCE_INLINE void operator*=(T that)
SYS_FORCE_INLINE void operator+=(T that)
SYS_FORCE_INLINE T minComponent() const
SYS_FORCE_INLINE constexpr const T * data() const noexcept
SYS_FORCE_INLINE UT_FixedVector(const S that[SIZE]) noexcept
SYS_FORCE_INLINE UT_FixedVector< T, SIZE > operator-() const
Mat3< typename promote< S, T >::type > operator*(S scalar, const Mat3< T > &m)
Returns M, where for .
Definition: Mat3.h:615
SYS_FORCE_INLINE const ThisType & operator=(T that) noexcept
SYS_FORCE_INLINE UT_StorageNum< typename UT_StorageBetter< T, S >::Type >::AtLeast32Bit distance2(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const
SYS_FORCE_INLINE void operator*=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that)
SYS_FORCE_INLINE bool isNan() const
SYS_FORCE_INLINE const T & operator[](exint i) const noexcept
SYS_FORCE_INLINE void operator/=(T that)
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:128
UT_StorageNum< T > Storage
SYS_FORCE_INLINE ThisType & operator=(const ThisType &that)=default
SYS_FORCE_INLINE bool equalZero(T tol=T(SYS_FTOLERANCE)) const
const GLdouble * v
Definition: glcorearb.h:836
SYS_FORCE_INLINE bool isZero() const noexcept
UT_FixedVector< T, SIZE, INSTANTIATED > FixedVectorType
SYS_FORCE_INLINE UT_FixedVector< typename UT_StorageBetter< T, S >::Type, SIZE > operator+(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const
SYS_FORCE_INLINE void negate()
void AtLeast32Bit
Definition: UT_Storage.h:72
SYS_FORCE_INLINE UT_FixedVector< typename UT_StorageBetter< T, S >::Type, SIZE > operator/(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
bool SYSisNan(const F f)
Definition: SYS_Math.h:173
SYS_FORCE_INLINE UT_FixedVector< T, SIZE > operator*(T that) const
static const exint TupleSize
png_uint_32 i
Definition: png.h:2877
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:101
SYS_FORCE_INLINE UT_StorageNum< typename UT_StorageBetter< T, S >::Type >::AtLeast32Bit dot(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const
SYS_FORCE_INLINE bool operator==(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const noexcept
SYS_FORCE_INLINE UT_FixedVector()=default
SYS_FORCE_INLINE UT_FixedVector(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) noexcept
SYS_FORCE_INLINE void operator+=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that)
SYS_FORCE_INLINE void operator/=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that)
fpreal32 MathFloat
Definition: UT_Storage.h:73
int64 exint
Definition: SYS_Types.h:109
SYS_FORCE_INLINE UT_FixedVector< T, SIZE > operator/(T that) const
static const bool isVectorType
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
SYS_FORCE_INLINE bool operator!=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const noexcept
SYS_FORCE_INLINE T maxComponent() const
SYS_FORCE_INLINE UT_StorageNum< typename UT_StorageBetter< T, S >::Type >::AtLeast32Bit dot(const UT_FixedVector< T, SIZE, INSTANTIATED > &a, const UT_FixedVector< S, SIZE, S_INSTANTIATED > &b)
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
SYS_FORCE_INLINE UT_StorageNum< typename UT_StorageBetter< T, S >::Type >::MathFloat distance(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const
SYS_FORCE_INLINE T * data() noexcept
UT_FixedVector< T, SIZE, INSTANTIATED > ThisType
SYS_FORCE_INLINE UT_FixedVector< typename UT_StorageBetter< T, S >::Type, SIZE > operator*(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const
SYS_FORCE_INLINE T & operator[](exint i) noexcept
SYS_FORCE_INLINE bool isEqual(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that, S tol=S(SYS_FTOLERANCE)) const
UT_FixedVector< T, 1 > FixedVectorType
SYS_FORCE_INLINE Storage::MathFloat normalize()
#define SIZE
Definition: simple.C:40
#define SYS_FTOLERANCE
Definition: SYS_Types.h:196
SYS_FORCE_INLINE void operator-=(T that)
SYS_FORCE_INLINE Storage::AtLeast32Bit length2() const noexcept
#define const
Definition: zconf.h:214
SYS_FORCE_INLINE ThisType & operator=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) noexcept
SYS_FORCE_INLINE UT_FixedVector< typename UT_StorageBetter< T, S >::Type, SIZE > operator-(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const
SYS_FORCE_INLINE Storage::MathFloat length() const
SYS_FORCE_INLINE UT_FixedVector(T that) noexcept
Initializes every component to the same value.
SYS_FORCE_INLINE T avgComponent() const
static const exint theSize
SYS_FORCE_INLINE void operator-=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that)