1#include "../detail/_vectorize.hpp"
2
3namespace glm
4{
5	template<length_t L, typename T, qualifier Q>
6	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> min(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& z)
7	{
8		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'min' only accept floating-point or integer inputs");
9		return glm::min(glm::min(x, y), z);
10	}
11
12	template<length_t L, typename T, qualifier Q>
13	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> min(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& z, vec<L, T, Q> const& w)
14	{
15		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'min' only accept floating-point or integer inputs");
16		return glm::min(glm::min(x, y), glm::min(z, w));
17	}
18
19	template<length_t L, typename T, qualifier Q>
20	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> max(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& z)
21	{
22		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'max' only accept floating-point or integer inputs");
23		return glm::max(glm::max(x, y), z);
24	}
25
26	template<length_t L, typename T, qualifier Q>
27	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> max(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& z, vec<L, T, Q> const& w)
28	{
29		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'max' only accept floating-point or integer inputs");
30		return glm::max(glm::max(x, y), glm::max(z, w));
31	}
32
33	template<length_t L, typename T, qualifier Q>
34	GLM_FUNC_QUALIFIER vec<L, T, Q> fmin(vec<L, T, Q> const& a, T b)
35	{
36		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point inputs");
37		return detail::functor2<vec, L, T, Q>::call(fmin, a, vec<L, T, Q>(b));
38	}
39
40	template<length_t L, typename T, qualifier Q>
41	GLM_FUNC_QUALIFIER vec<L, T, Q> fmin(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
42	{
43		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point inputs");
44		return detail::functor2<vec, L, T, Q>::call(fmin, a, b);
45	}
46
47	template<length_t L, typename T, qualifier Q>
48	GLM_FUNC_QUALIFIER vec<L, T, Q> fmin(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c)
49	{
50		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point inputs");
51		return fmin(fmin(a, b), c);
52	}
53
54	template<length_t L, typename T, qualifier Q>
55	GLM_FUNC_QUALIFIER vec<L, T, Q> fmin(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c, vec<L, T, Q> const& d)
56	{
57		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point inputs");
58		return fmin(fmin(a, b), fmin(c, d));
59	}
60
61	template<length_t L, typename T, qualifier Q>
62	GLM_FUNC_QUALIFIER vec<L, T, Q> fmax(vec<L, T, Q> const& a, T b)
63	{
64		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point inputs");
65		return detail::functor2<vec, L, T, Q>::call(fmax, a, vec<L, T, Q>(b));
66	}
67
68	template<length_t L, typename T, qualifier Q>
69	GLM_FUNC_QUALIFIER vec<L, T, Q> fmax(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
70	{
71		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point inputs");
72		return detail::functor2<vec, L, T, Q>::call(fmax, a, b);
73	}
74
75	template<length_t L, typename T, qualifier Q>
76	GLM_FUNC_QUALIFIER vec<L, T, Q> fmax(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c)
77	{
78		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point inputs");
79		return fmax(fmax(a, b), c);
80	}
81
82	template<length_t L, typename T, qualifier Q>
83	GLM_FUNC_QUALIFIER vec<L, T, Q> fmax(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c, vec<L, T, Q> const& d)
84	{
85		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point inputs");
86		return fmax(fmax(a, b), fmax(c, d));
87	}
88
89	template<length_t L, typename T, qualifier Q>
90	GLM_FUNC_QUALIFIER vec<L, T, Q> fclamp(vec<L, T, Q> const& x, T minVal, T maxVal)
91	{
92		return fmin(fmax(x, vec<L, T, Q>(minVal)), vec<L, T, Q>(maxVal));
93	}
94
95	template<length_t L, typename T, qualifier Q>
96	GLM_FUNC_QUALIFIER vec<L, T, Q> fclamp(vec<L, T, Q> const& x, vec<L, T, Q> const& minVal, vec<L, T, Q> const& maxVal)
97	{
98		return fmin(fmax(x, minVal), maxVal);
99	}
100
101	template<length_t L, typename T, qualifier Q>
102	GLM_FUNC_QUALIFIER vec<L, T, Q> clamp(vec<L, T, Q> const& Texcoord)
103	{
104		return glm::clamp(Texcoord, vec<L, T, Q>(0), vec<L, T, Q>(1));
105	}
106
107	template<length_t L, typename T, qualifier Q>
108	GLM_FUNC_QUALIFIER vec<L, T, Q> repeat(vec<L, T, Q> const& Texcoord)
109	{
110		return glm::fract(Texcoord);
111	}
112
113	template<length_t L, typename T, qualifier Q>
114	GLM_FUNC_QUALIFIER vec<L, T, Q> mirrorClamp(vec<L, T, Q> const& Texcoord)
115	{
116		return glm::fract(glm::abs(Texcoord));
117	}
118
119	template<length_t L, typename T, qualifier Q>
120	GLM_FUNC_QUALIFIER vec<L, T, Q> mirrorRepeat(vec<L, T, Q> const& Texcoord)
121	{
122		vec<L, T, Q> const Abs = glm::abs(Texcoord);
123		vec<L, T, Q> const Clamp = glm::mod(glm::floor(Abs), vec<L, T, Q>(2));
124		vec<L, T, Q> const Floor = glm::floor(Abs);
125		vec<L, T, Q> const Rest = Abs - Floor;
126		vec<L, T, Q> const Mirror = Clamp + Rest;
127		return mix(Rest, vec<L, T, Q>(1) - Rest, glm::greaterThanEqual(Mirror, vec<L, T, Q>(1)));
128	}
129}//namespace glm
130