• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/// @ref gtx_matrix_interpolation
2/// @file glm/gtx/matrix_interpolation.hpp
3
4namespace glm
5{
6	template <typename T, precision P>
7	GLM_FUNC_QUALIFIER void axisAngle
8	(
9		tmat4x4<T, P> const & mat,
10		tvec3<T, P> & axis,
11		T & angle
12	)
13	{
14		T epsilon = (T)0.01;
15		T epsilon2 = (T)0.1;
16
17		if((abs(mat[1][0] - mat[0][1]) < epsilon) && (abs(mat[2][0] - mat[0][2]) < epsilon) && (abs(mat[2][1] - mat[1][2]) < epsilon))
18		{
19			if ((abs(mat[1][0] + mat[0][1]) < epsilon2) && (abs(mat[2][0] + mat[0][2]) < epsilon2) && (abs(mat[2][1] + mat[1][2]) < epsilon2) && (abs(mat[0][0] + mat[1][1] + mat[2][2] - (T)3.0) < epsilon2))
20			{
21				angle = (T)0.0;
22				axis.x = (T)1.0;
23				axis.y = (T)0.0;
24				axis.z = (T)0.0;
25				return;
26			}
27			angle = static_cast<T>(3.1415926535897932384626433832795);
28			T xx = (mat[0][0] + (T)1.0) / (T)2.0;
29			T yy = (mat[1][1] + (T)1.0) / (T)2.0;
30			T zz = (mat[2][2] + (T)1.0) / (T)2.0;
31			T xy = (mat[1][0] + mat[0][1]) / (T)4.0;
32			T xz = (mat[2][0] + mat[0][2]) / (T)4.0;
33			T yz = (mat[2][1] + mat[1][2]) / (T)4.0;
34			if((xx > yy) && (xx > zz))
35			{
36				if (xx < epsilon) {
37					axis.x = (T)0.0;
38					axis.y = (T)0.7071;
39					axis.z = (T)0.7071;
40				} else {
41					axis.x = sqrt(xx);
42					axis.y = xy / axis.x;
43					axis.z = xz / axis.x;
44				}
45			}
46			else if (yy > zz)
47			{
48				if (yy < epsilon) {
49					axis.x = (T)0.7071;
50					axis.y = (T)0.0;
51					axis.z = (T)0.7071;
52				} else {
53					axis.y = sqrt(yy);
54					axis.x = xy / axis.y;
55					axis.z = yz / axis.y;
56				}
57			}
58			else
59			{
60				if (zz < epsilon) {
61					axis.x = (T)0.7071;
62					axis.y = (T)0.7071;
63					axis.z = (T)0.0;
64				} else {
65					axis.z = sqrt(zz);
66					axis.x = xz / axis.z;
67					axis.y = yz / axis.z;
68				}
69			}
70			return;
71		}
72		T s = sqrt((mat[2][1] - mat[1][2]) * (mat[2][1] - mat[1][2]) + (mat[2][0] - mat[0][2]) * (mat[2][0] - mat[0][2]) + (mat[1][0] - mat[0][1]) * (mat[1][0] - mat[0][1]));
73		if (glm::abs(s) < T(0.001))
74			s = (T)1.0;
75		angle = acos((mat[0][0] + mat[1][1] + mat[2][2] - (T)1.0) / (T)2.0);
76		axis.x = (mat[1][2] - mat[2][1]) / s;
77		axis.y = (mat[2][0] - mat[0][2]) / s;
78		axis.z = (mat[0][1] - mat[1][0]) / s;
79	}
80
81	template <typename T, precision P>
82	GLM_FUNC_QUALIFIER tmat4x4<T, P> axisAngleMatrix
83	(
84		tvec3<T, P> const & axis,
85		T const angle
86	)
87	{
88		T c = cos(angle);
89		T s = sin(angle);
90		T t = static_cast<T>(1) - c;
91		tvec3<T, P> n = normalize(axis);
92
93		return tmat4x4<T, P>(
94			t * n.x * n.x + c,          t * n.x * n.y + n.z * s,    t * n.x * n.z - n.y * s,    T(0),
95			t * n.x * n.y - n.z * s,    t * n.y * n.y + c,          t * n.y * n.z + n.x * s,    T(0),
96			t * n.x * n.z + n.y * s,    t * n.y * n.z - n.x * s,    t * n.z * n.z + c,          T(0),
97			T(0),                        T(0),                        T(0),                     T(1)
98		);
99	}
100
101	template <typename T, precision P>
102	GLM_FUNC_QUALIFIER tmat4x4<T, P> extractMatrixRotation
103	(
104		tmat4x4<T, P> const & mat
105	)
106	{
107		return tmat4x4<T, P>(
108			mat[0][0], mat[0][1], mat[0][2], 0.0,
109			mat[1][0], mat[1][1], mat[1][2], 0.0,
110			mat[2][0], mat[2][1], mat[2][2], 0.0,
111			0.0,       0.0,       0.0,       1.0
112		);
113	}
114
115	template <typename T, precision P>
116	GLM_FUNC_QUALIFIER tmat4x4<T, P> interpolate
117	(
118		tmat4x4<T, P> const & m1,
119		tmat4x4<T, P> const & m2,
120		T const delta
121	)
122	{
123		tmat4x4<T, P> m1rot = extractMatrixRotation(m1);
124		tmat4x4<T, P> dltRotation = m2 * transpose(m1rot);
125		tvec3<T, P> dltAxis;
126		T dltAngle;
127		axisAngle(dltRotation, dltAxis, dltAngle);
128		tmat4x4<T, P> out = axisAngleMatrix(dltAxis, dltAngle * delta) * m1rot;
129		out[3][0] = m1[3][0] + delta * (m2[3][0] - m1[3][0]);
130		out[3][1] = m1[3][1] + delta * (m2[3][1] - m1[3][1]);
131		out[3][2] = m1[3][2] + delta * (m2[3][2] - m1[3][2]);
132		return out;
133	}
134}//namespace glm
135