///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2008-08-03
// Updated : 2010-01-26
// Licence : This source is under MIT License
// File : glm/core/func_common.inl
///////////////////////////////////////////////////////////////////////////////////////////////////
namespace glm
{
namespace detail
{
template
struct Abs_
{
};
template
struct Abs_
{
static genFIType get(genFIType const & x)
{
GLM_STATIC_ASSERT(
detail::type::is_float ||
detail::type::is_int, "'abs' only accept floating-point and integer inputs");
return x >= genFIType(0) ? x : -x;
}
};
template
struct Abs_
{
static genFIType get(genFIType const & x)
{
GLM_STATIC_ASSERT(
detail::type::is_uint, "'abs' only accept floating-point and integer inputs");
return x;
}
};
}//namespace detail
namespace core{
namespace function{
namespace common{
// abs
template
GLM_FUNC_QUALIFIER genFIType abs(
genFIType const & x)
{
return detail::Abs_::is_signed>::get(x);
}
//template
//GLM_FUNC_QUALIFIER detail::tvec1 abs(
// detail::tvec1 const & v)
//{
// return detail::tvec1(
// abs(v.x));
//}
template
GLM_FUNC_QUALIFIER detail::tvec2 abs(
detail::tvec2 const & v)
{
return detail::tvec2(
abs(v.x),
abs(v.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 abs(
detail::tvec3 const & v)
{
return detail::tvec3(
abs(v.x),
abs(v.y),
abs(v.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 abs(
detail::tvec4 const & v)
{
return detail::tvec4(
abs(v.x),
abs(v.y),
abs(v.z),
abs(v.w));
}
// sign
//Try something like based on x >> 31 to get the sign bit
template
GLM_FUNC_QUALIFIER genFIType sign(
genFIType const & x)
{
GLM_STATIC_ASSERT(
detail::type::is_float ||
detail::type::is_int, "'sign' only accept signed inputs");
genFIType result;
if(x > genFIType(0))
result = genFIType(1);
else if(x < genFIType(0))
result = genFIType(-1);
else
result = genFIType(0);
return result;
}
template
GLM_FUNC_QUALIFIER detail::tvec2 sign(
detail::tvec2 const & x)
{
return detail::tvec2(
sign(x.x),
sign(x.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 sign(
detail::tvec3 const & x)
{
return detail::tvec3(
sign(x.x),
sign(x.y),
sign(x.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 sign(
detail::tvec4 const & x)
{
return detail::tvec4(
sign(x.x),
sign(x.y),
sign(x.z),
sign(x.w));
}
// floor
template <>
GLM_FUNC_QUALIFIER detail::thalf floor(detail::thalf const& x)
{
return detail::thalf(::std::floor(float(x)));
}
template
GLM_FUNC_QUALIFIER genType floor(genType const& x)
{
GLM_STATIC_ASSERT(detail::type::is_float, "'floor' only accept floating-point inputs");
return ::std::floor(x);
}
template
GLM_FUNC_QUALIFIER detail::tvec2 floor(detail::tvec2 const& x)
{
return detail::tvec2(
floor(x.x),
floor(x.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 floor(detail::tvec3 const& x)
{
return detail::tvec3(
floor(x.x),
floor(x.y),
floor(x.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 floor(detail::tvec4 const& x)
{
return detail::tvec4(
floor(x.x),
floor(x.y),
floor(x.z),
floor(x.w));
}
// trunc
template
GLM_FUNC_QUALIFIER genType trunc(genType const & x)
{
GLM_STATIC_ASSERT(detail::type::is_float, "'trunc' only accept floating-point inputs");
return x < 0 ? -floor(-x) : floor(x);
}
template
GLM_FUNC_QUALIFIER detail::tvec2 trunc(detail::tvec2 const & x)
{
return detail::tvec2(
trunc(x.x),
trunc(x.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 trunc(detail::tvec3 const & x)
{
return detail::tvec3(
trunc(x.x),
trunc(x.y),
trunc(x.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 trunc(detail::tvec4 const & x)
{
return detail::tvec4(
trunc(x.x),
trunc(x.y),
trunc(x.z),
trunc(x.w));
}
// round
template
GLM_FUNC_QUALIFIER genType round(genType const& x)
{
GLM_STATIC_ASSERT(detail::type::is_float, "'round' only accept floating-point inputs");
return genType(int(x + genType(0.5)));
}
template
GLM_FUNC_QUALIFIER detail::tvec2 round(detail::tvec2 const& x)
{
return detail::tvec2(
round(x.x),
round(x.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 round(detail::tvec3 const& x)
{
return detail::tvec3(
round(x.x),
round(x.y),
round(x.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 round(detail::tvec4 const& x)
{
return detail::tvec4(
round(x.x),
round(x.y),
round(x.z),
round(x.w));
}
// roundEven
template
GLM_FUNC_QUALIFIER genType roundEven(genType const& x)
{
GLM_STATIC_ASSERT(detail::type::is_float, "'roundEven' only accept floating-point inputs");
return genType(int(x + genType(int(x) % 2)));
}
template
GLM_FUNC_QUALIFIER detail::tvec2 roundEven(detail::tvec2 const& x)
{
return detail::tvec2(
roundEven(x.x),
roundEven(x.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 roundEven(detail::tvec3 const& x)
{
return detail::tvec3(
roundEven(x.x),
roundEven(x.y),
roundEven(x.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 roundEven(detail::tvec4 const& x)
{
return detail::tvec4(
roundEven(x.x),
roundEven(x.y),
roundEven(x.z),
roundEven(x.w));
}
// ceil
template
GLM_FUNC_QUALIFIER genType ceil(genType const & x)
{
GLM_STATIC_ASSERT(detail::type::is_float, "'ceil' only accept floating-point inputs");
return ::std::ceil(x);
}
template
GLM_FUNC_QUALIFIER detail::tvec2 ceil(detail::tvec2 const & x)
{
return detail::tvec2(
ceil(x.x),
ceil(x.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 ceil(detail::tvec3 const & x)
{
return detail::tvec3(
ceil(x.x),
ceil(x.y),
ceil(x.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 ceil(detail::tvec4 const & x)
{
return detail::tvec4(
ceil(x.x),
ceil(x.y),
ceil(x.z),
ceil(x.w));
}
// fract
template
GLM_FUNC_QUALIFIER genType fract
(
genType const & x
)
{
GLM_STATIC_ASSERT(detail::type::is_float, "'fract' only accept floating-point inputs");
return x - ::std::floor(x);
}
template
GLM_FUNC_QUALIFIER detail::tvec2 fract
(
detail::tvec2 const & x
)
{
return detail::tvec2(
fract(x.x),
fract(x.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 fract
(
detail::tvec3 const & x
)
{
return detail::tvec3(
fract(x.x),
fract(x.y),
fract(x.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 fract
(
detail::tvec4 const & x
)
{
return detail::tvec4(
fract(x.x),
fract(x.y),
fract(x.z),
fract(x.w));
}
// mod
template
GLM_FUNC_QUALIFIER genType mod
(
genType const & x,
genType const & y
)
{
GLM_STATIC_ASSERT(detail::type::is_float, "'mod' only accept floating-point inputs");
return x - y * floor(x / y);
}
template
GLM_FUNC_QUALIFIER detail::tvec2 mod
(
detail::tvec2 const & x,
typename detail::tvec2::value_type const & y
)
{
return detail::tvec2(
mod(x.x, y),
mod(x.y, y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 mod
(
detail::tvec3 const & x,
typename detail::tvec3::value_type const & y
)
{
return detail::tvec3(
mod(x.x, y),
mod(x.y, y),
mod(x.z, y));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 mod
(
detail::tvec4 const & x,
typename detail::tvec4::value_type const & y
)
{
return detail::tvec4(
mod(x.x, y),
mod(x.y, y),
mod(x.z, y),
mod(x.w, y));
}
template
GLM_FUNC_QUALIFIER detail::tvec2 mod
(
detail::tvec2 const & x,
detail::tvec2 const & y
)
{
return detail::tvec2(
mod(x.x, y.x),
mod(x.y, y.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 mod
(
detail::tvec3 const & x,
detail::tvec3 const & y
)
{
return detail::tvec3(
mod(x.x, y.x),
mod(x.y, y.y),
mod(x.z, y.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 mod
(
detail::tvec4 const & x,
detail::tvec4 const & y
)
{
return detail::tvec4(
mod(x.x, y.x),
mod(x.y, y.y),
mod(x.z, y.z),
mod(x.w, y.w));
}
// modf
template
GLM_FUNC_QUALIFIER genType modf
(
genType const & x,
genType & i
)
{
GLM_STATIC_ASSERT(detail::type::is_float, "'modf' only accept floating-point inputs");
i = glm::floor(x);
return x - i;
}
template
GLM_FUNC_QUALIFIER detail::tvec2 modf
(
detail::tvec2 const & x,
detail::tvec2 const & y
)
{
return detail::tvec2(
modf(x.x, y.x),
modf(x.y, y.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 modf
(
detail::tvec3 const & x,
detail::tvec3 const & y
)
{
return detail::tvec3(
modf(x.x, y.x),
modf(x.y, y.y),
modf(x.z, y.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 modf
(
detail::tvec4 const & x,
detail::tvec4 const & y
)
{
return detail::tvec4(
modf(x.x, y.x),
modf(x.y, y.y),
modf(x.z, y.z),
modf(x.w, y.w));
}
//// Only valid if (INT_MIN <= x-y <= INT_MAX)
//// min(x,y)
//r = y + ((x - y) & ((x - y) >> (sizeof(int) *
//CHAR_BIT – 1)));
//// max(x,y)
//r = x - ((x - y) & ((x - y) >> (sizeof(int) *
//CHAR_BIT - 1)));
// min
template
GLM_FUNC_QUALIFIER genType min
(
genType const & x,
genType const & y
)
{
GLM_STATIC_ASSERT(
detail::type::is_float ||
detail::type::is_int ||
detail::type::is_uint, "'min' only accept numbers");
return x < y ? x : y;
}
template
GLM_FUNC_QUALIFIER detail::tvec2 min
(
detail::tvec2 const & x,
typename detail::tvec2::value_type const & y
)
{
return detail::tvec2(
min(x.x, y),
min(x.y, y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 min
(
detail::tvec3 const & x,
typename detail::tvec3::value_type const & y
)
{
return detail::tvec3(
min(x.x, y),
min(x.y, y),
min(x.z, y));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 min
(
detail::tvec4 const & x,
typename detail::tvec4::value_type const & y
)
{
return detail::tvec4(
min(x.x, y),
min(x.y, y),
min(x.z, y),
min(x.w, y));
}
template
GLM_FUNC_QUALIFIER detail::tvec2 min
(
detail::tvec2 const & x,
detail::tvec2 const & y
)
{
return detail::tvec2(
min(x.x, y.x),
min(x.y, y.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 min
(
detail::tvec3 const & x,
detail::tvec3 const & y
)
{
return detail::tvec3(
min(x.x, y.x),
min(x.y, y.y),
min(x.z, y.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 min
(
detail::tvec4 const & x,
detail::tvec4 const & y
)
{
return detail::tvec4(
min(x.x, y.x),
min(x.y, y.y),
min(x.z, y.z),
min(x.w, y.w));
}
// max
template
GLM_FUNC_QUALIFIER genType max
(
genType const & x,
genType const & y
)
{
GLM_STATIC_ASSERT(
detail::type::is_float ||
detail::type::is_int ||
detail::type::is_uint, "'max' only accept numbers");
return x > y ? x : y;
}
template
GLM_FUNC_QUALIFIER detail::tvec2 max
(
detail::tvec2 const & x,
typename detail::tvec2::value_type y
)
{
return detail::tvec2(
max(x.x, y),
max(x.y, y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 max
(
detail::tvec3 const & x,
typename detail::tvec3::value_type y
)
{
return detail::tvec3(
max(x.x, y),
max(x.y, y),
max(x.z, y));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 max
(
detail::tvec4 const & x,
typename detail::tvec4::value_type y
)
{
return detail::tvec4(
max(x.x, y),
max(x.y, y),
max(x.z, y),
max(x.w, y));
}
template
GLM_FUNC_QUALIFIER detail::tvec2 max
(
detail::tvec2 const & x,
detail::tvec2 const & y
)
{
return detail::tvec2(
max(x.x, y.x),
max(x.y, y.y));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 max
(
detail::tvec3 const & x,
detail::tvec3 const & y
)
{
return detail::tvec3(
max(x.x, y.x),
max(x.y, y.y),
max(x.z, y.z));
}
template
GLM_FUNC_QUALIFIER detail::tvec4 max
(
detail::tvec4 const & x,
detail::tvec4 const & y)
{
return detail::tvec4(
max(x.x, y.x),
max(x.y, y.y),
max(x.z, y.z),
max(x.w, y.w));
}
// clamp
template
GLM_FUNC_QUALIFIER valType clamp
(
valType const & x,
valType const & minVal,
valType const & maxVal
)
{
GLM_STATIC_ASSERT(
detail::type::is_float ||
detail::type::is_int ||
detail::type::is_uint, "'clamp' only accept numbers");
// Old implementation, less predictable branching
//if(x >= maxVal) return maxVal;
//if(x <= minVal) return minVal;
//return x;
return glm::max(glm::min(x, maxVal), minVal);
}
template
GLM_FUNC_QUALIFIER detail::tvec2 clamp
(
detail::tvec2 const & x,
typename detail::tvec2::value_type const & minVal,
typename detail::tvec2::value_type const & maxVal
)
{
return detail::tvec2(
clamp(x.x, minVal, maxVal),
clamp(x.y, minVal, maxVal));
}
template
GLM_FUNC_QUALIFIER detail::tvec3 clamp
(
detail::tvec3