fw4spl
MatrixFunctions.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwMath/MatrixFunctions.hpp"
8 
9 #include "fwMath/VectorFunctions.hpp"
10 
11 #include <glm/gtc/matrix_transform.hpp>
12 #include <glm/mat4x4.hpp>
13 
14 namespace fwMath
15 {
16 
17 //------------------------------------------------------------------------------
18 
19 void multVecMatrix(const fwMatrix4x4& matrix, const fwVec3d& source, fwVec3d& dest)
20 {
21  // fwMatrix4x4 is stored row-major
22  // glm matrices are stored column-major
23 
24  ::glm::dmat4x4 mat(matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0],
25  matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1],
26  matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2],
27  matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]);
28 
29  ::glm::dvec4 vec(source[0], source[1], source[2], 1.0);
30  ::glm::dvec4 res = mat * vec;
31 
32  dest[0] = res[0];
33  dest[1] = res[1];
34  dest[2] = res[2];
35 }
36 
37 //------------------------------------------------------------------------------
38 
39 fwMatrix4x4 getInverse( const fwMatrix4x4& matrix )
40 {
41  // fwMatrix4x4 is stored row-major
42  // glm matrices are stored column-major
43 
44  ::glm::dmat4x4 mat(matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0],
45  matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1],
46  matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2],
47  matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]);
48 
49  ::glm::dmat4x4 matInv = ::glm::inverse(mat);
50 
51  fwMatrix4x4 inverse = {matInv[0][0], matInv[1][0], matInv[2][0], matInv[3][0],
52  matInv[0][1], matInv[1][1], matInv[2][1], matInv[3][1],
53  matInv[0][2], matInv[1][2], matInv[2][2], matInv[3][2],
54  matInv[0][3], matInv[1][3], matInv[2][3], matInv[3][3]};
55  return inverse;
56 }
57 
58 //------------------------------------------------------------------------------
59 
60 fwMatrix4x4 getRotationMatrix( const fwVec3d& _vecNorm )
61 {
62  fwMatrix4x4 R;
63 
64  const double FV0 = _vecNorm[0];
65  const double FV1 = _vecNorm[1];
66  const double YP = sqrt( FV0 * FV0 + FV1 * FV1 );
67  const double RZ = -atan2(FV0, FV1);
68  const double RX = -atan2(YP, _vecNorm[2]);
69 
70  // Rotation Matrix
71  // [ cos(z) sin(z) 0 0 ]
72  // [ ]
73  // [ - cos(x) sin(z) cos(x) cos(z) sin(x) 0 ]
74  // [ ]
75  // [ sin(x) sin(z) - sin(x) cos(z) cos(x) 0 ]
76  // [ ]
77  // [ 0 0 0 1 ]
78 
79  R[0][0] = cos(RZ);
80  R[0][1] = sin(RZ);
81  R[0][2] = 0;
82  R[0][3] = 0.;
83 
84  R[1][0] = -cos(RX) * sin(RZ);
85  R[1][1] = cos(RX) * cos(RZ);
86  R[1][2] = sin(RX);
87  R[1][3] = 0.;
88 
89  R[2][0] = sin(RX) * sin(RZ);
90  R[2][1] = -sin(RX) * cos(RZ);
91  R[2][2] = cos(RX);
92  R[2][3] = 0.;
93 
94  R[3][0] = 0.;
95  R[3][1] = 0.;
96  R[3][2] = 0.;
97  R[3][3] = 1.;
98 
99  return R;
100 }
101 
102 //------------------------------------------------------------------------------
103 }
104 
105 //------------------------------------------------------------------------------
106 
107 fwMatrix4x4 operator*( const fwMatrix4x4& matrix1, const fwMatrix4x4& matrix2 )
108 {
109  ::glm::dmat4x4 mat1(matrix1[0][0], matrix1[1][0], matrix1[2][0], matrix1[3][0],
110  matrix1[0][1], matrix1[1][1], matrix1[2][1], matrix1[3][1],
111  matrix1[0][2], matrix1[1][2], matrix1[2][2], matrix1[3][2],
112  matrix1[0][3], matrix1[1][3], matrix1[2][3], matrix1[3][3]);
113 
114  ::glm::dmat4x4 mat2(matrix2[0][0], matrix2[1][0], matrix2[2][0], matrix2[3][0],
115  matrix2[0][1], matrix2[1][1], matrix2[2][1], matrix2[3][1],
116  matrix2[0][2], matrix2[1][2], matrix2[2][2], matrix2[3][2],
117  matrix2[0][3], matrix2[1][3], matrix2[2][3], matrix2[3][3]);
118 
119  ::glm::dmat4x4 prod = mat1 * mat2;
120 
121  fwMatrix4x4 product = {prod[0][0], prod[1][0], prod[2][0], prod[3][0],
122  prod[0][1], prod[1][1], prod[2][1], prod[3][1],
123  prod[0][2], prod[1][2], prod[2][2], prod[3][2],
124  prod[0][3], prod[1][3], prod[2][3], prod[3][3]};
125 
126  return product;
127 }
128 
129 //------------------------------------------------------------------------------
FWMATH_API fwMatrix4x4 getInverse(const fwMatrix4x4 &matrix)
Computes the inverse of a matrix.
The namespace fwMath contains classes which provide the implementation of several mathematic function...
Definition: Compare.hpp:12
FWMATH_API fwMatrix4x4 getRotationMatrix(const fwVec3d &_vecNorm)
Compute a matrix rotation.
FWMATH_API void multVecMatrix(const fwMatrix4x4 &_matrix, const fwVec3d &_source, fwVec3d &_dest)
Multiply a matrix by a vector.