HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
matrix4f.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 ////////////////////////////////////////////////////////////////////////
8 // This file is generated by a script. Do not edit directly. Edit the
9 // matrix4.template.h file to make changes.
10 
11 #ifndef PXR_BASE_GF_MATRIX4F_H
12 #define PXR_BASE_GF_MATRIX4F_H
13 
14 /// \file gf/matrix4f.h
15 /// \ingroup group_gf_LinearAlgebra
16 
17 #include "pxr/pxr.h"
18 #include "pxr/base/gf/api.h"
19 #include "pxr/base/gf/declare.h"
20 #include "pxr/base/gf/matrixData.h"
21 #include "pxr/base/gf/vec4f.h"
22 #include "pxr/base/gf/traits.h"
24 #include "pxr/base/gf/limits.h"
25 #include "pxr/base/gf/math.h"
26 #include "pxr/base/gf/vec3f.h"
27 #include "pxr/base/tf/hash.h"
28 
29 #include <iosfwd>
30 #include <vector>
31 
33 
34 template <>
35 struct GfIsGfMatrix<class GfMatrix4f> { static const bool value = true; };
36 
37 class GfMatrix4d;
38 class GfMatrix4f;
39 class GfQuatf;
40 class GfRotation;
41 class GfMatrix3f;
42 
43 /// \class GfMatrix4f
44 /// \ingroup group_gf_LinearAlgebra
45 ///
46 /// Stores a 4x4 matrix of \c float elements. A basic type.
47 ///
48 /// Matrices are defined to be in row-major order, so <c>matrix[i][j]</c>
49 /// indexes the element in the \e i th row and the \e j th column.
50 ///
51 /// <h3>3D Transformations</h3>
52 ///
53 /// The following methods interpret a GfMatrix4f as a 3D
54 /// transformation: SetRotate(), SetScale(), SetTranslate(), SetLookAt(),
55 /// Factor(), ExtractTranslation(), ExtractRotation(), Transform(),
56 /// TransformDir(). By convention, vectors are treated primarily as row
57 /// vectors, implying the following:
58 /// \li Transformation matrices are organized to deal with row
59 /// vectors, not column vectors. For example, the last row of a matrix
60 /// contains the translation amounts.
61 /// \li Each of the Set() methods below completely rewrites the
62 /// matrix; for example, SetTranslate() yields a matrix
63 /// which does nothing but translate.
64 /// \li When multiplying two transformation matrices, the matrix
65 /// on the left applies a more local transformation to a row
66 /// vector. For example, if R represents a rotation
67 /// matrix and T represents a translation matrix, the
68 /// product R*T will rotate a row vector, then translate
69 /// it.
71 {
72 public:
73  typedef float ScalarType;
74 
75  static const size_t numRows = 4;
76  static const size_t numColumns = 4;
77 
78  /// GfMatrix4f value-initializes to zero and performs no default
79  /// initialization, like float or double.
80  GfMatrix4f() = default;
81 
82  /// Constructor. Initializes the matrix from 16 independent
83  /// \c float values, specified in row-major order. For example,
84  /// parameter \e m10 specifies the value in row 1 and column 0.
85  GfMatrix4f(float m00, float m01, float m02, float m03,
86  float m10, float m11, float m12, float m13,
87  float m20, float m21, float m22, float m23,
88  float m30, float m31, float m32, float m33) {
89  Set(m00, m01, m02, m03,
90  m10, m11, m12, m13,
91  m20, m21, m22, m23,
92  m30, m31, m32, m33);
93  }
94 
95  /// Constructor. Initializes the matrix from a 4x4 array
96  /// of \c float values, specified in row-major order.
97  GfMatrix4f(const float m[4][4]) {
98  Set(m);
99  }
100 
101  /// Constructor. Explicitly initializes the matrix to \e s times the
102  /// identity matrix.
103  explicit GfMatrix4f(float s) {
104  SetDiagonal(s);
105  }
106 
107  /// Constructor. Explicitly initializes the matrix to diagonal form,
108  /// with the \e i th element on the diagonal set to <c>v[i]</c>.
109  explicit GfMatrix4f(const GfVec4f& v) {
110  SetDiagonal(v);
111  }
112 
113  /// Constructor. Initialize the matrix from a vector of vectors of
114  /// double. The vector is expected to be 4x4. If it is
115  /// too big, only the first 4 rows and/or columns will be used.
116  /// If it is too small, uninitialized elements will be filled in with
117  /// the corresponding elements from an identity matrix.
118  ///
119  GF_API
120  explicit GfMatrix4f(const std::vector< std::vector<double> >& v);
121 
122  /// Constructor. Initialize the matrix from a vector of vectors of
123  /// float. The vector is expected to be 4x4. If it is
124  /// too big, only the first 4 rows and/or columns will be used.
125  /// If it is too small, uninitialized elements will be filled in with
126  /// the corresponding elements from an identity matrix.
127  ///
128  GF_API
129  explicit GfMatrix4f(const std::vector< std::vector<float> >& v);
130 
131  /// Constructor. Initialize the matrix from 4 row vectors of
132  /// double. Each vector is expected to length 4. If it is too
133  /// big, only the first 4 items will be used. If it is too small,
134  /// uninitialized elements will be filled in with the
135  /// corresponding elements from an identity matrix.
136  ///
137  GF_API
138  explicit GfMatrix4f(const std::vector<double>& r0,
139  const std::vector<double>& r1,
140  const std::vector<double>& r2,
141  const std::vector<double>& r3);
142 
143  /// Constructor. Initialize the matrix from 4 row vectors of
144  /// float. Each vector is expected to length 4. If it is too
145  /// big, only the first 4 items will be used. If it is too small,
146  /// uninitialized elements will be filled in with the
147  /// corresponding elements from an identity matrix.
148  ///
149  GF_API
150  explicit GfMatrix4f(const std::vector<float>& r0,
151  const std::vector<float>& r1,
152  const std::vector<float>& r2,
153  const std::vector<float>& r3);
154 
155  /// Constructor. Initializes a transformation matrix to perform the
156  /// indicated rotation and translation.
157  GF_API
159  const GfVec3f& translate);
160 
161  /// Constructor. Initializes a transformation matrix to perform the
162  /// indicated rotation and translation.
163  GF_API
164  GfMatrix4f(const GfMatrix3f& rotmx,
165  const GfVec3f& translate);
166  /// This explicit constructor converts a "double" matrix to a "float" matrix.
167  GF_API
168  explicit GfMatrix4f(const class GfMatrix4d& m);
169 
170  /// Sets a row of the matrix from a Vec4.
171  void SetRow(int i, const GfVec4f & v) {
172  _mtx[i][0] = v[0];
173  _mtx[i][1] = v[1];
174  _mtx[i][2] = v[2];
175  _mtx[i][3] = v[3];
176  }
177 
178  /// Sets a column of the matrix from a Vec4.
179  void SetColumn(int i, const GfVec4f & v) {
180  _mtx[0][i] = v[0];
181  _mtx[1][i] = v[1];
182  _mtx[2][i] = v[2];
183  _mtx[3][i] = v[3];
184  }
185 
186  /// Gets a row of the matrix as a Vec4.
187  GfVec4f GetRow(int i) const {
188  return GfVec4f(_mtx[i][0], _mtx[i][1], _mtx[i][2], _mtx[i][3]);
189  }
190 
191  /// Gets a column of the matrix as a Vec4.
192  GfVec4f GetColumn(int i) const {
193  return GfVec4f(_mtx[0][i], _mtx[1][i], _mtx[2][i], _mtx[3][i]);
194  }
195 
196  /// Sets the matrix from 16 independent \c float values,
197  /// specified in row-major order. For example, parameter \e m10 specifies
198  /// the value in row 1 and column 0.
199  GfMatrix4f& Set(float m00, float m01, float m02, float m03,
200  float m10, float m11, float m12, float m13,
201  float m20, float m21, float m22, float m23,
202  float m30, float m31, float m32, float m33) {
203  _mtx[0][0] = m00; _mtx[0][1] = m01; _mtx[0][2] = m02; _mtx[0][3] = m03;
204  _mtx[1][0] = m10; _mtx[1][1] = m11; _mtx[1][2] = m12; _mtx[1][3] = m13;
205  _mtx[2][0] = m20; _mtx[2][1] = m21; _mtx[2][2] = m22; _mtx[2][3] = m23;
206  _mtx[3][0] = m30; _mtx[3][1] = m31; _mtx[3][2] = m32; _mtx[3][3] = m33;
207  return *this;
208  }
209 
210  /// Sets the matrix from a 4x4 array of \c float
211  /// values, specified in row-major order.
212  GfMatrix4f& Set(const float m[4][4]) {
213  _mtx[0][0] = m[0][0];
214  _mtx[0][1] = m[0][1];
215  _mtx[0][2] = m[0][2];
216  _mtx[0][3] = m[0][3];
217  _mtx[1][0] = m[1][0];
218  _mtx[1][1] = m[1][1];
219  _mtx[1][2] = m[1][2];
220  _mtx[1][3] = m[1][3];
221  _mtx[2][0] = m[2][0];
222  _mtx[2][1] = m[2][1];
223  _mtx[2][2] = m[2][2];
224  _mtx[2][3] = m[2][3];
225  _mtx[3][0] = m[3][0];
226  _mtx[3][1] = m[3][1];
227  _mtx[3][2] = m[3][2];
228  _mtx[3][3] = m[3][3];
229  return *this;
230  }
231 
232  /// Sets the matrix to the identity matrix.
234  return SetDiagonal(1);
235  }
236 
237  /// Sets the matrix to zero.
239  return SetDiagonal(0);
240  }
241 
242  /// Sets the matrix to \e s times the identity matrix.
243  GF_API
244  GfMatrix4f& SetDiagonal(float s);
245 
246  /// Sets the matrix to have diagonal (<c>v[0], v[1], v[2], v[3]</c>).
247  GF_API
248  GfMatrix4f& SetDiagonal(const GfVec4f&);
249 
250  /// Fills a 4x4 array of \c float values with the values in
251  /// the matrix, specified in row-major order.
252  GF_API
253  float* Get(float m[4][4]) const;
254 
255  /// Returns raw access to components of matrix as an array of
256  /// \c float values. Components are in row-major order.
257  float* data() {
258  return _mtx.GetData();
259  }
260 
261  /// Returns const raw access to components of matrix as an array of
262  /// \c float values. Components are in row-major order.
263  const float* data() const {
264  return _mtx.GetData();
265  }
266 
267  /// Returns vector components as an array of \c float values.
268  float* GetArray() {
269  return _mtx.GetData();
270  }
271 
272  /// Returns vector components as a const array of \c float values.
273  const float* GetArray() const {
274  return _mtx.GetData();
275  }
276 
277  /// Accesses an indexed row \e i of the matrix as an array of 4 \c
278  /// float values so that standard indexing (such as <c>m[0][1]</c>)
279  /// works correctly.
280  float* operator [](int i) { return _mtx[i]; }
281 
282  /// Accesses an indexed row \e i of the matrix as an array of 4 \c
283  /// float values so that standard indexing (such as <c>m[0][1]</c>)
284  /// works correctly.
285  const float* operator [](int i) const { return _mtx[i]; }
286 
287  /// Hash.
288  friend inline size_t hash_value(GfMatrix4f const &m) {
289  return TfHash::Combine(
290  m._mtx[0][0],
291  m._mtx[0][1],
292  m._mtx[0][2],
293  m._mtx[0][3],
294  m._mtx[1][0],
295  m._mtx[1][1],
296  m._mtx[1][2],
297  m._mtx[1][3],
298  m._mtx[2][0],
299  m._mtx[2][1],
300  m._mtx[2][2],
301  m._mtx[2][3],
302  m._mtx[3][0],
303  m._mtx[3][1],
304  m._mtx[3][2],
305  m._mtx[3][3]
306  );
307  }
308 
309  /// Tests for element-wise matrix equality. All elements must match
310  /// exactly for matrices to be considered equal.
311  GF_API
312  bool operator ==(const GfMatrix4d& m) const;
313 
314  /// Tests for element-wise matrix equality. All elements must match
315  /// exactly for matrices to be considered equal.
316  GF_API
317  bool operator ==(const GfMatrix4f& m) const;
318 
319  /// Tests for element-wise matrix inequality. All elements must match
320  /// exactly for matrices to be considered equal.
321  bool operator !=(const GfMatrix4d& m) const {
322  return !(*this == m);
323  }
324 
325  /// Tests for element-wise matrix inequality. All elements must match
326  /// exactly for matrices to be considered equal.
327  bool operator !=(const GfMatrix4f& m) const {
328  return !(*this == m);
329  }
330 
331  /// Returns the transpose of the matrix.
332  GF_API
333  GfMatrix4f GetTranspose() const;
334 
335  /// Returns the inverse of the matrix, or FLT_MAX * SetIdentity() if the
336  /// matrix is singular. (FLT_MAX is the largest value a \c float can have,
337  /// as defined by the system.) The matrix is considered singular if the
338  /// determinant is less than or equal to the optional parameter \e eps. If
339  /// \e det is non-null, <c>*det</c> is set to the determinant.
340  GF_API
341  GfMatrix4f GetInverse(double* det = NULL, double eps = 0) const;
342 
343  /// Returns the determinant of the matrix.
344  GF_API
345  double GetDeterminant() const;
346 
347  /// Sets a row of the matrix from a Vec3.
348  /// The fourth element of the row is ignored.
349  void SetRow3(int i, const GfVec3f & v) {
350  _mtx[i][0] = v[0];
351  _mtx[i][1] = v[1];
352  _mtx[i][2] = v[2];
353  }
354 
355  /// Gets a row of the matrix as a Vec3.
356  GfVec3f GetRow3(int i) const {
357  return GfVec3f(_mtx[i][0], _mtx[i][1], _mtx[i][2]);
358  }
359 
360  /// Returns the determinant of the upper 3x3 matrix. This method is useful
361  /// when the matrix describes a linear transformation such as a rotation or
362  /// scale because the other values in the 4x4 matrix are not important.
363  double GetDeterminant3() const {
364  return _GetDeterminant3(0, 1, 2, 0, 1, 2);
365  }
366 
367  /// Returns true, if the row vectors of the upper 3x3 matrix form an
368  /// orthogonal basis. Note they do not have to be unit length for this
369  /// test to return true.
370  bool HasOrthogonalRows3() const {
371  // XXX Should add GfAreOrthogonal(v0, v1, v2) (which also
372  // GfRotation::Decompose() could use).
373  GfVec3f axis0(GetRow3(0)), axis1(GetRow3(1)), axis2(GetRow3(2));
374  return (GfAbs(GfDot(axis0, axis1)) < GF_MIN_ORTHO_TOLERANCE &&
375  GfAbs(GfDot(axis0, axis2)) < GF_MIN_ORTHO_TOLERANCE &&
376  GfAbs(GfDot(axis1, axis2)) < GF_MIN_ORTHO_TOLERANCE);
377  }
378 
379  /// Makes the matrix orthonormal in place. This is an iterative method
380  /// that is much more stable than the previous cross/cross method. If the
381  /// iterative method does not converge, a warning is issued.
382  ///
383  /// Returns true if the iteration converged, false otherwise. Leaves any
384  /// translation part of the matrix unchanged. If \a issueWarning is true,
385  /// this method will issue a warning if the iteration does not converge,
386  /// otherwise it will be silent.
387  GF_API
388  bool Orthonormalize(bool issueWarning=true);
389 
390  /// Returns an orthonormalized copy of the matrix.
391  GF_API
392  GfMatrix4f GetOrthonormalized(bool issueWarning=true) const;
393 
394  /// Returns the sign of the determinant of the upper 3x3 matrix, i.e. 1
395  /// for a right-handed matrix, -1 for a left-handed matrix, and 0 for a
396  /// singular matrix.
397  GF_API
398  double GetHandedness() const;
399 
400  /// Returns true if the vectors in the upper 3x3 matrix form a
401  /// right-handed coordinate system.
402  bool IsRightHanded() const {
403  return GetHandedness() == 1.0;
404  }
405 
406  /// Returns true if the vectors in the upper 3x3 matrix form a left-handed
407  /// coordinate system.
408  bool IsLeftHanded() const {
409  return GetHandedness() == -1.0;
410  }
411 
412  /// Post-multiplies matrix \e m into this matrix.
413  GF_API
414  GfMatrix4f& operator *=(const GfMatrix4f& m);
415 
416  /// Multiplies the matrix by a float.
417  GF_API
418  GfMatrix4f& operator *=(double);
419 
420  /// Returns the product of a matrix and a float.
421  friend GfMatrix4f operator *(const GfMatrix4f& m1, double d)
422  {
423  GfMatrix4f m = m1;
424  return m *= d;
425  }
426 
427  ///
428  // Returns the product of a matrix and a float.
429  friend GfMatrix4f operator *(double d, const GfMatrix4f& m)
430  {
431  return m * d;
432  }
433 
434  /// Adds matrix \e m to this matrix.
435  GF_API
436  GfMatrix4f& operator +=(const GfMatrix4f& m);
437 
438  /// Subtracts matrix \e m from this matrix.
439  GF_API
440  GfMatrix4f& operator -=(const GfMatrix4f& m);
441 
442  /// Returns the unary negation of matrix \e m.
443  GF_API
444  friend GfMatrix4f operator -(const GfMatrix4f& m);
445 
446  /// Adds matrix \e m2 to \e m1
447  friend GfMatrix4f operator +(const GfMatrix4f& m1, const GfMatrix4f& m2)
448  {
449  GfMatrix4f tmp(m1);
450  tmp += m2;
451  return tmp;
452  }
453 
454  /// Subtracts matrix \e m2 from \e m1.
455  friend GfMatrix4f operator -(const GfMatrix4f& m1, const GfMatrix4f& m2)
456  {
457  GfMatrix4f tmp(m1);
458  tmp -= m2;
459  return tmp;
460  }
461 
462  /// Multiplies matrix \e m1 by \e m2.
463  friend GfMatrix4f operator *(const GfMatrix4f& m1, const GfMatrix4f& m2)
464  {
465  GfMatrix4f tmp(m1);
466  tmp *= m2;
467  return tmp;
468  }
469 
470  /// Divides matrix \e m1 by \e m2 (that is, <c>m1 * inv(m2)</c>).
471  friend GfMatrix4f operator /(const GfMatrix4f& m1, const GfMatrix4f& m2)
472  {
473  return(m1 * m2.GetInverse());
474  }
475 
476  /// Returns the product of a matrix \e m and a column vector \e vec.
477  friend inline GfVec4f operator *(const GfMatrix4f& m, const GfVec4f& vec) {
478  return GfVec4f(vec[0] * m._mtx[0][0] + vec[1] * m._mtx[0][1] + vec[2] * m._mtx[0][2] + vec[3] * m._mtx[0][3],
479  vec[0] * m._mtx[1][0] + vec[1] * m._mtx[1][1] + vec[2] * m._mtx[1][2] + vec[3] * m._mtx[1][3],
480  vec[0] * m._mtx[2][0] + vec[1] * m._mtx[2][1] + vec[2] * m._mtx[2][2] + vec[3] * m._mtx[2][3],
481  vec[0] * m._mtx[3][0] + vec[1] * m._mtx[3][1] + vec[2] * m._mtx[3][2] + vec[3] * m._mtx[3][3]);
482  }
483 
484  /// Returns the product of row vector \e vec and a matrix \e m.
485  friend inline GfVec4f operator *(const GfVec4f &vec, const GfMatrix4f& m) {
486  return GfVec4f(vec[0] * m._mtx[0][0] + vec[1] * m._mtx[1][0] + vec[2] * m._mtx[2][0] + vec[3] * m._mtx[3][0],
487  vec[0] * m._mtx[0][1] + vec[1] * m._mtx[1][1] + vec[2] * m._mtx[2][1] + vec[3] * m._mtx[3][1],
488  vec[0] * m._mtx[0][2] + vec[1] * m._mtx[1][2] + vec[2] * m._mtx[2][2] + vec[3] * m._mtx[3][2],
489  vec[0] * m._mtx[0][3] + vec[1] * m._mtx[1][3] + vec[2] * m._mtx[2][3] + vec[3] * m._mtx[3][3]);
490  }
491 
492  /// Sets matrix to specify a uniform scaling by \e scaleFactor.
493  GF_API
494  GfMatrix4f& SetScale(float scaleFactor);
495 
496  /// Returns the matrix with any scaling or shearing removed,
497  /// leaving only the rotation and translation.
498  /// If the matrix cannot be decomposed, returns the original matrix.
499  GF_API
501 
502  /// \name 3D Transformation Utilities
503  /// @{
504 
505  /// Sets the matrix to specify a rotation equivalent to \e rot,
506  /// and clears the translation.
507  GF_API
508  GfMatrix4f& SetRotate(const GfQuatf &rot);
509 
510  /// Sets the matrix to specify a rotation equivalent to \e rot,
511  /// without clearing the translation.
512  GF_API
514 
515  /// Sets the matrix to specify a rotation equivalent to \e rot,
516  /// and clears the translation.
517  GF_API
519 
520  /// Sets the matrix to specify a rotation equivalent to \e rot,
521  /// without clearing the translation.
522  GF_API
524 
525  /// Sets the matrix to specify a rotation equivalent to \e mx,
526  /// and clears the translation.
527  GF_API
528  GfMatrix4f& SetRotate(const GfMatrix3f &mx);
529 
530  /// Sets the matrix to specify a rotation equivalent to \e mx,
531  /// without clearing the translation.
532  GF_API
533  GfMatrix4f& SetRotateOnly(const GfMatrix3f &mx);
534 
535  /// Sets the matrix to specify a nonuniform scaling in x, y, and z by
536  /// the factors in vector \e scaleFactors.
537  GF_API
538  GfMatrix4f& SetScale(const GfVec3f &scaleFactors);
539 
540  /// Sets matrix to specify a translation by the vector \e trans,
541  /// and clears the rotation.
542  GF_API
544 
545  /// Sets matrix to specify a translation by the vector \e trans,
546  /// without clearing the rotation.
547  GF_API
549 
550  /// Sets matrix to specify a rotation by \e rotate and a
551  /// translation by \e translate.
552  GF_API
554  const GfVec3f& translate);
555 
556  /// Sets matrix to specify a rotation by \e rotmx and a
557  /// translation by \e translate.
558  GF_API
559  GfMatrix4f& SetTransform(const GfMatrix3f& rotmx,
560  const GfVec3f& translate);
561 
562  /// Sets the matrix to specify a viewing matrix from parameters
563  /// similar to those used by <c>gluLookAt(3G)</c>. \e eyePoint
564  /// represents the eye point in world space. \e centerPoint
565  /// represents the world-space center of attention. \e upDirection
566  /// is a vector indicating which way is up.
567  GF_API
568  GfMatrix4f& SetLookAt(const GfVec3f &eyePoint,
569  const GfVec3f &centerPoint,
570  const GfVec3f &upDirection);
571 
572  /// Sets the matrix to specify a viewing matrix from a world-space
573  /// \e eyePoint and a world-space rotation that rigidly rotates the
574  /// orientation from its canonical frame, which is defined to be
575  /// looking along the <c>-z</c> axis with the <c>+y</c> axis as the up
576  /// direction.
577  GF_API
578  GfMatrix4f& SetLookAt(const GfVec3f &eyePoint,
579  const GfRotation &orientation);
580 
581  /// Factors the matrix into 5 components:
582  /// \li <c>\e M = r * s * -r * u * t</c>
583  /// where
584  /// \li \e t is a translation.
585  /// \li \e u and \e r are rotations, and \e -r is the transpose
586  /// (inverse) of \e r. The \e u matrix may contain shear
587  /// information.
588  /// \li \e s is a scale.
589  /// Any projection information could be returned in matrix \e p,
590  /// but currently p is never modified.
591  ///
592  /// Returns \c false if the matrix is singular (as determined by \e eps).
593  /// In that case, any zero scales in \e s are clamped to \e eps
594  /// to allow computation of \e u.
595  GF_API
596  bool Factor(GfMatrix4f* r, GfVec3f* s, GfMatrix4f* u,
597  GfVec3f* t, GfMatrix4f* p,
598  float eps = 1e-5) const;
599 
600  /// Returns the translation part of the matrix, defined as the first three
601  /// elements of the last row.
603  return GfVec3f(_mtx[3][0], _mtx[3][1], _mtx[3][2]);
604  }
605 
606  /// Returns the rotation corresponding to this matrix. This works well
607  /// only if the matrix represents a rotation.
608  ///
609  /// For good results, consider calling Orthonormalize() before calling
610  /// this method.
611  GF_API
612  GfRotation ExtractRotation() const;
613 
614  /// Return the rotation corresponding to this matrix as a quaternion.
615  /// This works well only if the matrix represents a rotation.
616  ///
617  /// For good results, consider calling Orthonormalize() before calling
618  /// this method.
619  GF_API
621 
622  /// Decompose the rotation corresponding to this matrix about 3 orthogonal
623  /// axes. If the axes are not orthogonal, warnings will be spewed.
624  ///
625  /// This is a convenience method that is equivalent to calling
626  /// ExtractRotation().Decompose().
627  GF_API
628  GfVec3f DecomposeRotation(const GfVec3f &axis0,
629  const GfVec3f &axis1,
630  const GfVec3f &axis2) const;
631 
632  /// Returns the rotation corresponding to this matrix. This works well
633  /// only if the matrix represents a rotation.
634  ///
635  /// For good results, consider calling Orthonormalize() before calling
636  /// this method.
637  GF_API
639 
640  /// Transforms the row vector \e vec by the matrix, returning the result.
641  /// This treats the vector as a 4-component vector whose fourth component
642  /// is 1.
643  GfVec3d Transform(const GfVec3d &vec) const {
644  return GfProject(GfVec4d(
645  vec[0] * _mtx[0][0] + vec[1] * _mtx[1][0] + vec[2] * _mtx[2][0] + _mtx[3][0],
646  vec[0] * _mtx[0][1] + vec[1] * _mtx[1][1] + vec[2] * _mtx[2][1] + _mtx[3][1],
647  vec[0] * _mtx[0][2] + vec[1] * _mtx[1][2] + vec[2] * _mtx[2][2] + _mtx[3][2],
648  vec[0] * _mtx[0][3] + vec[1] * _mtx[1][3] + vec[2] * _mtx[2][3] + _mtx[3][3]));
649  }
650 
651  /// Transforms the row vector \e vec by the matrix, returning the result.
652  /// This treats the vector as a 4-component vector whose fourth component
653  /// is 1. This is an overloaded method; it differs from the other version
654  /// in that it returns a different value type.
655  GfVec3f Transform(const GfVec3f &vec) const {
656  return (GfProject(GfVec4f(
657  vec[0] * _mtx[0][0] + vec[1] * _mtx[1][0] + vec[2] * _mtx[2][0] + _mtx[3][0],
658  vec[0] * _mtx[0][1] + vec[1] * _mtx[1][1] + vec[2] * _mtx[2][1] + _mtx[3][1],
659  vec[0] * _mtx[0][2] + vec[1] * _mtx[1][2] + vec[2] * _mtx[2][2] + _mtx[3][2],
660  vec[0] * _mtx[0][3] + vec[1] * _mtx[1][3] + vec[2] * _mtx[2][3] + _mtx[3][3])));
661  }
662 
663  /// Transforms row vector \e vec by the matrix, returning the result. This
664  /// treats the vector as a direction vector, so the translation
665  /// information in the matrix is ignored. That is, it treats the vector as
666  /// a 4-component vector whose fourth component is 0.
667  GfVec3d TransformDir(const GfVec3d &vec) const {
668  return GfVec3d(
669  vec[0] * _mtx[0][0] + vec[1] * _mtx[1][0] + vec[2] * _mtx[2][0],
670  vec[0] * _mtx[0][1] + vec[1] * _mtx[1][1] + vec[2] * _mtx[2][1],
671  vec[0] * _mtx[0][2] + vec[1] * _mtx[1][2] + vec[2] * _mtx[2][2]);
672  }
673 
674  /// Transforms row vector \e vec by the matrix, returning the result. This
675  /// treats the vector as a direction vector, so the translation
676  /// information in the matrix is ignored. That is, it treats the vector as
677  /// a 4-component vector whose fourth component is 0. This is an
678  /// overloaded method; it differs from the other version in that it
679  /// returns a different value type.
680  GfVec3f TransformDir(const GfVec3f &vec) const {
681  return GfVec3f(
682  vec[0] * _mtx[0][0] + vec[1] * _mtx[1][0] + vec[2] * _mtx[2][0],
683  vec[0] * _mtx[0][1] + vec[1] * _mtx[1][1] + vec[2] * _mtx[2][1],
684  vec[0] * _mtx[0][2] + vec[1] * _mtx[1][2] + vec[2] * _mtx[2][2]);
685  }
686 
687  /// Transforms the row vector \e vec by the matrix, returning the result.
688  /// This treats the vector as a 4-component vector whose fourth component
689  /// is 1 and ignores the fourth column of the matrix (i.e. assumes it is
690  /// (0, 0, 0, 1)).
691  GfVec3d TransformAffine(const GfVec3d &vec) const {
692  return GfVec3d(
693  vec[0] * _mtx[0][0] + vec[1] * _mtx[1][0] + vec[2] * _mtx[2][0] + _mtx[3][0],
694  vec[0] * _mtx[0][1] + vec[1] * _mtx[1][1] + vec[2] * _mtx[2][1] + _mtx[3][1],
695  vec[0] * _mtx[0][2] + vec[1] * _mtx[1][2] + vec[2] * _mtx[2][2] + _mtx[3][2]);
696  }
697 
698  /// Transforms the row vector \e vec by the matrix, returning the result.
699  /// This treats the vector as a 4-component vector whose fourth component
700  /// is 1 and ignores the fourth column of the matrix (i.e. assumes it is
701  /// (0, 0, 0, 1)).
702  GfVec3f TransformAffine(const GfVec3f &vec) const {
703  return GfVec3f(
704  vec[0] * _mtx[0][0] + vec[1] * _mtx[1][0] + vec[2] * _mtx[2][0] + _mtx[3][0],
705  vec[0] * _mtx[0][1] + vec[1] * _mtx[1][1] + vec[2] * _mtx[2][1] + _mtx[3][1],
706  vec[0] * _mtx[0][2] + vec[1] * _mtx[1][2] + vec[2] * _mtx[2][2] + _mtx[3][2]);
707  }
708  /// @}
709 
710 private:
711  /// Returns the determinant of the 3x3 submatrix specified by the three
712  /// given row and column indices (0-3 for each).
713  GF_API
714  double _GetDeterminant3(size_t row1, size_t row2, size_t row3,
715  size_t col1, size_t col2, size_t col3) const;
716 
717  /// Diagonalizes the upper 3x3 matrix of a matrix known to be symmetric.
718  void _Jacobi3(GfVec3d *eigenvalues, GfVec3d eigenvectors[3]) const;
719 
720  /// Set the 3x3 submatrix to the rotation given by a quaternion,
721  /// defined by the real component \p r and imaginary components \p i.
722  void _SetRotateFromQuat(float r, const GfVec3f& i);
723 
724 
725 private:
726  /// Matrix storage, in row-major order.
728 
729  // Friend declarations
730  friend class GfMatrix4d;
731 };
732 
733 
734 /// Tests for equality within a given tolerance, returning \c true if the
735 /// difference between each component of the matrix is less than or equal
736 /// to \p tolerance, or false otherwise.
737 GF_API
738 bool GfIsClose(GfMatrix4f const &m1, GfMatrix4f const &m2, double tolerance);
739 
740 /// Output a GfMatrix4f
741 /// \ingroup group_gf_DebuggingOutput
742 GF_API std::ostream& operator<<(std::ostream &, GfMatrix4f const &);
743 
745 
746 #endif // PXR_BASE_GF_MATRIX4F_H
bool HasOrthogonalRows3() const
Definition: matrix4f.h:370
GfVec3f GfProject(const GfVec4f &v)
Definition: homogeneous.h:48
GF_API GfVec3f DecomposeRotation(const GfVec3f &axis0, const GfVec3f &axis1, const GfVec3f &axis2) const
GfVec4f GetRow(int i) const
Gets a row of the matrix as a Vec4.
Definition: matrix4f.h:187
GF_API std::ostream & operator<<(std::ostream &, GfMatrix4f const &)
GfVec3f TransformDir(const GfVec3f &vec) const
Definition: matrix4f.h:680
GF_API friend GfMatrix4f operator-(const GfMatrix4f &m)
Returns the unary negation of matrix m.
static const size_t numRows
Definition: matrix4f.h:75
GF_API GfMatrix4f & operator*=(const GfMatrix4f &m)
Post-multiplies matrix m into this matrix.
GF_API GfMatrix4f & SetDiagonal(float s)
Sets the matrix to s times the identity matrix.
friend GfMatrix4f operator+(const GfMatrix4f &m1, const GfMatrix4f &m2)
Adds matrix m2 to m1.
Definition: matrix4f.h:447
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
Definition: thread.h:632
bool IsLeftHanded() const
Definition: matrix4f.h:408
GF_API GfMatrix4f & operator+=(const GfMatrix4f &m)
Adds matrix m to this matrix.
float * data()
Definition: matrix4f.h:257
const GLdouble * v
Definition: glcorearb.h:837
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
GLsizei const GLfloat * value
Definition: glcorearb.h:824
GF_API GfMatrix4f & SetRotate(const GfQuatf &rot)
GA_API const UT_StringHolder rot
GF_API GfMatrix4f & SetRotateOnly(const GfQuatf &rot)
Definition: vec3f.h:45
GLdouble s
Definition: glad.h:3009
Definition: vec4d.h:45
GfVec3d TransformDir(const GfVec3d &vec) const
Definition: matrix4f.h:667
GfVec4f GetColumn(int i) const
Gets a column of the matrix as a Vec4.
Definition: matrix4f.h:192
GF_API GfQuatf ExtractRotationQuat() const
GF_API GfMatrix3f ExtractRotationMatrix() const
double GfAbs(double f)
Definition: math.h:222
Definition: quatf.h:42
GF_API GfMatrix4f & SetTranslateOnly(const GfVec3f &t)
void SetRow3(int i, const GfVec3f &v)
Definition: matrix4f.h:349
GF_API GfMatrix4f GetInverse(double *det=NULL, double eps=0) const
GF_API GfMatrix4f RemoveScaleShear() const
GF_API bool Orthonormalize(bool issueWarning=true)
void SetColumn(int i, const GfVec4f &v)
Sets a column of the matrix from a Vec4.
Definition: matrix4f.h:179
bool IsRightHanded() const
Definition: matrix4f.h:402
friend GfMatrix4f operator*(const GfMatrix4f &m1, double d)
Returns the product of a matrix and a float.
Definition: matrix4f.h:421
GF_API float * Get(float m[4][4]) const
GfMatrix4f & Set(float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33)
Definition: matrix4f.h:199
GF_API GfMatrix4f & SetScale(float scaleFactor)
Sets matrix to specify a uniform scaling by scaleFactor.
GF_API GfMatrix4f & SetTransform(const GfRotation &rotate, const GfVec3f &translate)
GfVec3d Transform(const GfVec3d &vec) const
Definition: matrix4f.h:643
double GetDeterminant3() const
Definition: matrix4f.h:363
T * GetData()
Return a pointer to the start of all the data.
Definition: matrixData.h:33
GA_API const UT_StringHolder trans
GfVec3f GetRow3(int i) const
Gets a row of the matrix as a Vec3.
Definition: matrix4f.h:356
friend size_t hash_value(GfMatrix4f const &m)
Hash.
Definition: matrix4f.h:288
GF_API double GetHandedness() const
GF_API bool Factor(GfMatrix4f *r, GfVec3f *s, GfMatrix4f *u, GfVec3f *t, GfMatrix4f *p, float eps=1e-5) const
float * operator[](int i)
Definition: matrix4f.h:280
GfMatrix4f & SetZero()
Sets the matrix to zero.
Definition: matrix4f.h:238
GF_API bool operator==(const GfMatrix4d &m) const
float ScalarType
Definition: matrix4f.h:73
double GfDot(const GfDualQuatd &dq1, const GfDualQuatd &dq2)
Return the dot (inner) product of two dual quaternions.
Definition: dualQuatd.h:261
ImageBuf OIIO_API rotate(const ImageBuf &src, float angle, string_view filtername=string_view(), float filterwidth=0.0f, bool recompute_roi=false, ROI roi={}, int nthreads=0)
GLdouble t
Definition: glad.h:2397
GfMatrix4f(const GfVec4f &v)
Definition: matrix4f.h:109
Definition: vec4f.h:45
GfMatrix4f & SetIdentity()
Sets the matrix to the identity matrix.
Definition: matrix4f.h:233
GF_API GfMatrix4f GetTranspose() const
Returns the transpose of the matrix.
GF_API GfMatrix4f & SetTranslate(const GfVec3f &trans)
GF_API GfMatrix4f & SetLookAt(const GfVec3f &eyePoint, const GfVec3f &centerPoint, const GfVec3f &upDirection)
static size_t Combine(Args &&...args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:487
GfMatrix4f & Set(const float m[4][4])
Definition: matrix4f.h:212
GfMatrix4f(const float m[4][4])
Definition: matrix4f.h:97
friend GfMatrix4f operator/(const GfMatrix4f &m1, const GfMatrix4f &m2)
Divides matrix m1 by m2 (that is, m1 * inv(m2)).
Definition: matrix4f.h:471
GF_API double GetDeterminant() const
Returns the determinant of the matrix.
GF_API bool GfIsClose(GfMatrix4f const &m1, GfMatrix4f const &m2, double tolerance)
GfVec3f ExtractTranslation() const
Definition: matrix4f.h:602
Definition: vec3d.h:45
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
GfMatrix4f()=default
GfVec3f TransformAffine(const GfVec3f &vec) const
Definition: matrix4f.h:702
GfMatrix4f(float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33)
Definition: matrix4f.h:85
GF_API GfRotation ExtractRotation() const
GfVec3f Transform(const GfVec3f &vec) const
Definition: matrix4f.h:655
GLboolean r
Definition: glcorearb.h:1222
PUGI__FN char_t * translate(char_t *buffer, const char_t *from, const char_t *to, size_t to_length)
Definition: pugixml.cpp:8574
static const size_t numColumns
Definition: matrix4f.h:76
GfMatrix4f(float s)
Definition: matrix4f.h:103
GF_API GfMatrix4f & operator-=(const GfMatrix4f &m)
Subtracts matrix m from this matrix.
GfVec3d TransformAffine(const GfVec3d &vec) const
Definition: matrix4f.h:691
void SetRow(int i, const GfVec4f &v)
Sets a row of the matrix from a Vec4.
Definition: matrix4f.h:171
GF_API GfMatrix4f GetOrthonormalized(bool issueWarning=true) const
Returns an orthonormalized copy of the matrix.
#define GF_MIN_ORTHO_TOLERANCE
Definition: limits.h:22
const float * data() const
Definition: matrix4f.h:263
#define GF_API
Definition: api.h:23
float * GetArray()
Returns vector components as an array of float values.
Definition: matrix4f.h:268
bool operator!=(const GfMatrix4d &m) const
Definition: matrix4f.h:321
const float * GetArray() const
Returns vector components as a const array of float values.
Definition: matrix4f.h:273