1/// @ref gtx_vector_angle
2/// @file glm/gtx/vector_angle.inl
3
4namespace glm
5{
6	template <typename genType>
7	GLM_FUNC_QUALIFIER genType angle
8	(
9		genType const & x,
10		genType const & y
11	)
12	{
13		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'angle' only accept floating-point inputs");
14		return acos(clamp(dot(x, y), genType(-1), genType(1)));
15	}
16
17	template <typename T, precision P, template <typename, precision> class vecType>
18	GLM_FUNC_QUALIFIER T angle
19	(
20		vecType<T, P> const & x,
21		vecType<T, P> const & y
22	)
23	{
24		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'angle' only accept floating-point inputs");
25		return acos(clamp(dot(x, y), T(-1), T(1)));
26	}
27
28	//! \todo epsilon is hard coded to 0.01
29	template <typename T, precision P>
30	GLM_FUNC_QUALIFIER T orientedAngle
31	(
32		tvec2<T, P> const & x,
33		tvec2<T, P> const & y
34	)
35	{
36		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'orientedAngle' only accept floating-point inputs");
37		T const Angle(acos(clamp(dot(x, y), T(-1), T(1))));
38
39		if(all(epsilonEqual(y, glm::rotate(x, Angle), T(0.0001))))
40			return Angle;
41		else
42			return -Angle;
43	}
44
45	template <typename T, precision P>
46	GLM_FUNC_QUALIFIER T orientedAngle
47	(
48		tvec3<T, P> const & x,
49		tvec3<T, P> const & y,
50		tvec3<T, P> const & ref
51	)
52	{
53		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'orientedAngle' only accept floating-point inputs");
54
55		T const Angle(acos(clamp(dot(x, y), T(-1), T(1))));
56		return mix(Angle, -Angle, dot(ref, cross(x, y)) < T(0));
57	}
58}//namespace glm
59