1/// @ref gtx_rotate_vector
2/// @file glm/gtx/rotate_vector.inl
3
4namespace glm
5{
6	template <typename T, precision P>
7	GLM_FUNC_QUALIFIER tvec3<T, P> slerp
8	(
9		tvec3<T, P> const & x,
10		tvec3<T, P> const & y,
11		T const & a
12	)
13	{
14		// get cosine of angle between vectors (-1 -> 1)
15		T CosAlpha = dot(x, y);
16		// get angle (0 -> pi)
17		T Alpha = acos(CosAlpha);
18		// get sine of angle between vectors (0 -> 1)
19		T SinAlpha = sin(Alpha);
20		// this breaks down when SinAlpha = 0, i.e. Alpha = 0 or pi
21		T t1 = sin((static_cast<T>(1) - a) * Alpha) / SinAlpha;
22		T t2 = sin(a * Alpha) / SinAlpha;
23
24		// interpolate src vectors
25		return x * t1 + y * t2;
26	}
27
28	template <typename T, precision P>
29	GLM_FUNC_QUALIFIER tvec2<T, P> rotate
30	(
31		tvec2<T, P> const & v,
32		T const & angle
33	)
34	{
35		tvec2<T, P> Result;
36		T const Cos(cos(angle));
37		T const Sin(sin(angle));
38
39		Result.x = v.x * Cos - v.y * Sin;
40		Result.y = v.x * Sin + v.y * Cos;
41		return Result;
42	}
43
44	template <typename T, precision P>
45	GLM_FUNC_QUALIFIER tvec3<T, P> rotate
46	(
47		tvec3<T, P> const & v,
48		T const & angle,
49		tvec3<T, P> const & normal
50	)
51	{
52		return tmat3x3<T, P>(glm::rotate(angle, normal)) * v;
53	}
54	/*
55	template <typename T, precision P>
56	GLM_FUNC_QUALIFIER tvec3<T, P> rotateGTX(
57		const tvec3<T, P>& x,
58		T angle,
59		const tvec3<T, P>& normal)
60	{
61		const T Cos = cos(radians(angle));
62		const T Sin = sin(radians(angle));
63		return x * Cos + ((x * normal) * (T(1) - Cos)) * normal + cross(x, normal) * Sin;
64	}
65	*/
66	template <typename T, precision P>
67	GLM_FUNC_QUALIFIER tvec4<T, P> rotate
68	(
69		tvec4<T, P> const & v,
70		T const & angle,
71		tvec3<T, P> const & normal
72	)
73	{
74		return rotate(angle, normal) * v;
75	}
76
77	template <typename T, precision P>
78	GLM_FUNC_QUALIFIER tvec3<T, P> rotateX
79	(
80		tvec3<T, P> const & v,
81		T const & angle
82	)
83	{
84		tvec3<T, P> Result(v);
85		T const Cos(cos(angle));
86		T const Sin(sin(angle));
87
88		Result.y = v.y * Cos - v.z * Sin;
89		Result.z = v.y * Sin + v.z * Cos;
90		return Result;
91	}
92
93	template <typename T, precision P>
94	GLM_FUNC_QUALIFIER tvec3<T, P> rotateY
95	(
96		tvec3<T, P> const & v,
97		T const & angle
98	)
99	{
100		tvec3<T, P> Result = v;
101		T const Cos(cos(angle));
102		T const Sin(sin(angle));
103
104		Result.x =  v.x * Cos + v.z * Sin;
105		Result.z = -v.x * Sin + v.z * Cos;
106		return Result;
107	}
108
109	template <typename T, precision P>
110	GLM_FUNC_QUALIFIER tvec3<T, P> rotateZ
111	(
112		tvec3<T, P> const & v,
113		T const & angle
114	)
115	{
116		tvec3<T, P> Result = v;
117		T const Cos(cos(angle));
118		T const Sin(sin(angle));
119
120		Result.x = v.x * Cos - v.y * Sin;
121		Result.y = v.x * Sin + v.y * Cos;
122		return Result;
123	}
124
125	template <typename T, precision P>
126	GLM_FUNC_QUALIFIER tvec4<T, P> rotateX
127	(
128		tvec4<T, P> const & v,
129		T const & angle
130	)
131	{
132		tvec4<T, P> Result = v;
133		T const Cos(cos(angle));
134		T const Sin(sin(angle));
135
136		Result.y = v.y * Cos - v.z * Sin;
137		Result.z = v.y * Sin + v.z * Cos;
138		return Result;
139	}
140
141	template <typename T, precision P>
142	GLM_FUNC_QUALIFIER tvec4<T, P> rotateY
143	(
144		tvec4<T, P> const & v,
145		T const & angle
146	)
147	{
148		tvec4<T, P> Result = v;
149		T const Cos(cos(angle));
150		T const Sin(sin(angle));
151
152		Result.x =  v.x * Cos + v.z * Sin;
153		Result.z = -v.x * Sin + v.z * Cos;
154		return Result;
155	}
156
157	template <typename T, precision P>
158	GLM_FUNC_QUALIFIER tvec4<T, P> rotateZ
159	(
160		tvec4<T, P> const & v,
161		T const & angle
162	)
163	{
164		tvec4<T, P> Result = v;
165		T const Cos(cos(angle));
166		T const Sin(sin(angle));
167
168		Result.x = v.x * Cos - v.y * Sin;
169		Result.y = v.x * Sin + v.y * Cos;
170		return Result;
171	}
172
173	template <typename T, precision P>
174	GLM_FUNC_QUALIFIER tmat4x4<T, P> orientation
175	(
176		tvec3<T, P> const & Normal,
177		tvec3<T, P> const & Up
178	)
179	{
180		if(all(equal(Normal, Up)))
181			return tmat4x4<T, P>(T(1));
182
183		tvec3<T, P> RotationAxis = cross(Up, Normal);
184		T Angle = acos(dot(Normal, Up));
185
186		return rotate(Angle, RotationAxis);
187	}
188}//namespace glm
189