HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_SymMatrix3.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_SymMatrix3.h (UT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __UT_SYMMATRIX3_H_INCLUDED__
12 #define __UT_SYMMATRIX3_H_INCLUDED__
13 
14 #include "UT_API.h"
15 
16 #include "UT_Assert.h"
17 #include "UT_VectorTypes.h"
18 #include <SYS/SYS_Inline.h>
19 #include <SYS/SYS_Math.h> // for SYSlerp, ...
20 #include <SYS/SYS_StaticAssert.h>
21 #include <SYS/SYS_Types.h>
22 
23 #include <string.h> // for memset, ...
24 
25 
26 // Forward declaration
27 template <typename T> class UT_SymMatrix3T;
28 
29 // Free floating methods that operate on UT_SymMatrix3T
30 template <typename T>
32 template <typename T>
34 template <typename T>
36 template <typename T>
38 
39 
40 /// Generic symmetric 3x3 matrix
41 template <typename T>
42 class UT_SymMatrix3T
43 {
44 public:
45  typedef T value_type;
47  static const int tuple_size = 6;
48 
49  /// Construct uninitialized matrix
51 
52  /// Construct matrix with uniform scale
53  explicit UT_SymMatrix3T<T>(T s)
54  {
55  setScale(s, s, s);
56  }
57 
58  /// Construct matrix with arbitrary scale
60  {
61  setScale(s.x(), s.y(), s.z());
62  }
63 
64  /// Construct matrix with full components
66  T q00, T q10, T q11, T q20, T q21, T q22)
67  {
68  myLower.q00 = q00;
69  myLower.q10 = q10; myLower.q11 = q11;
70  myLower.q20 = q20; myLower.q21 = q21; myLower.q22 = q22;
71  }
72 
73  /// Create Householder Reflection matrix R such that R*M will be M with the
74  /// upper N components of column N zeroed out.
75  /// @note This is only useful when N is 1 or 2 for a 3x3 matrix.
76  template <int N>
78 
79  /// Set this to the zero matrix
80  inline void zero()
81  {
82  ::memset(&myV[0], 0, sizeof(myV));
83  }
84 
85  /// Set this to the identity matrix
86  inline void identity()
87  {
88  setScale(1, 1, 1);
89  }
90 
91  /// Return whether this is the identity matrix.
92  inline bool isIdentity() const
93  {
94  return myLower.q00 == 1.0f && myLower.q11 == 1.0f &&
95  myLower.q22 == 1.0f && myLower.q10 == 0.0f &&
96  myLower.q20 == 0.0f && myLower.q21 == 0.0f;
97  }
98 
99  /// Set this to a scale matrix
100  inline void setScale(T sx, T sy, T sz)
101  {
102  myLower.q00 = sx;
103  myLower.q11 = sy;
104  myLower.q22 = sz;
105  myLower.q10 = myLower.q20 = myLower.q21 = 0;
106  }
107  /// Set this to a scale matrix
108  inline void setScale(const UT_Vector3T<T>& s)
109  {
110  setScale(s.x(), s.y(), s.z());
111  }
112 
113  /// Return element (i,j)
114  inline T operator()(const int i, const int j) const
115  {
116  UT_ASSERT_P(i >= 0 && i < 3 && j >= 0 && j < 3);
117  if (i <= j)
118  return myV[(j*(j + 1))/2 + i];
119  else
120  return myV[(i*(i + 1))/2 + j];
121  }
122  /// Return reference to element (i,j)
123  inline T& operator()(const int i, const int j)
124  {
125  UT_ASSERT_P(i >= 0 && i < 3 && j >= 0 && j < 3);
126  if (i <= j)
127  return myV[(j*(j + 1))/2 + i];
128  else
129  return myV[(i*(i + 1))/2 + j];
130  }
131 
132  inline type& operator+=(const type& m)
133  {
134  for (int i = 0; i < tuple_size; ++i)
135  myV[i] += m.myV[i];
136  return *this;
137  }
138  inline type& operator-=(const type& m)
139  {
140  for (int i = 0; i < tuple_size; ++i)
141  myV[i] -= m.myV[i];
142  return *this;
143  }
144  inline type& operator*=(T scalar)
145  {
146  for (int i = 0; i < tuple_size; ++i)
147  myV[i] *= scalar;
148  return *this;
149  }
150  inline type& operator/=(T scalar)
151  {
152  return operator*=(1.0/scalar);
153  }
154 
155  /// Set this to a linear interpolation of the two given transforms:
156  /// *this = a + t*(b - a)
157  void lerp(const type& a, const type& b, T t)
158  {
159  for (int i = 0; i < 6; ++i)
160  myV[i] = SYSlerp(a.myV[i], b.myV[i], t);
161  }
162 
163  /// Inner class to access the elements symbolically
164  struct LowerTri
165  {
167  };
168  struct UpperTri
169  {
171  };
172 
173  /// Return the raw pointer to an array of tuple_size (6) elements
174  /// @{
175  const T* data() const { return &myV[0]; }
176  T* data() { return &myV[0]; }
177  /// @}
178 
179  /// Return reference to the lower triangular elements for symbolic access
180  const LowerTri & lowerTri() const { return myLower; }
181 
182  /// Return reference to the upper triangular elements for symbolic access
183  const UpperTri & upperTri() const { return myUpper; }
184 
185 
186  void transpose() {}
187 
188  // Sets the matrix to v * vT
189  void outerproduct(const UT_Vector3T<T> &v);
190  void outerproduct(T a, T b, T c);
191 
192  // Updates: Matrix += v * vT
193  void outerproductUpdate(const UT_Vector3T<T> &v);
194  void outerproductUpdate(T a, T b, T c);
195 
196  // Updates: Matrix += coef * v * vT
197  void outerproductUpdate(const UT_Vector3T<T> &v, T coef);
198  void outerproductUpdate(T a, T b, T c, T coef);
199 
200  // Calculates vT * Matrix * v
201  T vQv(const UT_Vector3T<T> &v) const;
202 
203 private:
204  // myV stores the elements of upper triangular portion of the symmetric
205  // matrix in a column-major form (or equivalently, the lower triangular
206  // portion in row-major form). The element (I, J) with I <= J, is stored
207  // at index: c = (J * (J + 1))/2 + I
208  // So the matrix is:
209  // myV[0] myV[1] myV[3]
210  // myV[1] myV[2] myV[4]
211  // myV[3] myV[4] myV[5]
212  //
213  union {
214  T myV[6];
217  };
218 
219  template <typename S> friend class UT_Matrix3T;
220  template <typename S> friend class UT_Matrix4T;
221 };
225 
226 ///////////////////////////////////////////////////////////////////////////////
227 //
228 // Implementations
229 //
230 
231 /// Return (m1 + m2)
232 template <typename T>
235 {
236  typedef typename UT_SymMatrix3T<T>::LowerTri LowerTri;
237  const LowerTri& x = m1.lowerTri();
238  const LowerTri& y = m2.lowerTri();
239  return UT_SymMatrix3T<T>(x.q00 + y.q00,
240  x.q10 + y.q10, x.q11 + y.q11,
241  x.q20 + y.q20, x.q21 + y.q21, x.q22 + y.q22);
242 }
243 
244 /// Return (m1 - m2)
245 template <typename T>
248 {
249  typedef typename UT_SymMatrix3T<T>::LowerTri LowerTri;
250  const LowerTri& x = m1.lowerTri();
251  const LowerTri& y = m2.lowerTri();
252  return UT_SymMatrix3T<T>(x.q00 - y.q00,
253  x.q10 - y.q10, x.q11 - y.q11,
254  x.q20 - y.q20, x.q21 - y.q21, x.q22 - y.q22);
255 }
256 
257 /// Return (m * s) for scalar s
258 template <typename T>
261 {
262  typedef typename UT_SymMatrix3T<T>::LowerTri LowerTri;
263  const LowerTri& l = m.lowerTri();
264  return UT_SymMatrix3T<T>(l.q00 * scale,
265  l.q10 * scale, l.q11 * scale,
266  l.q20 * scale, l.q21 * scale, l.q22 * scale);
267 }
268 
269 /// Create Householder Reflection matrix R such that R*M will be M with the
270 /// upper N components of column N zeroed out.
271 /// @note This is only useful when N is 1 or 2 for a 3x3 matrix.
272 template <typename T>
273 template <int N>
274 inline UT_SymMatrix3T<T>
276 {
277  // Adapted from Algorithm 5.1.1 (Householder Vector) in
278  // "Matrix Computations" (3rd Edition) by Golub and Van Loan.
279 
280  SYS_STATIC_ASSERT(N >= 1 && N <= 2);
282  T sigma;
283  if (N == 2)
284  {
285  v.assign(m(0,2), m(1,2), 1);
286  sigma = v(0)*v(0) + v(1)*v(1);
287  }
288  else if (N == 1)
289  {
290  v.assign(m(0,1), 1, 0);
291  sigma = v(0)*v(0);
292  }
293  if (sigma != 0)
294  {
295  T denom;
296  const T diag = m(N,N);
297  T mu = SYSsqrt(diag*diag + sigma);
298  if (diag <= 0)
299  denom = diag - mu;
300  else
301  denom = -sigma / (diag + mu);
302  v(0) /= denom;
303  if (N == 2)
304  v(1) /= denom;
305 
306  T beta = 2 * denom*denom / (sigma + denom*denom);
307  if (N == 2)
308  {
309  return UT_SymMatrix3T<T>(
310  1 - beta*v(0)*v(0),
311  - beta*v(0)*v(1), 1 - beta*v(1)*v(1),
312  - beta*v(0), - beta*v(1), 1 - beta);
313  }
314  else if (N == 1)
315  {
316  return UT_SymMatrix3T<T>(
317  1 - beta*v(0)*v(0),
318  - beta*v(0), 1 - beta,
319  0, 0, 1);
320  }
321  }
322  return UT_SymMatrix3T<T>(1); // identity
323 }
324 
325 /// Return (s * m) for scalar s
326 template <typename T>
329 {
330  typedef typename UT_SymMatrix3T<T>::LowerTri LowerTri;
331  const LowerTri& l = m.lowerTri();
332  return UT_SymMatrix3T<T>(l.q00 * scale,
333  l.q10 * scale, l.q11 * scale,
334  l.q20 * scale, l.q21 * scale, l.q22 * scale);
335 }
336 
337 template <typename T>
338 void
340 {
341  outerproduct(v.x(), v.y(), v.z());
342 }
343 
344 template <typename T>
345 void
347 {
348  myUpper.q00 = a * a; myUpper.q01 = a * b; myUpper.q02 = a * c;
349  myUpper.q11 = b * b; myUpper.q12 = b * c;
350  myUpper.q22 = c * c;
351 }
352 
353 template <typename T>
354 void
356 {
357  outerproductUpdate(v.x(), v.y(), v.z());
358 }
359 
360 template <typename T>
361 void
363 {
364  myUpper.q00 += a * a; myUpper.q01 += a * b; myUpper.q02 += a * c;
365  myUpper.q11 += b * b; myUpper.q12 += b * c;
366  myUpper.q22 += c * c;
367 
368 }
369 
370 template <typename T>
371 void
373 {
374  outerproductUpdate(v.x(), v.y(), v.z(), coef);
375 }
376 
377 template <typename T>
378 void
380 {
381  myUpper.q00 += coef * (a * a); myUpper.q01 += coef * (a * b);
382  myUpper.q02 += coef * (a * c);
383  myUpper.q11 += coef * (b * b); myUpper.q12 += coef * (b * c);
384  myUpper.q22 += coef * (c * c);
385 
386 }
387 
388 // Calculates vT this v
389 template <typename T>
390 T
392 {
393  T a = v.x(), b = v.y(), c = v.z();
394 
395  return (a * (a * myUpper.q00 + 2 * (b * myUpper.q01 + c * myUpper.q02)) +
396  b * (b * myUpper.q11 + 2 * (c * myUpper.q12)) +
397  c * (c * myUpper.q22 ));
398 }
399 
400 // Overload for custom formatting of UT_Matrix3T<T> with UTformat.
401 template<typename T>
402 UT_API size_t format(char *buffer, size_t buffer_size,
403  const UT_SymMatrix3T<T> &m);
404 
405 #endif // __UT_SYMMATRIX3_H_INCLUDED__
GLdouble s
Definition: glew.h:1390
UT_SymMatrix3T< float > UT_SymMatrix3F
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:609
UT_API size_t format(char *buffer, size_t buffer_size, const UT_SymMatrix3T< T > &m)
#define SYS_STATIC_ASSERT(expr)
T vQv(const UT_Vector3T< T > &v) const
static const int tuple_size
Definition: UT_SymMatrix3.h:47
T & operator()(const int i, const int j)
Return reference to element (i,j)
UT_SymMatrix3T< T > type
Definition: UT_SymMatrix3.h:46
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:625
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:13880
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
const LowerTri & lowerTri() const
Return reference to the lower triangular elements for symbolic access.
#define UT_API
Definition: UT_API.h:13
Generic symmetric 3x3 matrix.
Definition: UT_SymMatrix3.h:27
const GLdouble * m
Definition: glew.h:9124
GLdouble l
Definition: glew.h:9122
const GLdouble * v
Definition: glew.h:1391
UT_Matrix2T< T > SYSlerp(const UT_Matrix2T< T > &v1, const UT_Matrix2T< T > &v2, S t)
Definition: UT_Matrix2.h:604
SYS_FORCE_INLINE T & x(void)
Definition: UT_Vector3.h:507
void outerproduct(const UT_Vector3T< T > &v)
3D Vector class.
void outerproductUpdate(T b, const UT_Vector4T< S > &v1, const UT_Vector4T< S > &v2)
void zero()
Set this to the zero matrix.
Definition: UT_SymMatrix3.h:80
void identity()
Set this to the identity matrix.
Definition: UT_SymMatrix3.h:86
LowerTri myLower
static UT_SymMatrix3T< T > householderZeroUpper(const UT_Matrix3T< T > &m)
SYS_FORCE_INLINE T & z(void)
Definition: UT_Vector3.h:511
UT_SymMatrix3T< fpreal > UT_SymMatrix3R
type & operator+=(const type &m)
void setScale(T sx, T sy, T sz)
Set this to a scale matrix.
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:635
UT_SymMatrix3T< double > UT_SymMatrix3D
GLuint buffer
Definition: glew.h:1680
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:134
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
void setScale(const UT_Vector3T< T > &s)
Set this to a scale matrix.
T operator()(const int i, const int j) const
Return element (i,j)
const UpperTri & upperTri() const
Return reference to the upper triangular elements for symbolic access.
const GLfloat * c
Definition: glew.h:16296
const T * data() const
bool isIdentity() const
Return whether this is the identity matrix.
Definition: UT_SymMatrix3.h:92
void lerp(const type &a, const type &b, T t)
Inner class to access the elements symbolically.
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
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:537
SYS_FORCE_INLINE T & y(void)
Definition: UT_Vector3.h:509
GA_API const UT_StringHolder N
void outerproductUpdate(const UT_Vector3T< T > &v)
UpperTri myUpper
type & operator/=(T scalar)
type & operator*=(T scalar)
type & operator-=(const type &m)
GLdouble GLdouble t
Definition: glew.h:1398