Ocean
HomogenousMatrix4.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_MATH_HOMOGENOUS_MATRIX_4_H
9 #define META_OCEAN_MATH_HOMOGENOUS_MATRIX_4_H
10 
11 #include "ocean/math/Math.h"
12 #include "ocean/math/Numeric.h"
13 #include "ocean/math/Quaternion.h"
14 #include "ocean/math/Rotation.h"
16 #include "ocean/math/Vector3.h"
17 #include "ocean/math/Vector4.h"
18 
19 #include <vector>
20 
21 namespace Ocean
22 {
23 
24 // Forward declaration.
25 template <typename T> class EulerT;
26 
27 // Forward declaration.
28 template <typename T> class RotationT;
29 
30 // Forward declaration.
31 template <typename T> class SquareMatrixT4;
32 
33 // Forward declaration.
34 template <typename T> class QuaternionT;
35 
36 // Forward declaration.
37 template <typename T> class HomogenousMatrixT4;
38 
39 /**
40  * Definition of the HomogenousMatrix4 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag either with single or double precision float data type.
41  * @see HomogenousMatrixT4
42  * @ingroup math
43  */
45 
46 /**
47  * Instantiation of the HomogenousMatrixT4 template class using a double precision float data type.
48  * @see HomogenousMatrixT4
49  * @ingroup math
50  */
52 
53 /**
54  * Instantiation of the HomogenousMatrixT4 template class using a float precision float data type.
55  * @see HomogenousMatrixT4
56  * @ingroup math
57  */
59 
60 /**
61  * Definition of a typename alias for vectors with HomogenousMatrixT4 objects.
62  * @see HomogenousMatrixT4
63  * @ingroup math
64  */
65 template <typename T>
66 using HomogenousMatricesT4 = std::vector<HomogenousMatrixT4<T>>;
67 
68 /**
69  * Definition of a vector holding HomogenousMatrix4 objects.
70  * @see HomogenousMatrix4
71  * @ingroup math
72  */
73 typedef std::vector<HomogenousMatrix4> HomogenousMatrices4;
74 
75 /**
76  * Definition of a vector holding HomogenousMatrixD4 objects.
77  * @ingroup math
78  */
79 typedef std::vector<HomogenousMatrixD4> HomogenousMatricesD4;
80 
81 /**
82  * Definition of a vector holding HomogenousMatrixF4 objects.
83  * @ingroup math
84  */
85 typedef std::vector<HomogenousMatrixF4> HomogenousMatricesF4;
86 
87 
88 /**
89  * This class implements a 4x4 homogeneous transformation matrix using floating point values with the precision specified by type T.
90  * <pre>
91  * The values are stored in a column major/aligned order with indices:
92  * | 0 4 8 12 |
93  * | 1 5 9 13 |
94  * | 2 6 10 14 |
95  * | 3 7 11 15 |
96  *
97  * This matrix allows homogeneous transformations only.
98  * With basis vectors (rx1, ry1, rz1), (rx2, ry2, rz2), (rx3, ry3, rz3), and translation vector (tx, ty, tz):
99  * | rx1 rx2 rx3 tx |
100  * | ry1 ry2 ry3 ty |
101  * | rz1 rz2 rz3 tz |
102  * | 0 0 0 1 |
103  * </pre>
104  * @tparam T Data type of matrix elements
105  * @see HomogenousMatrix4, HomogenousMatrixF4, HomogenousMatrixD4.
106  * @ingroup math
107  */
108 template <typename T>
110 {
111  template <typename U> friend class HomogenousMatrixT4;
112 
113  public:
114 
115  /**
116  * Definition of the used data type.
117  */
118  typedef T Type;
119 
120  public:
121 
122  /**
123  * Creates a new default HomogenousMatrixT4 object with undefined elements.
124  * Beware: This matrix is neither a zero nor an entity matrix!
125  */
127 
128  /**
129  * Copy constructor.
130  * @param matrix The matrix to copy
131  */
133 
134  /**
135  * Copy constructor for a matrix with difference element data type than T.
136  * @param matrix The matrix to copy
137  * @tparam U The element data type of the second matrix
138  */
139  template <typename U>
140  inline explicit HomogenousMatrixT4(const HomogenousMatrixT4<U>& matrix);
141 
142  /**
143  * Creates a new HomogenousMatrixT4.
144  * Beware: The zero matrix will hold a zero in the lower right corner which must be set explicitly later to create a valid matrix.<br>
145  * Only constructors explicitly set the lower right value to 1 like e.g., the constructor building a matrix from a rotation or translation and so on.
146  * @param setToIdentity True, to create a identity matrix; False, to set a zero matrix
147  */
148  inline explicit HomogenousMatrixT4(const bool setToIdentity);
149 
150  /**
151  * Creates a new HomogenousMatrixT4 object by 16 given floating point values of type U.
152  * @param arrayValues The array with 16 matrix elements of type U
153  */
154  template <typename U>
155  explicit HomogenousMatrixT4(const U* arrayValues);
156 
157  /**
158  * Creates a new HomogenousMatrixT4 object by 16 given floating point values.
159  * @param arrayValues The array with 16 matrix elements
160  */
161  explicit HomogenousMatrixT4(const T* arrayValues);
162 
163  /**
164  * Creates a new HomogenousMatrixT4 object by an array of at least sixteen elements of float type U.
165  * @param arrayValues The sixteen matrix elements defining the new matrix, must be valid
166  * @param valuesRowAligned True, if the given values are stored in a row aligned order; False, if the values are stored in a column aligned order (which is the default case for this matrix)
167  * @tparam U The floating point type of the given elements
168  */
169  template <typename U>
170  HomogenousMatrixT4(const U* arrayValues, const bool valuesRowAligned);
171 
172  /**
173  * Creates a new HomogenousMatrixT4 object by an array of at least sixteen elements.
174  * @param valuesRowAligned True, if the given values are stored in a row aligned order; False, if the values are stored in a column aligned order (which is the default case for this matrix)
175  * @param arrayValues The sixteen matrix elements defining the new matrix, must be valid
176  */
177  HomogenousMatrixT4(const T* arrayValues, const bool valuesRowAligned);
178 
179  /**
180  * Creates a new HomogenousMatrixT4 object with only a translation.
181  * @param translation The translation of the resulting transformation
182  */
184 
185  /**
186  * Creates a new HomogenousMatrixT4 object with only a rotation.
187  * @param rotation The angle-axis rotation of the resulting transformation
188  */
190 
191  /**
192  * Creates a new HomogenousMatrixT4 object with only a rotation given as Euler rotation.
193  * @param euler The euler rotation of the resulting transformation
194  */
195  explicit HomogenousMatrixT4(const EulerT<T>& euler);
196 
197  /**
198  * Creates a new HomogenousMatrixT4 object with only a rotation given as quaternion.
199  * @param rotation The rotation of the resulting transformation
200  */
202 
203  /**
204  * Creates a new HomogenousMatrixT4 object with only a rotation given as 3x3 rotation matrix.
205  * @param rotation 3x3 rotation matrix
206  */
208 
209  /**
210  * Creates a new HomogenousMatrixT4 object from a 4x4 square matrix.
211  * @param matrix The 4x4 square matrix
212  */
213  explicit HomogenousMatrixT4(const SquareMatrixT4<T>& matrix);
214 
215  /**
216  * Creates a new HomogenousMatrixT4 object with a translation and rotation.
217  * The resulting transformation can be written as the following matrix multiplication:
218  * <pre>
219  * HomogenousMatrix4(translation, rotation) == HomogenousMatrix4(translation) * HomogenousMatrix4(rotation)
220  * </pre>
221  * @param translation The translation of the resulting transformation
222  * @param rotation The rotation of the resulting transformation, must be valid
223  */
225 
226  /**
227  * Creates a new HomogenousMatrixT4 object with a translation and rotation.
228  * @param translationAndRotation The pair of translation and rotation of the resulting transformation
229  */
230  explicit HomogenousMatrixT4(const std::pair<VectorT3<T>, RotationT<T>>& translationAndRotation);
231 
232  /**
233  * Creates a new HomogenousMatrixT4 object with a translation and rotation.
234  * The resulting transformation can be written as the following matrix multiplication:
235  * <pre>
236  * HomogenousMatrix4(translation, euler) == HomogenousMatrix4(translation) * HomogenousMatrix4(euler)
237  * </pre>
238  * @param translation The translation of the resulting transformation
239  * @param euler The euler rotation of the resulting transformation, must be valid
240  */
242 
243  /**
244  * Creates a new HomogenousMatrixT4 object with a translation and rotation.
245  * The resulting transformation can be written as the following matrix multiplication:
246  * <pre>
247  * HomogenousMatrix4(translation, rotation) == HomogenousMatrix4(translation) * HomogenousMatrix4(rotation)
248  * </pre>
249  * @param translation The translation of the resulting transformation
250  * @param rotation The quaternion rotation of the resulting transformation, must be valid
251  */
253 
254  /**
255  * Creates a new HomogenousMatrixT4 object with a translation and rotation.
256  * @param translationAndRotation The pair of translation and rotation of the resulting transformation
257  */
258  explicit HomogenousMatrixT4(const std::pair<VectorT3<T>, QuaternionT<T>>& translationAndRotation);
259 
260  /**
261  * Creates a new HomogenousMatrixT4 object with a translation and rotation matrix.
262  * The resulting transformation can be written as the following matrix multiplication:
263  * <pre>
264  * HomogenousMatrix4(translation, rotation) == HomogenousMatrix4(translation) * HomogenousMatrix4(rotation)
265  * </pre>
266  * @param translation The translation of the resulting transformation
267  * @param rotation The rotation matrix of the resulting transformation, must be valid
268  */
270 
271  /**
272  * Creates a new HomogenousMatrixT4 object by a translation and a scale.
273  * @param translation The translation of the resulting transformation
274  * @param scale The scale of the resulting transformation
275  */
277 
278  /**
279  * Creates a new HomogenousMatrixT4 object by a translation, rotation and scale.
280  * @param translation The translation of the resulting transformation
281  * @param rotation The rotation of the resulting transformation, must be valid
282  * @param scale The scale of the resulting transformation
283  */
285 
286  /**
287  * Creates a new HomogenousMatrixT4 object by a translation, rotation, scale and shear.
288  * @param translation The translation of the resulting transformation
289  * @param rotation The rotation of the resulting transformation as unit quaternion, must be valid
290  * @param scale The scale of the resulting transformation
291  * @param shear The shear of the resulting transformation with order (xy, xz, yz)
292  */
294 
295  /**
296  * Creates a new HomogenousMatrixT4 object by a translation, rotation, scale and shear.
297  * @param translation The translation of the resulting transformation
298  * @param rotation The rotation of the resulting transformation, must be valid
299  * @param scale The scale of the resulting transformation
300  * @param shear The shear of the resulting transformation with order (xy, xz, yz)
301  */
303 
304  /**
305  * Creates a new HomogenousMatrixT4 object by a translation, rotation and scale.
306  * @param translation The translation of the resulting transformation
307  * @param rotation The quaternion rotation of the resulting transformation, must be valid
308  * @param scale The scale of the resulting transformation
309  */
311 
312  /**
313  * Creates a new HomogenousMatrixT4 object by three basis vectors.
314  * @param xAxis First basis vector
315  * @param yAxis Second basis vector
316  * @param zAxis Third basis vector
317  */
319 
320  /**
321  * Creates a new HomogenousMatrixT4 object by three basis vectors and a translation vector.
322  * @param xAxis First basis vector
323  * @param yAxis Second basis vector
324  * @param zAxis Third basis vector
325  * @param translation The translation vector
326  */
328 
329  /**
330  * Returns the x-axis of the transformation which is the first vector of the upper left 3x3 rotation matrix of this homogeneous 4x4 transformation.
331  * @return The x-axis of this transformation
332  */
333  inline VectorT3<T> xAxis() const;
334 
335  /**
336  * Returns the y-axis of the transformation which is the second vector of the upper left 3x3 rotation matrix of this homogeneous 4x4 transformation.
337  * @return The y-axis of this transformation
338  */
339  inline VectorT3<T> yAxis() const;
340 
341  /**
342  * Returns the z-axis of the transformation which is the first vector of the upper left 3x3 rotation matrix of this homogeneous 4x4 transformation.
343  * @return The z-axis of this transformation
344  */
345  inline VectorT3<T> zAxis() const;
346 
347  /**
348  * Returns the translation of the transformation.
349  * @return Translation
350  */
351  inline VectorT3<T> translation() const;
352 
353  /**
354  * Returns the rotation of the transformation as quaternion.
355  * @return Rotation
356  */
358 
359  /**
360  * Returns the scale of the transformation.
361  * @return Transformation scale
362  */
364 
365  /**
366  * Decomposes the transformation matrix into translation, rotation, scale and shear parameters.
367  * @param translation The returning translation parameter
368  * @param rotation The returning rotation parameter as quaternion
369  * @param scale The returning scale parameter
370  * @param shear The returning shear parameter with order (xy, xz, yz)
371  * @return True, if succeeded (otherwise the transformation matrix has a zero-scaling axis and the translation is decomposed only)
372  */
374 
375  /**
376  * Returns the rotation matrix of the transformation.
377  * @return Rotation matrix containing scale
378  */
380 
381  /**
382  * Copies the 3x3 rotation matrix elements of the 4x4 transformation.
383  * @param data The buffer receiving the nine rotation matrix elements, must be valid
384  * @param transposed True, to copy the transposed rotation matrix (to copy the array into a row major buffer); False, to copy the matrix into a column major buffer
385  */
386  inline void rotationMatrix(T* data, const bool transposed = false) const;
387 
388  /**
389  * Returns the 3x3 orthonormal rotation matrix of the 4x4 transformation (by forcing a orthogonal and normalized rotation matrix).
390  * All vectors of the resulting rotation matrix have unit length.
391  * @return The normalized rotation matrix
392  */
394 
395  /**
396  * Returns the transposed of this matrix.
397  * @return Transposed matrix as square 4x4 matrix
398  */
400 
401  /**
402  * Returns the inverted of this matrix.
403  * This matrix must not be singular, ensure that the matrix is invertible before calling this function.<br>
404  * Even better: avoid the usage of this function and call invert() instead.<br>
405  * In case, this matrix is not invertible, this matrix will be returned instead.
406  * @return The inverted matrix
407  * see invert().
408  */
409  HomogenousMatrixT4<T> inverted() const noexcept;
410 
411  /**
412  * Inverts the matrix.
413  * @return True, if the matrix could be inverted (because the matrix was not singular)
414  */
415  bool invert();
416 
417  /**
418  * Inverts the matrix and returns the result as parameter.
419  * @param invertedMatrix The resulting inverted matrix
420  * @return True, if the matrix could be inverted because the matrix is not singular
421  * @see inverted(), solve().
422  */
423  bool invert(HomogenousMatrixT4<T>& invertedMatrix) const;
424 
425  /**
426  * Returns the determinant of the matrix.
427  * @return Matrix determinant
428  */
429  T determinant() const;
430 
431  /**
432  * Returns the trace of the matrix which is the sum of the diagonal elements.
433  * @return Trace of the matrix
434  */
435  inline T trace() const;
436 
437  /**
438  * Sets the translation of this transformation.
439  * @param translation The translation to set
440  * @return Reference to this transformation matrix
441  */
443 
444  /**
445  * Sets the rotation of this transformation.
446  * @param rotation The rotation to set, must be valid
447  * @return Reference to this transformation matrix
448  */
450 
451  /**
452  * Sets the rotation of this transformation.
453  * @param quaternion The quaternion rotation to set, must be valid
454  * @return Reference to this transformation matrix
455  */
456  HomogenousMatrixT4<T>& setRotation(const QuaternionT<T>& quaternion);
457 
458  /**
459  * Sets the rotation of this transformation.
460  * @param matrix The 3x3 rotation matrix to set
461  * @return Reference to this transformation matrix
462  */
464 
465  /**
466  * Applies new scale values.
467  * @param scale The new scale values which are applied to the inner 3x3 rotation matrix
468  * @return Reference to this transformation matrix
469  */
471 
472  /**
473  * Sets the matrix to the identity matrix.
474  * @see isIdentity().
475  */
476  inline void toIdentity();
477 
478  /**
479  * Sets the matrix to a zero matrix (including the lower right element).
480  * @see isNull();
481  */
482  inline void toNull();
483 
484  /**
485  * Returns whether this matrix is a valid homogeneous transformation.
486  * @return True, if so
487  */
488  bool isValid() const;
489 
490  /**
491  * Returns whether this matrix is an identity matrix.
492  * @return True, if so
493  * @see toIdentity().
494  */
495  bool isIdentity() const;
496 
497  /**
498  * Returns whether two matrices are almost identical up to a specified epsilon.
499  * @param matrix Second matrix that will be checked
500  * @param epsilon The epsilon threshold to be used, with range [0, infinity)
501  * @return True, if so
502  */
503  inline bool isEqual(const HomogenousMatrixT4<T>& matrix, const T epsilon = NumericT<T>::eps()) const;
504 
505  /**
506  * Returns whether this matrix is a zero matrix (with all elements equal to zero).
507  * @return True, if so
508  * @see toNull().
509  */
510  bool isNull() const;
511 
512  /**
513  * Returns a pointer to the internal values.
514  * @return The pointer to the internal values, always valid
515  */
516  inline const T* data() const;
517 
518  /**
519  * Returns a pointer to the internal values.
520  * @return The pointer to the internal values, always valid
521  */
522  inline T* data();
523 
524  /**
525  * Copies the elements of this matrix to an array with floating point values of the same type T.
526  * @param arrayValues Array with 16 floating point values of type T receiving the elements of this matrix, must be valid
527  * @param valuesRowAligned True, if the target values are stored in a row aligned order; False, if the values are stored in a column aligned order (which is the default case for this matrix)
528  */
529  inline void copyElements(T* arrayValues, const bool valuesRowAligned = false) const;
530 
531  /**
532  * Copies the elements of this matrix to an array with floating point values of the type U.
533  * @param arrayValues Array with 16 floating point values of type U receiving the elements of this matrix, must be valid
534  * @param valuesRowAligned True, if the target values are stored in a row aligned order; False, if the values are stored in a column aligned order (which is the default case for this matrix)
535  */
536  template <typename U>
537  inline void copyElements(U* arrayValues, const bool valuesRowAligned = false) const;
538 
539  /**
540  * Transforms a 3D vector by application of only the inner rotation matrix (including scale and shearing) of this transformation.
541  * @param vector The vector to be transformed
542  * @return Transformed 3D vector
543  */
544  inline VectorT3<T> rotationMatrix(const VectorT3<T>& vector) const;
545 
546  /**
547  * Transforms a 3D vector by application of only the inner transposed rotation matrix (including scale and shearing) of this transformation.
548  * @param vector The vector to be transformed
549  * @return Transformed 3D vector
550  */
551  inline VectorT3<T> transposedRotationMatrix(const VectorT3<T>& vector) const;
552 
553  /**
554  * Default copy assignment operator.
555  * @return Reference to this object
556  */
557  HomogenousMatrixT4<T>& operator=(const HomogenousMatrixT4<T>&) = default;
558 
559  /**
560  * Returns whether two transformations are identical up to a small epsilon.
561  * @param matrix Right operand
562  * @return True, if so
563  */
564  bool operator==(const HomogenousMatrixT4<T>& matrix) const;
565 
566  /**
567  * Returns whether two transformations are not identical up to a small epsilon.
568  * @param matrix Right operand
569  * @return True, if so
570  */
571  inline bool operator!=(const HomogenousMatrixT4<T>& matrix) const;
572 
573  /**
574  * Combines two transformation matrices.
575  * @param matrix Right transformation matrix
576  * @return Combined transformation matrix
577  */
578  HomogenousMatrixT4<T> operator*(const HomogenousMatrixT4<T>& matrix) const;
579 
580  /**
581  * Combines and assigns two transformation matrices.
582  * @param matrix Right transformation matrix
583  * @return Reference to this transformation matrix
584  */
585  inline HomogenousMatrixT4<T>& operator*=(const HomogenousMatrixT4<T>& matrix);
586 
587  /**
588  * Combines a transformation with a rotation.
589  * @param rotation The rotation to combine, must be valid
590  * @return Combined transformation matrix
591  */
592  HomogenousMatrixT4<T> operator*(const RotationT<T>& rotation) const;
593 
594  /**
595  * Combines and assigns a transformation with a rotation.
596  * @param rotation The rotation to combine, must be valid
597  * @return Reference to this transformation matrix
598  */
599  inline HomogenousMatrixT4<T>& operator*=(const RotationT<T>& rotation);
600 
601  /**
602  * Combines a transformation with a quaternion rotation.
603  * @param rotation The quaternion rotation to combine, must be valid
604  * @return Combined transformation matrix
605  */
606  HomogenousMatrixT4<T> operator*(const QuaternionT<T>& rotation) const;
607 
608  /**
609  * Combines and assigns a transformation with a quaternion rotation.
610  * @param rotation The quaternion rotation to combine, must be valid
611  * @return Reference to this transformation matrix
612  */
613  inline HomogenousMatrixT4<T>& operator*=(const QuaternionT<T>& rotation);
614 
615  /**
616  * Transforms a 3D vector.
617  * The vector will be extended with a 1.0 as fourth element and de-homogenized afterwards.
618  * @param vector The vector to transform
619  * @return Resulting transformed and homogenized 3D vector
620  */
621  inline VectorT3<T> operator*(const VectorT3<T>& vector) const;
622 
623  /**
624  * Transforms a 4D vector.
625  * @param vector The vector to transform
626  * @return The resulting transformed 4D vector
627  */
628  inline VectorT4<T> operator*(const VectorT4<T>& vector) const;
629 
630  /**
631  * Element operator.
632  * @param index The index of the element to return [0, 15]
633  * @return Specified element
634  */
635  inline T operator[](const unsigned int index) const;
636 
637  /**
638  * Element operator.
639  * @param index The index of the element to return [0, 15]
640  * @return Specified element
641  */
642  inline T& operator[](const unsigned int index);
643 
644  /**
645  * Element operator.
646  * @param row The row of the element to return [0, 3]
647  * @param column The column of the element to return [0, 3]
648  * @return Specified element
649  */
650  inline T operator()(const unsigned int row, const unsigned int column) const;
651 
652  /**
653  * Element operator.
654  * @param row The row of the element to return [0, 3]
655  * @param column The column of the element to return [0, 3]
656  * @return Specified element
657  */
658  inline T& operator()(const unsigned int row, const unsigned int column);
659 
660  /**
661  * Element operator.
662  * @param index The index of the element to return [0, 15]
663  * @return Specified element
664  */
665  inline T operator()(const unsigned int index) const;
666 
667  /**
668  * Element operator.
669  * @param index The index of the element to return [0, 15]
670  * @return Specified element
671  */
672  inline T& operator()(const unsigned int index);
673 
674  /**
675  * Access operator.
676  * @return Pointer to the internal values
677  */
678  inline const T* operator()() const;
679 
680  /**
681  * Access operator.
682  * @return Pointer to the internal values
683  */
684  inline T* operator()();
685 
686  /**
687  * Hash function.
688  * @param matrix The matrix for which the hash value will be determined
689  * @return The resulting hash value
690  */
691  inline size_t operator()(const HomogenousMatrixT4<T>& matrix) const;
692 
693  /**
694  * Converts matrices with specific data type to matrices with different data type.
695  * @param matrices The matrices to convert
696  * @return The converted matrices
697  * @tparam U The element data type of the matrices to convert
698  */
699  template <typename U>
700  static inline std::vector< HomogenousMatrixT4<T> > matrices2matrices(const std::vector< HomogenousMatrixT4<U> >& matrices);
701 
702  /**
703  * Converts matrices with specific data type to matrices with different data type.
704  * @param matrices The matrices to convert
705  * @param size The number of matrices to convert
706  * @return The converted matrices
707  * @tparam U The element data type of the matrices to convert
708  */
709  template <typename U>
710  static inline std::vector< HomogenousMatrixT4<T> > matrices2matrices(const HomogenousMatrixT4<U>* matrices, const size_t size);
711 
712  protected:
713 
714  /// The sixteen values of the transformation matrix.
715  T values_[16];
716 };
717 
718 template <typename T>
720 {
721  // nothing to do here
722 }
723 
724 template <typename T>
726 {
727  memcpy(values_, matrix.values_, sizeof(T) * 16);
728 }
729 
730 template <typename T>
731 template <typename U>
733 {
734  for (unsigned int n = 0u; n < 16u; ++n)
735  {
736  values_[n] = T(matrix.values_[n]);
737  }
738 }
739 
740 template <typename T>
741 inline HomogenousMatrixT4<T>::HomogenousMatrixT4(const bool setToIdentity)
742 {
743  if (setToIdentity)
744  {
745  values_[ 0] = T(1.0);
746  values_[ 1] = T(0.0);
747  values_[ 2] = T(0.0);
748  values_[ 3] = T(0.0);
749 
750  values_[ 4] = T(0.0);
751  values_[ 5] = T(1.0);
752  values_[ 6] = T(0.0);
753  values_[ 7] = T(0.0);
754 
755  values_[ 8] = T(0.0);
756  values_[ 9] = T(0.0);
757  values_[10] = T(1.0);
758  values_[11] = T(0.0);
759 
760  values_[12] = T(0.0);
761  values_[13] = T(0.0);
762  values_[14] = T(0.0);
763  values_[15] = T(1.0);
764 
765  ocean_assert(isValid());
766  }
767  else
768  {
769  for (unsigned int n = 0u; n < 16u; ++n)
770  {
771  values_[n] = T(0);
772  }
773 
774  ocean_assert(!isValid());
775  }
776 }
777 
778 template <typename T>
779 template <typename U>
781 {
782  for (unsigned int n = 0u; n < 16u; ++n)
783  {
784  values_[n] = T(arrayValues[n]);
785  }
786 }
787 
788 template <typename T>
790 {
791  memcpy(values_, arrayValues, sizeof(T) * 16);
792 }
793 
794 template <typename T>
795 template <typename U>
796 HomogenousMatrixT4<T>::HomogenousMatrixT4(const U* arrayValues, const bool valuesRowAligned)
797 {
798  ocean_assert(arrayValues);
799 
800  if (valuesRowAligned)
801  {
802  values_[ 0] = T(arrayValues[ 0]);
803  values_[ 1] = T(arrayValues[ 4]);
804  values_[ 2] = T(arrayValues[ 8]);
805  values_[ 3] = T(arrayValues[12]);
806  values_[ 4] = T(arrayValues[ 1]);
807  values_[ 5] = T(arrayValues[ 5]);
808  values_[ 6] = T(arrayValues[ 9]);
809  values_[ 7] = T(arrayValues[13]);
810  values_[ 8] = T(arrayValues[ 2]);
811  values_[ 9] = T(arrayValues[ 6]);
812  values_[10] = T(arrayValues[10]);
813  values_[11] = T(arrayValues[14]);
814  values_[12] = T(arrayValues[ 3]);
815  values_[13] = T(arrayValues[ 7]);
816  values_[14] = T(arrayValues[11]);
817  values_[15] = T(arrayValues[15]);
818  }
819  else
820  {
821  for (unsigned int n = 0u; n < 16u; ++n)
822  {
823  values_[n] = T(arrayValues[n]);
824  }
825  }
826 }
827 
828 template <typename T>
829 HomogenousMatrixT4<T>::HomogenousMatrixT4(const T* arrayValues, const bool valuesRowAligned)
830 {
831  ocean_assert(arrayValues);
832 
833  if (valuesRowAligned)
834  {
835  values_[ 0] = arrayValues[ 0];
836  values_[ 1] = arrayValues[ 4];
837  values_[ 2] = arrayValues[ 8];
838  values_[ 3] = arrayValues[12];
839  values_[ 4] = arrayValues[ 1];
840  values_[ 5] = arrayValues[ 5];
841  values_[ 6] = arrayValues[ 9];
842  values_[ 7] = arrayValues[13];
843  values_[ 8] = arrayValues[ 2];
844  values_[ 9] = arrayValues[ 6];
845  values_[10] = arrayValues[10];
846  values_[11] = arrayValues[14];
847  values_[12] = arrayValues[ 3];
848  values_[13] = arrayValues[ 7];
849  values_[14] = arrayValues[11];
850  values_[15] = arrayValues[15];
851  }
852  else
853  {
854  memcpy(values_, arrayValues, sizeof(T) * 16);
855  }
856 }
857 
858 template <typename T>
860 {
861  values_[ 0] = T(1.0);
862  values_[ 1] = T(0.0);
863  values_[ 2] = T(0.0);
864  values_[ 3] = T(0.0);
865 
866  values_[ 4] = T(0.0);
867  values_[ 5] = T(1.0);
868  values_[ 6] = T(0.0);
869  values_[ 7] = T(0.0);
870 
871  values_[ 8] = T(0.0);
872  values_[ 9] = T(0.0);
873  values_[10] = T(1.0);
874  values_[11] = T(0.0);
875 
876  values_[12] = translation[0];
877  values_[13] = translation[1];
878  values_[14] = translation[2];
879  values_[15] = T(1.0);
880 
881  ocean_assert(isValid());
882 }
883 
884 template <typename T>
886 {
887  ocean_assert(rotation.isValid());
888 
889  //values[ 0] = T(1.0);
890  //values[ 1] = T(0.0);
891  //values[ 2] = T(0.0);
892  values_[ 3] = T(0.0);
893 
894  //values[ 4] = T(0.0);
895  //values[ 5] = T(1.0);
896  //values[ 6] = T(0.0);
897  values_[ 7] = T(0.0);
898 
899  //values[ 8] = T(0.0);
900  //values[ 9] = T(0.0);
901  //values[10] = T(1.0);
902  values_[11] = T(0.0);
903 
904  values_[12] = T(0.0);
905  values_[13] = T(0.0);
906  values_[14] = T(0.0);
907  values_[15] = T(1.0);
908 
910 
911  ocean_assert(isValid());
912 }
913 
914 template <typename T>
916 {
917  ocean_assert(euler.isValid());
918 
919  //values[ 0] = T(1.0);
920  //values[ 1] = T(0.0);
921  //values[ 2] = T(0.0);
922  values_[ 3] = T(0.0);
923 
924  //values[ 4] = T(0.0);
925  //values[ 5] = T(1.0);
926  //values[ 6] = T(0.0);
927  values_[ 7] = T(0.0);
928 
929  //values[ 8] = T(0.0);
930  //values[ 9] = T(0.0);
931  //values[10] = T(1.0);
932  values_[11] = T(0.0);
933 
934  values_[12] = T(0.0);
935  values_[13] = T(0.0);
936  values_[14] = T(0.0);
937  values_[15] = T(1.0);
938 
940 
941  ocean_assert(isValid());
942 }
943 
944 template <typename T>
946 {
947  ocean_assert(rotation.isValid());
948 
949  //values[ 0] = T(1.0);
950  //values[ 1] = T(0.0);
951  //values[ 2] = T(0.0);
952  values_[ 3] = T(0.0);
953 
954  //values[ 4] = T(0.0);
955  //values[ 5] = T(1.0);
956  //values[ 6] = T(0.0);
957  values_[ 7] = T(0.0);
958 
959  //values[ 8] = T(0.0);
960  //values[ 9] = T(0.0);
961  //values[10] = T(1.0);
962  values_[11] = T(0.0);
963 
964  values_[12] = T(0.0);
965  values_[13] = T(0.0);
966  values_[14] = T(0.0);
967  values_[15] = T(1.0);
968 
970 
971  ocean_assert(isValid());
972 }
973 
974 template <typename T>
976 {
977  values_[ 0] = rotation()[0];
978  values_[ 1] = rotation()[1];
979  values_[ 2] = rotation()[2];
980  values_[ 3] = T(0.0);
981 
982  values_[ 4] = rotation()[3];
983  values_[ 5] = rotation()[4];
984  values_[ 6] = rotation()[5];
985  values_[ 7] = T(0.0);
986 
987  values_[ 8] = rotation()[6];
988  values_[ 9] = rotation()[7];
989  values_[10] = rotation()[8];
990  values_[11] = T(0.0);
991 
992  values_[12] = T(0.0);
993  values_[13] = T(0.0);
994  values_[14] = T(0.0);
995  values_[15] = T(1.0);
996 
997  ocean_assert(isValid());
998 }
999 
1000 template <typename T>
1002 {
1003  memcpy(values_, matrix(), sizeof(T) * 16);
1004 
1005  ocean_assert(isValid());
1006 }
1007 
1008 template <typename T>
1010 {
1011  ocean_assert(rotation.isValid());
1012 
1013  //values[ 0] = T(1.0);
1014  //values[ 1] = T(0.0);
1015  //values[ 2] = T(0.0);
1016  values_[ 3] = T(0.0);
1017 
1018  //values[ 4] = T(0.0);
1019  //values[ 5] = T(1.0);
1020  //values[ 6] = T(0.0);
1021  values_[ 7] = T(0.0);
1022 
1023  //values[ 8] = T(0.0);
1024  //values[ 9] = T(0.0);
1025  //values[10] = T(1.0);
1026  values_[11] = T(0.0);
1027 
1028  values_[12] = translation[0];
1029  values_[13] = translation[1];
1030  values_[14] = translation[2];
1031  values_[15] = T(1.0);
1032 
1034 
1035  ocean_assert(isValid());
1036 }
1037 
1038 template <typename T>
1039 HomogenousMatrixT4<T>::HomogenousMatrixT4(const std::pair< VectorT3<T>, RotationT<T> >& translationAndRotation)
1040 {
1041  ocean_assert(translationAndRotation.second.isValid());
1042 
1043  //values[ 0] = T(1.0);
1044  //values[ 1] = T(0.0);
1045  //values[ 2] = T(0.0);
1046  values_[ 3] = T(0.0);
1047 
1048  //values[ 4] = T(0.0);
1049  //values[ 5] = T(1.0);
1050  //values[ 6] = T(0.0);
1051  values_[ 7] = T(0.0);
1052 
1053  //values[ 8] = T(0.0);
1054  //values[ 9] = T(0.0);
1055  //values[10] = T(1.0);
1056  values_[11] = T(0.0);
1057 
1058  values_[12] = translationAndRotation.first[0];
1059  values_[13] = translationAndRotation.first[1];
1060  values_[14] = translationAndRotation.first[2];
1061  values_[15] = T(1.0);
1062 
1063  setRotation(translationAndRotation.second);
1064 
1065  ocean_assert(isValid());
1066 }
1067 
1068 template <typename T>
1070 {
1071  ocean_assert(euler.isValid());
1072 
1073  //values[ 0] = T(1.0);
1074  //values[ 1] = T(0.0);
1075  //values[ 2] = T(0.0);
1076  values_[ 3] = T(0.0);
1077 
1078  //values[ 4] = T(0.0);
1079  //values[ 5] = T(1.0);
1080  //values[ 6] = T(0.0);
1081  values_[ 7] = T(0.0);
1082 
1083  //values[ 8] = T(0.0);
1084  //values[ 9] = T(0.0);
1085  //values[10] = T(1.0);
1086  values_[11] = T(0.0);
1087 
1088  values_[12] = translation[0];
1089  values_[13] = translation[1];
1090  values_[14] = translation[2];
1091  values_[15] = T(1.0);
1092 
1094 
1095  ocean_assert(isValid());
1096 }
1097 
1098 template <typename T>
1100 {
1101  ocean_assert(rotation.isValid());
1102 
1103  //values[ 0] = T(1.0);
1104  //values[ 1] = T(0.0);
1105  //values[ 2] = T(0.0);
1106  values_[ 3] = T(0.0);
1107 
1108  //values[ 4] = T(0.0);
1109  //values[ 5] = T(1.0);
1110  //values[ 6] = T(0.0);
1111  values_[ 7] = T(0.0);
1112 
1113  //values[ 8] = T(0.0);
1114  //values[ 9] = T(0.0);
1115  //values[10] = T(1.0);
1116  values_[11] = T(0.0);
1117 
1118  values_[12] = translation[0];
1119  values_[13] = translation[1];
1120  values_[14] = translation[2];
1121  values_[15] = T(1.0);
1122 
1124 
1125  ocean_assert(isValid());
1126 }
1127 
1128 template <typename T>
1129 HomogenousMatrixT4<T>::HomogenousMatrixT4(const std::pair< VectorT3<T>, QuaternionT<T> >& translationAndRotation)
1130 {
1131  ocean_assert(translationAndRotation.second.isValid());
1132 
1133  //values[ 0] = T(1.0);
1134  //values[ 1] = T(0.0);
1135  //values[ 2] = T(0.0);
1136  values_[ 3] = T(0.0);
1137 
1138  //values[ 4] = T(0.0);
1139  //values[ 5] = T(1.0);
1140  //values[ 6] = T(0.0);
1141  values_[ 7] = T(0.0);
1142 
1143  //values[ 8] = T(0.0);
1144  //values[ 9] = T(0.0);
1145  //values[10] = T(1.0);
1146  values_[11] = T(0.0);
1147 
1148  values_[12] = translationAndRotation.first[0];
1149  values_[13] = translationAndRotation.first[1];
1150  values_[14] = translationAndRotation.first[2];
1151  values_[15] = T(1.0);
1152 
1153  setRotation(translationAndRotation.second);
1154 
1155  ocean_assert(isValid());
1156 }
1157 
1158 template <typename T>
1160 {
1161  values_[ 0] = rotation()[0];
1162  values_[ 1] = rotation()[1];
1163  values_[ 2] = rotation()[2];
1164  values_[ 3] = T(0.0);
1165 
1166  values_[ 4] = rotation()[3];
1167  values_[ 5] = rotation()[4];
1168  values_[ 6] = rotation()[5];
1169  values_[ 7] = T(0.0);
1170 
1171  values_[ 8] = rotation()[6];
1172  values_[ 9] = rotation()[7];
1173  values_[10] = rotation()[8];
1174  values_[11] = T(0.0);
1175 
1176  values_[12] = translation[0];
1177  values_[13] = translation[1];
1178  values_[14] = translation[2];
1179  values_[15] = T(1.0);
1180 
1181  ocean_assert(isValid());
1182 }
1183 
1184 template <typename T>
1186 {
1187  values_[ 0] = scale.x();
1188  values_[ 1] = T(0.0);
1189  values_[ 2] = T(0.0);
1190  values_[ 3] = T(0.0);
1191 
1192  values_[ 4] = T(0.0);
1193  values_[ 5] = scale.y();
1194  values_[ 6] = T(0.0);
1195  values_[ 7] = T(0.0);
1196 
1197  values_[ 8] = T(0.0);
1198  values_[ 9] = T(0.0);
1199  values_[10] = scale.z();
1200  values_[11] = T(0.0);
1201 
1202  values_[12] = translation[0];
1203  values_[13] = translation[1];
1204  values_[14] = translation[2];
1205  values_[15] = T(1.0);
1206 
1207  ocean_assert(isValid());
1208 }
1209 
1210 template <typename T>
1212 {
1213  ocean_assert(rotation.isValid());
1214 
1215  //values[ 0] = T(1.0);
1216  //values[ 1] = T(0.0);
1217  //values[ 2] = T(0.0);
1218  values_[ 3] = T(0.0);
1219 
1220  //values[ 4] = T(0.0);
1221  //values[ 5] = T(1.0);
1222  //values[ 6] = T(0.0);
1223  values_[ 7] = T(0.0);
1224 
1225  //values[ 8] = T(0.0);
1226  //values[ 9] = T(0.0);
1227  //values[10] = T(1.0);
1228  values_[11] = T(0.0);
1229 
1230  values_[12] = translation[0];
1231  values_[13] = translation[1];
1232  values_[14] = translation[2];
1233  values_[15] = T(1.0);
1234 
1236  applyScale(scale);
1237 
1238  ocean_assert(isValid());
1239 }
1240 
1241 template <typename T>
1243 {
1244  values_[3] = T(0.0);
1245  values_[7] = T(0.0);
1246  values_[11] = T(0.0);
1247  values_[15] = T(1.0);
1248 
1250 
1251  values_[12] = T(0.0);
1252  values_[13] = T(0.0);
1253  values_[14] = T(0.0);
1254 
1255  HomogenousMatrixT4<T> shearMatrix(true);
1256  shearMatrix(0, 1) = shear(0);
1257  shearMatrix(0, 2) = shear(1);
1258  shearMatrix(1, 2) = shear(2);
1259  *this = *this * shearMatrix;
1260 
1261  applyScale(scale);
1262 
1263  memcpy(values_ + 12, translation(), sizeof(T) * 3);
1264 
1265  ocean_assert(isValid());
1266 }
1267 
1268 template <typename T>
1270 {
1271  values_[3] = T(0.0);
1272  values_[7] = T(0.0);
1273  values_[11] = T(0.0);
1274  values_[15] = T(1.0);
1275 
1277 
1278  HomogenousMatrixT4<T> shearMatrix(true);
1279  shearMatrix(0, 1) = shear(0);
1280  shearMatrix(0, 2) = shear(1);
1281  shearMatrix(1, 2) = shear(2);
1282  *this = *this * shearMatrix;
1283 
1284  applyScale(scale);
1285 
1286  memcpy(values_ + 12, translation(), sizeof(T) * 3);
1287 
1288  ocean_assert(isValid());
1289 }
1290 
1291 template <typename T>
1293 {
1294  memcpy(values_ + 12, translation(), sizeof(T) * 3);
1295 
1296  values_[3] = T(0.0);
1297  values_[7] = T(0.0);
1298  values_[11] = T(0.0);
1299  values_[15] = T(1.0);
1300 
1302  applyScale(scale);
1303 
1304  ocean_assert(isValid());
1305 }
1306 
1307 template <typename T>
1309 {
1310  values_[ 0] = xAxis[0];
1311  values_[ 1] = xAxis[1];
1312  values_[ 2] = xAxis[2];
1313  values_[ 3] = T(0.0);
1314 
1315  values_[ 4] = yAxis[0];
1316  values_[ 5] = yAxis[1];
1317  values_[ 6] = yAxis[2];
1318  values_[ 7] = T(0.0);
1319 
1320  values_[ 8] = zAxis[0];
1321  values_[ 9] = zAxis[1];
1322  values_[10] = zAxis[2];
1323  values_[11] = T(0.0);
1324 
1325  values_[12] = T(0.0);
1326  values_[13] = T(0.0);
1327  values_[14] = T(0.0);
1328  values_[15] = T(1.0);
1329 
1330  ocean_assert(isValid());
1331 }
1332 
1333 template <typename T>
1335 {
1336  values_[ 0] = xAxis[0];
1337  values_[ 1] = xAxis[1];
1338  values_[ 2] = xAxis[2];
1339  values_[ 3] = T(0.0);
1340 
1341  values_[ 4] = yAxis[0];
1342  values_[ 5] = yAxis[1];
1343  values_[ 6] = yAxis[2];
1344  values_[ 7] = T(0.0);
1345 
1346  values_[ 8] = zAxis[0];
1347  values_[ 9] = zAxis[1];
1348  values_[10] = zAxis[2];
1349  values_[11] = T(0.0);
1350 
1351  values_[12] = translation[0];
1352  values_[13] = translation[1];
1353  values_[14] = translation[2];
1354  values_[15] = T(1.0);
1355 
1356  ocean_assert(isValid());
1357 }
1358 
1359 template <typename T>
1361 {
1362  ocean_assert(isValid());
1363  return VectorT3<T>(values_ + 0);
1364 }
1365 
1366 template <typename T>
1368 {
1369  ocean_assert(isValid());
1370  return VectorT3<T>(values_ + 4);
1371 }
1372 
1373 template <typename T>
1375 {
1376  ocean_assert(isValid());
1377  return VectorT3<T>(values_ + 8);
1378 }
1379 
1380 template <typename T>
1382 {
1383  ocean_assert(isValid());
1384  return VectorT3<T>(values_ + 12);
1385 }
1386 
1387 template <typename T>
1389 {
1390  ocean_assert(isValid());
1391  return QuaternionT<T>(*this);
1392 }
1393 
1394 template <typename T>
1396 {
1397  ocean_assert(isValid());
1398 
1399  const VectorT3<T> x(values_);
1400  const VectorT3<T> y(values_ + 4);
1401  const VectorT3<T> z(values_ + 8);
1402 
1403  return VectorT3<T>(x.length(), y.length(), z.length());
1404 }
1405 
1406 template <typename T>
1408 {
1409  ocean_assert(isValid());
1410 
1412 
1414  VectorT3<T> yAxis(values_ + 4);
1415  VectorT3<T> zAxis(values_ + 8);
1416 
1417  // x scale factor and normalization of x-axis
1418  scale.x() = xAxis.length();
1419  if (NumericT<T>::isEqualEps(scale.x()))
1420  {
1421  return false;
1422  }
1423 
1424  xAxis /= scale.x();
1425 
1426  // xy shear factor
1427  shear(0) = xAxis * yAxis;
1428  // make y-axis orthogonal to x-axis
1429  yAxis -= xAxis * shear(0);
1430 
1431  // y scale factor and normalization of y-axis
1432  scale.y() = yAxis.length();
1433  if (NumericT<T>::isEqualEps(scale.y()))
1434  {
1435  return false;
1436  }
1437 
1438  const T invScaleY = T(1) / scale.y();
1439 
1440  yAxis *= invScaleY;
1441 
1442  // normalization of xy shear factor
1443  shear(0) *= invScaleY;
1444 
1445  // xz shear factor and orthogonalization of z-axis
1446  shear(1) = xAxis * zAxis;
1447  zAxis -= xAxis * shear(1);
1448 
1449  // yz shear factor and orthogonalization of z-axis
1450  shear(2) = yAxis * zAxis;
1451  zAxis -= yAxis * shear(2);
1452 
1453  // z scale factor and normalization of z-axis
1454  scale.z() = zAxis.length();
1455 
1456  if (NumericT<T>::isEqualEps(scale.z()))
1457  {
1458  return false;
1459  }
1460 
1461  const T invScaleZ = T(1) / scale.z();
1462 
1463  zAxis *= invScaleZ;
1464 
1465  // normalization of xz shear and yz shear
1466  shear(1) *= invScaleZ;
1467  shear(2) *= invScaleZ;
1468 
1469  // check for a coordinate system flip
1470  if (xAxis * yAxis.cross(zAxis) < 0)
1471  {
1472  scale = -scale;
1473  xAxis = -xAxis;
1474  yAxis = -yAxis;
1475  zAxis = -zAxis;
1476  }
1477 
1478  // no we have pairwise orthogonal base vectors
1479 
1480 #ifdef OCEAN_DEBUG
1481  const T epsilon = std::is_same<T, float>::value ? NumericT<T>::weakEps() : NumericT<T>::eps();
1482  ocean_assert(NumericT<T>::isEqual(xAxis * yAxis, 0, epsilon));
1483  ocean_assert(NumericT<T>::isEqual(xAxis * zAxis, 0, epsilon));
1484  ocean_assert(NumericT<T>::isEqual(yAxis * zAxis, 0, epsilon));
1485 #endif
1486 
1488 
1489  return true;
1490 }
1491 
1492 template <typename T>
1494 {
1495  ocean_assert(isValid());
1496 
1497  return SquareMatrixT3<T>(values_[0], values_[1], values_[2],
1498  values_[4], values_[5], values_[6],
1499  values_[8], values_[9], values_[10]);
1500 }
1501 
1502 template <typename T>
1503 inline void HomogenousMatrixT4<T>::rotationMatrix(T* data, const bool transposed) const
1504 {
1505  ocean_assert(data);
1506 
1507  if (transposed)
1508  {
1509  data[0] = values_[0];
1510  data[1] = values_[4];
1511  data[2] = values_[8];
1512 
1513  data[3] = values_[1];
1514  data[4] = values_[5];
1515  data[5] = values_[9];
1516 
1517  data[6] = values_[2];
1518  data[7] = values_[6];
1519  data[8] = values_[10];
1520  }
1521  else
1522  {
1523  data[0] = values_[0];
1524  data[1] = values_[1];
1525  data[2] = values_[2];
1526 
1527  data[3] = values_[4];
1528  data[4] = values_[5];
1529  data[5] = values_[6];
1530 
1531  data[6] = values_[8];
1532  data[7] = values_[9];
1533  data[8] = values_[10];
1534  }
1535 }
1536 
1537 template <typename T>
1539 {
1540  ocean_assert(isValid());
1541  return rotationMatrix().orthonormalMatrix();
1542 }
1543 
1544 template <typename T>
1546 {
1547  ocean_assert(isValid());
1548 
1549  SquareMatrixT4<T> result(*this);
1550 
1551  result[1] = values_[4];
1552  result[4] = values_[1];
1553 
1554  result[2] = values_[8];
1555  result[8] = values_[2];
1556 
1557  result[3] = values_[12];
1558  result[12] = values_[3];
1559 
1560  result[7] = values_[13];
1561  result[13] = values_[7];
1562 
1563  result[11] = values_[14];
1564  result[14] = values_[11];
1565 
1566  result[6] = values_[9];
1567  result[9] = values_[6];
1568 
1569  ocean_assert(result == SquareMatrixT4<T>(*this).transposed());
1570 
1571  return result;
1572 }
1573 
1574 template <typename T>
1576 {
1577  ocean_assert(isValid());
1578 
1579  HomogenousMatrixT4<T> invertedMatrix;
1580 
1581  if (!invert(invertedMatrix))
1582  {
1583  ocean_assert(false && "Could not invert the matrix.");
1584  return *this;
1585  }
1586 
1587  return invertedMatrix;
1588 }
1589 
1590 template <typename T>
1592 {
1593  HomogenousMatrixT4<T> invertedMatrix;
1594 
1595  if (!invert(invertedMatrix))
1596  {
1597  return false;
1598  }
1599 
1600  *this = invertedMatrix;
1601 
1602  return true;
1603 }
1604 
1605 template <typename T>
1607 {
1608  ocean_assert(isValid());
1609 
1610  const T det = determinant();
1611 
1612  if (NumericT<T>::isEqualEps(det))
1613  {
1614  return false;
1615  }
1616 
1617  const T factor = T(1.0) / det;
1618 
1619  invertedMatrix.values_[0] = (values_[5] * values_[10] - values_[6] * values_[9]) * factor;
1620  invertedMatrix.values_[1] = (values_[2] * values_[9] - values_[1] * values_[10]) * factor;
1621  invertedMatrix.values_[2] = (values_[1] * values_[6] - values_[2] * values_[5]) * factor;
1622  invertedMatrix.values_[4] = (values_[8] * values_[6] - values_[4] * values_[10]) * factor;
1623  invertedMatrix.values_[5] = (values_[0] * values_[10] - values_[8] * values_[2]) * factor;
1624  invertedMatrix.values_[6] = (values_[4] * values_[2] - values_[0] * values_[6]) * factor;
1625  invertedMatrix.values_[8] = (values_[4] * values_[9] - values_[8] * values_[5]) * factor;
1626  invertedMatrix.values_[9] = (values_[8] * values_[1] - values_[0] * values_[9]) * factor;
1627  invertedMatrix.values_[10] = (values_[0] * values_[5] - values_[4] * values_[1]) * factor;
1628 
1629  invertedMatrix.values_[12] = -(invertedMatrix.values_[0] * values_[12] + invertedMatrix.values_[4] * values_[13] + invertedMatrix.values_[8] * values_[14]);
1630  invertedMatrix.values_[13] = -(invertedMatrix.values_[1] * values_[12] + invertedMatrix.values_[5] * values_[13] + invertedMatrix.values_[9] * values_[14]);
1631  invertedMatrix.values_[14] = -(invertedMatrix.values_[2] * values_[12] + invertedMatrix.values_[6] * values_[13] + invertedMatrix.values_[10] * values_[14]);
1632 
1633  invertedMatrix.values_[3] = T(0.0);
1634  invertedMatrix.values_[7] = T(0.0);
1635  invertedMatrix.values_[11] = T(0.0);
1636  invertedMatrix.values_[15] = T(1.0);
1637 
1638  return true;
1639 }
1640 
1641 template <typename T>
1643 {
1644  return values_[0] * (values_[5] * values_[10] - values_[6] * values_[9])
1645  + values_[1] * (values_[6] * values_[8] - values_[4] * values_[10])
1646  + values_[2] * (values_[4] * values_[9] - values_[5] * values_[8]);
1647 }
1648 
1649 template <typename T>
1651 {
1652  ocean_assert(isValid());
1653  return values_[0] + values_[5] + values_[10] + T(1.0);
1654 }
1655 
1656 template <typename T>
1658 {
1659  values_[12] = translation[0];
1660  values_[13] = translation[1];
1661  values_[14] = translation[2];
1662 
1663  return *this;
1664 }
1665 
1666 template <typename T>
1668 {
1669  // R(n, angle) = cos(angle) * I + (1 - cos(angle) * nn^T - sin(angle) * X(n)
1670 
1671  ocean_assert(rotation.isValid());
1672 
1673  const T cosValue = NumericT<T>::cos(rotation.angle());
1674  const T cosValue1 = T(1.0) - cosValue;
1675  const T sinValue = NumericT<T>::sin(rotation.angle());
1676 
1677  const VectorT3<T> axis(rotation.axis());
1678 
1679  const T xx = axis.x() * axis.x() * cosValue1;
1680  const T yy = axis.y() * axis.y() * cosValue1;
1681  const T zz = axis.z() * axis.z() * cosValue1;
1682  const T xy = axis.x() * axis.y() * cosValue1;
1683  const T xz = axis.x() * axis.z() * cosValue1;
1684  const T yz = axis.y() * axis.z() * cosValue1;
1685 
1686  const T nx = axis.x() * sinValue;
1687  const T ny = axis.y() * sinValue;
1688  const T nz = axis.z() * sinValue;
1689 
1690  values_[0] = xx + cosValue;
1691  values_[1] = xy + nz;
1692  values_[2] = xz - ny;
1693 
1694  values_[4] = xy - nz;
1695  values_[5] = yy + cosValue;
1696  values_[6] = yz + nx;
1697 
1698  values_[8] = xz + ny;
1699  values_[9] = yz - nx;
1700  values_[10] = zz + cosValue;
1701 
1702  ocean_assert(isValid() && NumericT<T>::isEqual(determinant(), T(1.0)));
1703  return *this;
1704 }
1705 
1706 template <typename T>
1708 {
1709  ocean_assert(quaternion.isValid());
1710 
1711  const T xx = quaternion.x() * quaternion.x();
1712  const T yy = quaternion.y() * quaternion.y();
1713  const T zz = quaternion.z() * quaternion.z();
1714 
1715  const T wx = quaternion.w() * quaternion.x();
1716  const T wy = quaternion.w() * quaternion.y();
1717  const T wz = quaternion.w() * quaternion.z();
1718  const T xy = quaternion.x() * quaternion.y();
1719  const T xz = quaternion.x() * quaternion.z();
1720  const T yz = quaternion.y() * quaternion.z();
1721 
1722  values_[ 0] = T(1.0) - T(2.0) * (yy + zz);
1723  values_[ 1] = T(2.0) * (wz + xy);
1724  values_[ 2] = T(2.0) * (xz - wy);
1725 
1726  values_[ 4] = T(2.0) * (xy - wz);
1727  values_[ 5] = T(1.0) - T(2.0) * (xx + zz);
1728  values_[ 6] = T(2.0) * (wx + yz);
1729 
1730  values_[ 8] = T(2.0) * (wy + xz);
1731  values_[ 9] = T(2.0) * (yz - wx);
1732  values_[10] = T(1.0) - T(2.0) * (xx + yy);
1733 
1734  ocean_assert(isValid() && NumericT<T>::isWeakEqual(determinant(), T(1.0)));
1735  return *this;
1736 }
1737 
1738 template <typename T>
1740 {
1741  memcpy(values_, matrix(), sizeof(T) * 3);
1742  memcpy(values_ + 4, matrix() + 3, sizeof(T) * 3);
1743  memcpy(values_ + 8, matrix() + 6, sizeof(T) * 3);
1744 
1745  return *this;
1746 }
1747 
1748 template <typename T>
1750 {
1751  ocean_assert(isValid());
1752 
1753  values_[0] *= scale(0);
1754  values_[1] *= scale(0);
1755  values_[2] *= scale(0);
1756 
1757  values_[4] *= scale(1);
1758  values_[5] *= scale(1);
1759  values_[6] *= scale(1);
1760 
1761  values_[8] *= scale(2);
1762  values_[9] *= scale(2);
1763  values_[10] *= scale(2);
1764 
1765  return *this;
1766 }
1767 
1768 template <typename T>
1770 {
1771  values_[ 0] = T(1.0);
1772  values_[ 1] = T(0.0);
1773  values_[ 2] = T(0.0);
1774  values_[ 3] = T(0.0);
1775 
1776  values_[ 4] = T(0.0);
1777  values_[ 5] = T(1.0);
1778  values_[ 6] = T(0.0);
1779  values_[ 7] = T(0.0);
1780 
1781  values_[ 8] = T(0.0);
1782  values_[ 9] = T(0.0);
1783  values_[10] = T(1.0);
1784  values_[11] = T(0.0);
1785 
1786  values_[12] = T(0.0);
1787  values_[13] = T(0.0);
1788  values_[14] = T(0.0);
1789  values_[15] = T(1.0);
1790 
1791  ocean_assert(isValid());
1792 }
1793 
1794 template <typename T>
1796 {
1797  for (unsigned int n = 0u; n < 16u; ++n)
1798  {
1799  values_[n] = T(0);
1800  }
1801 
1802  ocean_assert(!isValid());
1803 }
1804 
1805 template <typename T>
1807 {
1809 }
1810 
1811 template <typename T>
1813 {
1818 }
1819 
1820 template <typename T>
1821 inline bool HomogenousMatrixT4<T>::isEqual(const HomogenousMatrixT4<T>& matrix, const T epsilon) const
1822 {
1823  return NumericT<T>::isEqual(values_[0], matrix.values_[0], epsilon) && NumericT<T>::isEqual(values_[1], matrix.values_[1], epsilon)
1824  && NumericT<T>::isEqual(values_[2], matrix.values_[2], epsilon) && NumericT<T>::isEqual(values_[3], matrix.values_[3], epsilon)
1825  && NumericT<T>::isEqual(values_[4], matrix.values_[4], epsilon) && NumericT<T>::isEqual(values_[5], matrix.values_[5], epsilon)
1826  && NumericT<T>::isEqual(values_[6], matrix.values_[6], epsilon) && NumericT<T>::isEqual(values_[7], matrix.values_[7], epsilon)
1827  && NumericT<T>::isEqual(values_[8], matrix.values_[8], epsilon) && NumericT<T>::isEqual(values_[9], matrix.values_[9], epsilon)
1828  && NumericT<T>::isEqual(values_[10], matrix.values_[10], epsilon) && NumericT<T>::isEqual(values_[11], matrix.values_[11], epsilon)
1829  && NumericT<T>::isEqual(values_[12], matrix.values_[12], epsilon) && NumericT<T>::isEqual(values_[13], matrix.values_[13], epsilon)
1830  && NumericT<T>::isEqual(values_[14], matrix.values_[14], epsilon) && NumericT<T>::isEqual(values_[15], matrix.values_[15], epsilon);
1831 }
1832 
1833 template <typename T>
1835 {
1840 }
1841 
1842 template <typename T>
1843 inline const T* HomogenousMatrixT4<T>::data() const
1844 {
1845  return values_;
1846 }
1847 
1848 template <typename T>
1850 {
1851  return values_;
1852 }
1853 
1854 template <typename T>
1855 inline void HomogenousMatrixT4<T>::copyElements(T* arrayValues, const bool valuesRowAligned) const
1856 {
1857  ocean_assert(arrayValues != nullptr);
1858 
1859  if (valuesRowAligned)
1860  {
1861  // this matrix and the provided array are both column aligned
1862  // thus, we can simply copy the data
1863 
1864  arrayValues[ 0] = values_[ 0];
1865  arrayValues[ 1] = values_[ 4];
1866  arrayValues[ 2] = values_[ 8];
1867  arrayValues[ 3] = values_[12];
1868 
1869  arrayValues[ 4] = values_[ 1];
1870  arrayValues[ 5] = values_[ 5];
1871  arrayValues[ 6] = values_[ 9];
1872  arrayValues[ 7] = values_[13];
1873 
1874  arrayValues[ 8] = values_[ 2];
1875  arrayValues[ 9] = values_[ 6];
1876  arrayValues[10] = values_[10];
1877  arrayValues[11] = values_[14];
1878 
1879  arrayValues[12] = values_[ 3];
1880  arrayValues[13] = values_[ 7];
1881  arrayValues[14] = values_[11];
1882  arrayValues[15] = values_[15];
1883  }
1884  else
1885  {
1886  // this matrix and the provided array are both column aligned
1887  // thus, we can simply copy the data
1888 
1889  memcpy(arrayValues, values_, sizeof(T) * 16);
1890  }
1891 }
1892 
1893 template <typename T>
1894 template <typename U>
1895 inline void HomogenousMatrixT4<T>::copyElements(U* arrayValues, const bool valuesRowAligned) const
1896 {
1897  ocean_assert(arrayValues != nullptr);
1898 
1899  if (valuesRowAligned)
1900  {
1901  // the provided buffer is row aligned (this matrix is column aligned)
1902  // thus, we have to assign the values in a transposed manner
1903 
1904  arrayValues[ 0] = U(values_[ 0]);
1905  arrayValues[ 1] = U(values_[ 4]);
1906  arrayValues[ 2] = U(values_[ 8]);
1907  arrayValues[ 3] = U(values_[12]);
1908 
1909  arrayValues[ 4] = U(values_[ 1]);
1910  arrayValues[ 5] = U(values_[ 5]);
1911  arrayValues[ 6] = U(values_[ 9]);
1912  arrayValues[ 7] = U(values_[13]);
1913 
1914  arrayValues[ 8] = U(values_[ 2]);
1915  arrayValues[ 9] = U(values_[ 6]);
1916  arrayValues[10] = U(values_[10]);
1917  arrayValues[11] = U(values_[14]);
1918 
1919  arrayValues[12] = U(values_[ 3]);
1920  arrayValues[13] = U(values_[ 7]);
1921  arrayValues[14] = U(values_[11]);
1922  arrayValues[15] = U(values_[15]);
1923  }
1924  else
1925  {
1926  // this matrix and the provided array are both column aligned
1927  // thus, we can simply copy the data
1928 
1929  for (unsigned int n = 0u; n < 16u; ++n)
1930  {
1931  arrayValues[n] = U(values_[n]);
1932  }
1933  }
1934 }
1935 
1936 template <typename T>
1938 {
1939  ocean_assert(isValid());
1940 
1941  return VectorT3<T>(values_[0] * vector[0] + values_[4] * vector[1] + values_[8] * vector[2],
1942  values_[1] * vector[0] + values_[5] * vector[1] + values_[9] * vector[2],
1943  values_[2] * vector[0] + values_[6] * vector[1] + values_[10] * vector[2]);
1944 }
1945 
1946 template <typename T>
1948 {
1949  ocean_assert(isValid());
1950 
1951  return VectorT3<T>(values_[0] * vector[0] + values_[1] * vector[1] + values_[2] * vector[2],
1952  values_[4] * vector[0] + values_[5] * vector[1] + values_[6] * vector[2],
1953  values_[8] * vector[0] + values_[9] * vector[1] + values_[10] * vector[2]);
1954 }
1955 
1956 template <typename T>
1958 {
1959  return isEqual(matrix);
1960 }
1961 
1962 template <typename T>
1964 {
1965  return !(*this == matrix);
1966 }
1967 
1968 template <typename T>
1970 {
1971  ocean_assert(isValid() && matrix.isValid());
1972 
1973  HomogenousMatrixT4<T> result;
1974 
1975  result.values_[0] = values_[0] * matrix.values_[0] + values_[4] * matrix.values_[1] + values_[8] * matrix.values_[2] + values_[12] * matrix.values_[3];
1976  result.values_[1] = values_[1] * matrix.values_[0] + values_[5] * matrix.values_[1] + values_[9] * matrix.values_[2] + values_[13] * matrix.values_[3];
1977  result.values_[2] = values_[2] * matrix.values_[0] + values_[6] * matrix.values_[1] + values_[10] * matrix.values_[2] + values_[14] * matrix.values_[3];
1978  result.values_[3] = T(0.0);
1979 
1980  result.values_[4] = values_[0] * matrix.values_[4] + values_[4] * matrix.values_[5] + values_[8] * matrix.values_[6] + values_[12] * matrix.values_[7];
1981  result.values_[5] = values_[1] * matrix.values_[4] + values_[5] * matrix.values_[5] + values_[9] * matrix.values_[6] + values_[13] * matrix.values_[7];
1982  result.values_[6] = values_[2] * matrix.values_[4] + values_[6] * matrix.values_[5] + values_[10] * matrix.values_[6] + values_[14] * matrix.values_[7];
1983  result.values_[7] = T(0.0);
1984 
1985  result.values_[8] = values_[0] * matrix.values_[8] + values_[4] * matrix.values_[9] + values_[8] * matrix.values_[10] + values_[12] * matrix.values_[11];
1986  result.values_[9] = values_[1] * matrix.values_[8] + values_[5] * matrix.values_[9] + values_[9] * matrix.values_[10] + values_[13] * matrix.values_[11];
1987  result.values_[10] = values_[2] * matrix.values_[8] + values_[6] * matrix.values_[9] + values_[10] * matrix.values_[10] + values_[14] * matrix.values_[11];
1988  result.values_[11] = T(0.0);
1989 
1990  result.values_[12] = values_[0] * matrix.values_[12] + values_[4] * matrix.values_[13] + values_[8] * matrix.values_[14] + values_[12] * matrix.values_[15];
1991  result.values_[13] = values_[1] * matrix.values_[12] + values_[5] * matrix.values_[13] + values_[9] * matrix.values_[14] + values_[13] * matrix.values_[15];
1992  result.values_[14] = values_[2] * matrix.values_[12] + values_[6] * matrix.values_[13] + values_[10] * matrix.values_[14] + values_[14] * matrix.values_[15];
1993  result.values_[15] = T(1.0);
1994 
1995  ocean_assert(result.isValid());
1996 
1997  return result;
1998 }
1999 
2000 template <typename T>
2002 {
2003  *this = *this * matrix;
2004  return *this;
2005 }
2006 
2007 template <typename T>
2009 {
2010  return *this * HomogenousMatrixT4<T>(rotation);
2011 }
2012 
2013 
2014 template <typename T>
2016 {
2017  *this = *this * rotation;
2018  return *this;
2019 }
2020 
2021 template <typename T>
2023 {
2024  return *this * HomogenousMatrixT4<T>(rotation);
2025 }
2026 
2027 template <typename T>
2029 {
2030  *this = *this * rotation;
2031  return *this;
2032 }
2033 
2034 template <typename T>
2036 {
2037  ocean_assert(isValid());
2038 
2039  return VectorT3<T>(values_[0] * vector[0] + values_[4] * vector[1] + values_[8] * vector[2] + values_[12],
2040  values_[1] * vector[0] + values_[5] * vector[1] + values_[9] * vector[2] + values_[13],
2041  values_[2] * vector[0] + values_[6] * vector[1] + values_[10] * vector[2] + values_[14]);
2042 }
2043 
2044 template <typename T>
2046 {
2047  ocean_assert(isValid());
2048 
2049  return VectorT4<T>(values_[0] * vector[0] + values_[4] * vector[1] + values_[8] * vector[2] + values_[12] * vector[3],
2050  values_[1] * vector[0] + values_[5] * vector[1] + values_[9] * vector[2] + values_[13] * vector[3],
2051  values_[2] * vector[0] + values_[6] * vector[1] + values_[10] * vector[2] + values_[14] * vector[3],
2052  vector[3]);
2053 }
2054 
2055 template <typename T>
2056 inline T HomogenousMatrixT4<T>::operator[](const unsigned int index) const
2057 {
2058  ocean_assert(index < 16);
2059  return values_[index];
2060 }
2061 
2062 template <typename T>
2063 inline T& HomogenousMatrixT4<T>::operator[](const unsigned int index)
2064 {
2065  ocean_assert(index < 16u);
2066  return values_[index];
2067 }
2068 
2069 template <typename T>
2070 inline T HomogenousMatrixT4<T>::operator()(const unsigned int row, const unsigned int column) const
2071 {
2072  ocean_assert(row < 4u && column < 4u);
2073  return values_[column * 4u + row];
2074 }
2075 
2076 template <typename T>
2077 inline T& HomogenousMatrixT4<T>::operator()(const unsigned int row, const unsigned int column)
2078 {
2079  ocean_assert(row < 4u && column < 4u);
2080  return values_[column * 4u + row];
2081 }
2082 
2083 template <typename T>
2084 inline T HomogenousMatrixT4<T>::operator()(const unsigned int index) const
2085 {
2086  ocean_assert(index < 16u);
2087  return values_[index];
2088 }
2089 
2090 template <typename T>
2091 inline T& HomogenousMatrixT4<T>::operator()(const unsigned int index)
2092 {
2093  ocean_assert(index < 16u);
2094  return values_[index];
2095 }
2096 
2097 template <typename T>
2098 inline const T* HomogenousMatrixT4<T>::operator()() const
2099 {
2100  return values_;
2101 }
2102 
2103 template <typename T>
2105 {
2106  return values_;
2107 }
2108 
2109 template <typename T>
2111 {
2112  // we skip the value of the lower matrix row, as these values are always [0, 0, 0, 1]
2113 
2114  size_t seed = std::hash<T>{}(matrix.values_[0]);
2115  seed ^= std::hash<T>{}(matrix.values_[1]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2116  seed ^= std::hash<T>{}(matrix.values_[2]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2117 
2118  seed ^= std::hash<T>{}(matrix.values_[4]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2119  seed ^= std::hash<T>{}(matrix.values_[5]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2120  seed ^= std::hash<T>{}(matrix.values_[6]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2121 
2122  seed ^= std::hash<T>{}(matrix.values_[8]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2123  seed ^= std::hash<T>{}(matrix.values_[9]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2124  seed ^= std::hash<T>{}(matrix.values_[10]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2125 
2126  seed ^= std::hash<T>{}(matrix.values_[12]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2127  seed ^= std::hash<T>{}(matrix.values_[13]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2128  seed ^= std::hash<T>{}(matrix.values_[14]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
2129 
2130  return seed;
2131 }
2132 
2133 template <typename T>
2134 template <typename U>
2135 inline std::vector< HomogenousMatrixT4<T> > HomogenousMatrixT4<T>::matrices2matrices(const std::vector< HomogenousMatrixT4<U> >& matrices)
2136 {
2137  std::vector< HomogenousMatrixT4<T> > result;
2138  result.reserve(matrices.size());
2139 
2140  for (typename std::vector< HomogenousMatrixT4<U> >::const_iterator i = matrices.begin(); i != matrices.end(); ++i)
2141  {
2142  result.push_back(HomogenousMatrixT4<T>(*i));
2143  }
2144 
2145  return result;
2146 }
2147 
2148 template <>
2149 template <>
2150 inline std::vector< HomogenousMatrixT4<float> > HomogenousMatrixT4<float>::matrices2matrices(const std::vector< HomogenousMatrixT4<float> >& matrices)
2151 {
2152  return matrices;
2153 }
2154 
2155 template <>
2156 template <>
2157 inline std::vector< HomogenousMatrixT4<double> > HomogenousMatrixT4<double>::matrices2matrices(const std::vector< HomogenousMatrixT4<double> >& matrices)
2158 {
2159  return matrices;
2160 }
2161 
2162 template <typename T>
2163 template <typename U>
2164 inline std::vector< HomogenousMatrixT4<T> > HomogenousMatrixT4<T>::matrices2matrices(const HomogenousMatrixT4<U>* matrices, const size_t size)
2165 {
2166  std::vector< HomogenousMatrixT4<T> > result;
2167  result.reserve(size);
2168 
2169  for (size_t n = 0; n < size; ++n)
2170  {
2171  result.push_back(HomogenousMatrixT4<T>(matrices[n]));
2172  }
2173 
2174  return result;
2175 }
2176 
2177 template <typename T>
2178 std::ostream& operator<<(std::ostream& stream, const HomogenousMatrixT4<T>& matrix)
2179 {
2180  stream << "|" << matrix(0, 0) << ", " << matrix(0, 1) << ", " << matrix(0, 2) << ", " << matrix(0, 3) << "|" << std::endl;
2181  stream << "|" << matrix(1, 0) << ", " << matrix(1, 1) << ", " << matrix(1, 2) << ", " << matrix(1, 3) << "|" << std::endl;
2182  stream << "|" << matrix(2, 0) << ", " << matrix(2, 1) << ", " << matrix(2, 2) << ", " << matrix(2, 3) << "|" << std::endl;
2183  stream << "|" << matrix(3, 0) << ", " << matrix(3, 1) << ", " << matrix(3, 2) << ", " << matrix(3, 3) << "|";
2184 
2185  return stream;
2186 }
2187 
2188 template <bool tActive, typename T>
2189 MessageObject<tActive>& operator<<(MessageObject<tActive>& messageObject, const HomogenousMatrixT4<T>& matrix)
2190 {
2191  return messageObject << "|" << matrix(0, 0) << ", " << matrix(0, 1) << ", " << matrix(0, 2) << ", " << matrix(0, 3) << "|\n|"
2192  << matrix(1, 0) << ", " << matrix(1, 1) << ", " << matrix(1, 2) << ", " << matrix(1, 3) << "|\n|"
2193  << matrix(2, 0) << ", " << matrix(2, 1) << ", " << matrix(2, 2) << ", " << matrix(2, 3) << "|\n|"
2194  << matrix(3, 0) << ", " << matrix(3, 1) << ", " << matrix(3, 2) << ", " << matrix(3, 3) << "|";
2195 }
2196 
2197 template <bool tActive, typename T>
2198 MessageObject<tActive>& operator<<(MessageObject<tActive>&& messageObject, const HomogenousMatrixT4<T>& matrix)
2199 {
2200  return messageObject << "|" << matrix(0, 0) << ", " << matrix(0, 1) << ", " << matrix(0, 2) << ", " << matrix(0, 3) << "|\n|"
2201  << matrix(1, 0) << ", " << matrix(1, 1) << ", " << matrix(1, 2) << ", " << matrix(1, 3) << "|\n|"
2202  << matrix(2, 0) << ", " << matrix(2, 1) << ", " << matrix(2, 2) << ", " << matrix(2, 3) << "|\n|"
2203  << matrix(3, 0) << ", " << matrix(3, 1) << ", " << matrix(3, 2) << ", " << matrix(3, 3) << "|";
2204 }
2205 
2206 }
2207 
2208 #endif // META_OCEAN_MATH_HOMOGENOUS_MATRIX_4_H
This class implements an euler rotation with angles: yaw, pitch and roll.
Definition: Euler.h:80
bool isValid() const
Returns whether the euler rotation holds valid parameters.
Definition: Euler.h:351
HomogenousMatrixT4()
Creates a new default HomogenousMatrixT4 object with undefined elements.
Definition: HomogenousMatrix4.h:719
bool invert()
Inverts the matrix.
Definition: HomogenousMatrix4.h:1591
const T * data() const
Returns a pointer to the internal values.
Definition: HomogenousMatrix4.h:1843
HomogenousMatrixT4(const U *arrayValues, const bool valuesRowAligned)
Creates a new HomogenousMatrixT4 object by an array of at least sixteen elements of float type U.
Definition: HomogenousMatrix4.h:796
friend class HomogenousMatrixT4
Definition: HomogenousMatrix4.h:111
HomogenousMatrixT4(const EulerT< T > &euler)
Creates a new HomogenousMatrixT4 object with only a rotation given as Euler rotation.
Definition: HomogenousMatrix4.h:915
HomogenousMatrixT4(const VectorT3< T > &translation, const QuaternionT< T > &rotation, const VectorT3< T > &scale)
Creates a new HomogenousMatrixT4 object by a translation, rotation and scale.
Definition: HomogenousMatrix4.h:1292
HomogenousMatrixT4(const SquareMatrixT4< T > &matrix)
Creates a new HomogenousMatrixT4 object from a 4x4 square matrix.
Definition: HomogenousMatrix4.h:1001
HomogenousMatrixT4< T > inverted() const noexcept
Returns the inverted of this matrix.
Definition: HomogenousMatrix4.h:1575
VectorT3< T > scale() const
Returns the scale of the transformation.
Definition: HomogenousMatrix4.h:1395
HomogenousMatrixT4< T > & setRotation(const RotationT< T > &rotation)
Sets the rotation of this transformation.
Definition: HomogenousMatrix4.h:1667
VectorT3< T > transposedRotationMatrix(const VectorT3< T > &vector) const
Transforms a 3D vector by application of only the inner transposed rotation matrix (including scale a...
Definition: HomogenousMatrix4.h:1947
SquareMatrixT3< T > rotationMatrix() const
Returns the rotation matrix of the transformation.
Definition: HomogenousMatrix4.h:1493
void copyElements(T *arrayValues, const bool valuesRowAligned=false) const
Copies the elements of this matrix to an array with floating point values of the same type T.
Definition: HomogenousMatrix4.h:1855
HomogenousMatrixT4(const VectorT3< T > &translation)
Creates a new HomogenousMatrixT4 object with only a translation.
Definition: HomogenousMatrix4.h:859
T trace() const
Returns the trace of the matrix which is the sum of the diagonal elements.
Definition: HomogenousMatrix4.h:1650
HomogenousMatrixT4(const T *arrayValues, const bool valuesRowAligned)
Creates a new HomogenousMatrixT4 object by an array of at least sixteen elements.
Definition: HomogenousMatrix4.h:829
HomogenousMatrixT4(const VectorT3< T > &translation, const VectorT3< T > &scale)
Creates a new HomogenousMatrixT4 object by a translation and a scale.
Definition: HomogenousMatrix4.h:1185
VectorT3< T > yAxis() const
Returns the y-axis of the transformation which is the second vector of the upper left 3x3 rotation ma...
Definition: HomogenousMatrix4.h:1367
HomogenousMatrixT4< T > & applyScale(const VectorT3< T > &scale)
Applies new scale values.
Definition: HomogenousMatrix4.h:1749
static std::vector< HomogenousMatrixT4< T > > matrices2matrices(const std::vector< HomogenousMatrixT4< U > > &matrices)
Converts matrices with specific data type to matrices with different data type.
Definition: HomogenousMatrix4.h:2135
HomogenousMatrixT4(const std::pair< VectorT3< T >, RotationT< T >> &translationAndRotation)
Creates a new HomogenousMatrixT4 object with a translation and rotation.
HomogenousMatrixT4(const VectorT3< T > &translation, const SquareMatrixT3< T > &rotation)
Creates a new HomogenousMatrixT4 object with a translation and rotation matrix.
Definition: HomogenousMatrix4.h:1159
T values_[16]
The sixteen values of the transformation matrix.
Definition: HomogenousMatrix4.h:715
HomogenousMatrixT4< T > & setTranslation(const VectorT3< T > &translation)
Sets the translation of this transformation.
Definition: HomogenousMatrix4.h:1657
T operator[](const unsigned int index) const
Element operator.
Definition: HomogenousMatrix4.h:2056
void toNull()
Sets the matrix to a zero matrix (including the lower right element).
Definition: HomogenousMatrix4.h:1795
HomogenousMatrixT4(const VectorT3< T > &translation, const RotationT< T > &rotation, const VectorT3< T > &scale)
Creates a new HomogenousMatrixT4 object by a translation, rotation and scale.
Definition: HomogenousMatrix4.h:1211
HomogenousMatrixT4(const std::pair< VectorT3< T >, QuaternionT< T >> &translationAndRotation)
Creates a new HomogenousMatrixT4 object with a translation and rotation.
HomogenousMatrixT4< T > & operator*=(const HomogenousMatrixT4< T > &matrix)
Combines and assigns two transformation matrices.
Definition: HomogenousMatrix4.h:2001
T determinant() const
Returns the determinant of the matrix.
Definition: HomogenousMatrix4.h:1642
HomogenousMatrixT4(const QuaternionT< T > &rotation)
Creates a new HomogenousMatrixT4 object with only a rotation given as quaternion.
Definition: HomogenousMatrix4.h:945
HomogenousMatrixT4(const VectorT3< T > &translation, const EulerT< T > &euler)
Creates a new HomogenousMatrixT4 object with a translation and rotation.
Definition: HomogenousMatrix4.h:1069
T Type
Definition of the used data type.
Definition: HomogenousMatrix4.h:118
HomogenousMatrixT4(const VectorT3< T > &xAxis, const VectorT3< T > &yAxis, const VectorT3< T > &zAxis)
Creates a new HomogenousMatrixT4 object by three basis vectors.
Definition: HomogenousMatrix4.h:1308
bool isNull() const
Returns whether this matrix is a zero matrix (with all elements equal to zero).
Definition: HomogenousMatrix4.h:1834
void rotationMatrix(T *data, const bool transposed=false) const
Copies the 3x3 rotation matrix elements of the 4x4 transformation.
Definition: HomogenousMatrix4.h:1503
VectorT3< T > xAxis() const
Returns the x-axis of the transformation which is the first vector of the upper left 3x3 rotation mat...
Definition: HomogenousMatrix4.h:1360
HomogenousMatrixT4(const RotationT< T > &rotation)
Creates a new HomogenousMatrixT4 object with only a rotation.
Definition: HomogenousMatrix4.h:885
HomogenousMatrixT4(const VectorT3< T > &translation, const QuaternionT< T > &rotation)
Creates a new HomogenousMatrixT4 object with a translation and rotation.
Definition: HomogenousMatrix4.h:1099
VectorT3< T > translation() const
Returns the translation of the transformation.
Definition: HomogenousMatrix4.h:1381
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition: HomogenousMatrix4.h:1806
HomogenousMatrixT4(const VectorT3< T > &translation, const RotationT< T > &rotation, const VectorT3< T > &scale, const VectorT3< T > &shear)
Creates a new HomogenousMatrixT4 object by a translation, rotation, scale and shear.
Definition: HomogenousMatrix4.h:1269
bool decompose(VectorT3< T > &translation, QuaternionT< T > &rotation, VectorT3< T > &scale, VectorT3< T > &shear) const
Decomposes the transformation matrix into translation, rotation, scale and shear parameters.
Definition: HomogenousMatrix4.h:1407
HomogenousMatrixT4< T > operator*(const HomogenousMatrixT4< T > &matrix) const
Combines two transformation matrices.
Definition: HomogenousMatrix4.h:1969
HomogenousMatrixT4(const U *arrayValues)
Creates a new HomogenousMatrixT4 object by 16 given floating point values of type U.
Definition: HomogenousMatrix4.h:780
QuaternionT< T > rotation() const
Returns the rotation of the transformation as quaternion.
Definition: HomogenousMatrix4.h:1388
bool operator!=(const HomogenousMatrixT4< T > &matrix) const
Returns whether two transformations are not identical up to a small epsilon.
Definition: HomogenousMatrix4.h:1963
void toIdentity()
Sets the matrix to the identity matrix.
Definition: HomogenousMatrix4.h:1769
bool operator==(const HomogenousMatrixT4< T > &matrix) const
Returns whether two transformations are identical up to a small epsilon.
Definition: HomogenousMatrix4.h:1957
bool isIdentity() const
Returns whether this matrix is an identity matrix.
Definition: HomogenousMatrix4.h:1812
bool isEqual(const HomogenousMatrixT4< T > &matrix, const T epsilon=NumericT< T >::eps()) const
Returns whether two matrices are almost identical up to a specified epsilon.
Definition: HomogenousMatrix4.h:1821
HomogenousMatrixT4(const SquareMatrixT3< T > &rotation)
Creates a new HomogenousMatrixT4 object with only a rotation given as 3x3 rotation matrix.
Definition: HomogenousMatrix4.h:975
HomogenousMatrixT4(const VectorT3< T > &translation, const RotationT< T > &rotation)
Creates a new HomogenousMatrixT4 object with a translation and rotation.
Definition: HomogenousMatrix4.h:1009
SquareMatrixT4< T > transposed() const
Returns the transposed of this matrix.
Definition: HomogenousMatrix4.h:1545
SquareMatrixT3< T > orthonormalRotationMatrix() const
Returns the 3x3 orthonormal rotation matrix of the 4x4 transformation (by forcing a orthogonal and no...
Definition: HomogenousMatrix4.h:1538
HomogenousMatrixT4(const bool setToIdentity)
Creates a new HomogenousMatrixT4.
Definition: HomogenousMatrix4.h:741
HomogenousMatrixT4(const VectorT3< T > &xAxis, const VectorT3< T > &yAxis, const VectorT3< T > &zAxis, const VectorT3< T > &translation)
Creates a new HomogenousMatrixT4 object by three basis vectors and a translation vector.
Definition: HomogenousMatrix4.h:1334
const T * operator()() const
Access operator.
Definition: HomogenousMatrix4.h:2098
HomogenousMatrixT4(const HomogenousMatrixT4< U > &matrix)
Copy constructor for a matrix with difference element data type than T.
Definition: HomogenousMatrix4.h:732
HomogenousMatrixT4(const VectorT3< T > &translation, const QuaternionT< T > &rotation, const VectorT3< T > &scale, const VectorT3< T > &shear)
Creates a new HomogenousMatrixT4 object by a translation, rotation, scale and shear.
Definition: HomogenousMatrix4.h:1242
VectorT3< T > zAxis() const
Returns the z-axis of the transformation which is the first vector of the upper left 3x3 rotation mat...
Definition: HomogenousMatrix4.h:1374
HomogenousMatrixT4(const T *arrayValues)
Creates a new HomogenousMatrixT4 object by 16 given floating point values.
Definition: HomogenousMatrix4.h:789
HomogenousMatrixT4(const HomogenousMatrixT4< T > &matrix)
Copy constructor.
Definition: HomogenousMatrix4.h:725
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static constexpr T weakEps()
Returns a weak epsilon.
static T sin(const T value)
Returns the sine of a given value.
Definition: Numeric.h:1568
static constexpr T eps()
Returns a small epsilon.
static bool isEqual(const T first, const T second)
Returns whether two values are equal up to a small epsilon.
Definition: Numeric.h:2386
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition: Numeric.h:2087
static T cos(const T value)
Returns the cosine of a given value.
Definition: Numeric.h:1584
This class implements a unit quaternion rotation.
Definition: Quaternion.h:100
const T & x() const
Returns the x value of the quaternion.
Definition: Quaternion.h:917
bool isValid() const
Returns whether this quaternion is a valid unit quaternion.
Definition: Quaternion.h:899
const T & w() const
Returns the w value of the quaternion.
Definition: Quaternion.h:905
const T & y() const
Returns the y value of the quaternion.
Definition: Quaternion.h:929
const T & z() const
Returns the z value of the quaternion.
Definition: Quaternion.h:941
This class implements a axis-angle rotation using floating point values.
Definition: Rotation.h:79
This class implements a 3x3 square matrix.
Definition: SquareMatrix3.h:88
This class implements a 4x4 square matrix.
Definition: SquareMatrix4.h:85
SquareMatrixT4< T > transposed() const
Returns the transposed of this matrix.
Definition: SquareMatrix4.h:802
This class implements a vector with three elements.
Definition: Vector3.h:97
const T & y() const noexcept
Returns the y value.
Definition: Vector3.h:812
const T & x() const noexcept
Returns the x value.
Definition: Vector3.h:800
const T & z() const noexcept
Returns the z value.
Definition: Vector3.h:824
T length() const
Returns the length of the vector.
Definition: Vector3.h:664
This class implements a vector with four elements.
Definition: Vector4.h:97
std::vector< HomogenousMatrixT4< T > > HomogenousMatricesT4
Definition of a typename alias for vectors with HomogenousMatrixT4 objects.
Definition: HomogenousMatrix4.h:66
std::vector< HomogenousMatrix4 > HomogenousMatrices4
Definition of a vector holding HomogenousMatrix4 objects.
Definition: HomogenousMatrix4.h:73
HomogenousMatrixT4< double > HomogenousMatrixD4
Instantiation of the HomogenousMatrixT4 template class using a double precision float data type.
Definition: HomogenousMatrix4.h:51
std::vector< HomogenousMatrixD4 > HomogenousMatricesD4
Definition of a vector holding HomogenousMatrixD4 objects.
Definition: HomogenousMatrix4.h:79
HomogenousMatrixT4< Scalar > HomogenousMatrix4
Definition of the HomogenousMatrix4 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag eit...
Definition: HomogenousMatrix4.h:37
HomogenousMatrixT4< float > HomogenousMatrixF4
Instantiation of the HomogenousMatrixT4 template class using a float precision float data type.
Definition: HomogenousMatrix4.h:58
std::vector< HomogenousMatrixF4 > HomogenousMatricesF4
Definition of a vector holding HomogenousMatrixF4 objects.
Definition: HomogenousMatrix4.h:85
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15
std::ostream & operator<<(std::ostream &stream, const HighPerformanceStatistic &highPerformanceStatistic)
Definition: HighPerformanceTimer.h:963