///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 – 2015 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the “Software”), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/func_common.inl
/// @date 2008-08-03 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#include “func_vector_relational.hpp” namespace glm{ template return x >= genFIType(0) ? x : -x; template template return vecType template return vecType template template return static_cast template template template template return (x >> Shift) | y; template // abs template template // sign return detail::compute_sign template return detail::compute_sign // floor // trunc return x < static_cast template // round return x < static_cast template /* return genType(int(x + genType(int(x) % 2))); // roundEven int Integer = static_cast if(FractionalPart > static_cast // ceil // fract return fract(tvec1 template // mod template template // modf return std::modf(x, &i); template template template template //// Only valid if (INT_MIN <= x-y <= INT_MAX)
//// min(x,y)
//r = y + ((x - y) & ((x - y) >> (sizeof(int) * // min return x < y ? x : y;
}
template template // max return x > y ? x : y; template template // clamp return min(max(x, minVal), maxVal); template return min(max(x, minVal), maxVal); template return min(max(x, minVal), maxVal); template template template // step template class vecType, typename T, precision P> return mix(vecType template class vecType, typename T, precision P> // smoothstep genType const tmp(clamp((x – edge0) / (edge1 – edge0), genType(0), genType(1))); template vecType template vecType # if GLM_HAS_CXX11_STL # if GLM_HAS_CXX11_STL return detail::functor1 # if GLM_HAS_CXX11_STL # if GLM_HAS_CXX11_STL return detail::functor1 GLM_FUNC_QUALIFIER int floatBitsToInt(float const & v) template class vecType, precision P> GLM_FUNC_QUALIFIER uint floatBitsToUint(float const & v) template class vecType, precision P> GLM_FUNC_QUALIFIER float intBitsToFloat(int const & v) template class vecType, precision P> GLM_FUNC_QUALIFIER float uintBitsToFloat(uint const & v) template class vecType, precision P> template template return std::frexp(x, exp); template return tvec1 template return tvec2 template return tvec3 template return tvec4 template return std::ldexp(x, exp); template return tvec1 template return tvec2 template return tvec3 template return tvec4
#include “type_vec2.hpp”
#include “type_vec3.hpp”
#include “type_vec4.hpp”
#include “_vectorize.hpp”
#include
namespace detail
{
template
struct compute_abs
{};
struct compute_abs
{
GLM_FUNC_QUALIFIER static genFIType call(genFIType x)
{
GLM_STATIC_ASSERT(
std::numeric_limits
“‘abs’ only accept floating-point and integer scalar or vector inputs”);
// TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff;
}
};
struct compute_abs
{
GLM_FUNC_QUALIFIER static genFIType call(genFIType x)
{
GLM_STATIC_ASSERT(
!std::numeric_limits
“‘abs’ only accept floating-point and integer scalar or vector inputs”);
return x;
}
};
struct compute_mix_vector
{
GLM_FUNC_QUALIFIER static vecType
{
GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, “‘mix’ only accept floating-point inputs for the interpolator a”);
}
};
struct compute_mix_vector
{
GLM_FUNC_QUALIFIER static vecType
{
vecType
for(detail::component_count_t i = 0; i < detail::component_count(x); ++i)
Result[i] = a[i] ? y[i] : x[i];
return Result;
}
};
template
struct compute_mix_scalar
{
GLM_FUNC_QUALIFIER static vecType
{
GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, “‘mix’ only accept floating-point inputs for the interpolator a”);
}
};
struct compute_mix_scalar
{
GLM_FUNC_QUALIFIER static vecType
{
return a ? y : x;
}
};
struct compute_mix
{
GLM_FUNC_QUALIFIER static T call(T const & x, T const & y, U const & a)
{
GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, “‘mix’ only accept floating-point inputs for the interpolator a”);
}
};
struct compute_mix
{
GLM_FUNC_QUALIFIER static T call(T const & x, T const & y, bool const & a)
{
return a ? y : x;
}
};
struct compute_sign
{
GLM_FUNC_QUALIFIER static vecType
{
return vecType
}
};
struct compute_sign
{
GLM_FUNC_QUALIFIER static vecType
{
return vecType
}
};
struct compute_sign
{
GLM_FUNC_QUALIFIER static vecType
{
T const Shift(static_cast
vecType
}
};
struct compute_mod
{
GLM_FUNC_QUALIFIER static vecType
{
GLM_STATIC_ASSERT(std::numeric_limits
return a – b * floor(a / b);
}
};
}//namespace detail
template <>
GLM_FUNC_QUALIFIER int32 abs(int32 x)
{
int32 const y = x >> 31;
return (x ^ y) – y;
}
GLM_FUNC_QUALIFIER genFIType abs(genFIType x)
{
return detail::compute_abs
}
GLM_FUNC_QUALIFIER vecType
{
return detail::functor1
}
// fast and works for any type
template
GLM_FUNC_QUALIFIER genFIType sign(genFIType x)
{
GLM_STATIC_ASSERT(
std::numeric_limits
“‘sign’ only accept signed inputs”);
}
GLM_FUNC_QUALIFIER vecType
{
GLM_STATIC_ASSERT(
std::numeric_limits
“‘sign’ only accept signed inputs”);
}
using ::std::floor;
template
GLM_FUNC_QUALIFIER vecType
{
return detail::functor1
}
# if GLM_HAS_CXX11_STL
using ::std::trunc;
# else
template
GLM_FUNC_QUALIFIER genType trunc(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits
}
# endif
GLM_FUNC_QUALIFIER vecType
{
return detail::functor1
}
# if GLM_HAS_CXX11_STL
using ::std::round;
# else
template
GLM_FUNC_QUALIFIER genType round(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits
}
# endif
GLM_FUNC_QUALIFIER vecType
{
return detail::functor1
}
// roundEven
template
GLM_FUNC_QUALIFIER genType roundEven(genType const& x)
{
GLM_STATIC_ASSERT(std::numeric_limits
}
*/
template
GLM_FUNC_QUALIFIER genType roundEven(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits
genType IntegerPart = static_cast
genType FractionalPart = fract(x);
{
return round(x);
}
else if((Integer % 2) == 0)
{
return IntegerPart;
}
else if(x <= static_cast
{
return IntegerPart – static_cast
}
else
{
return IntegerPart + static_cast
}
//else // Bug on MinGW 4.5.2
//{
// return mix(IntegerPart + genType(-1), IntegerPart + genType(1), x <= genType(0));
//}
}
template
GLM_FUNC_QUALIFIER vecType
{
return detail::functor1
}
using ::std::ceil;
template
GLM_FUNC_QUALIFIER vecType
{
return detail::functor1
}
template
GLM_FUNC_QUALIFIER genType fract(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits
}
GLM_FUNC_QUALIFIER vecType
{
return x – floor(x);
}
template
GLM_FUNC_QUALIFIER genType mod(genType x, genType y)
{
return mod(tvec1
}
GLM_FUNC_QUALIFIER vecType
{
return detail::compute_mod
}
GLM_FUNC_QUALIFIER vecType
{
return detail::compute_mod
}
template
GLM_FUNC_QUALIFIER genType modf(genType x, genType & i)
{
GLM_STATIC_ASSERT(std::numeric_limits
}
GLM_FUNC_QUALIFIER tvec1
{
return tvec1
modf(x.x, i.x));
}
GLM_FUNC_QUALIFIER tvec2
{
return tvec2
modf(x.x, i.x),
modf(x.y, i.y));
}
GLM_FUNC_QUALIFIER tvec3
{
return tvec3
modf(x.x, i.x),
modf(x.y, i.y),
modf(x.z, i.z));
}
GLM_FUNC_QUALIFIER tvec4
{
return tvec4
modf(x.x, i.x),
modf(x.y, i.y),
modf(x.z, i.z),
modf(x.w, i.w));
}
//CHAR_BIT – 1)));
//// max(x,y)
//r = x – ((x – y) & ((x – y) >> (sizeof(int) *
//CHAR_BIT – 1)));
template
GLM_FUNC_QUALIFIER genType min(genType x, genType y)
{
GLM_STATIC_ASSERT(std::numeric_limits
GLM_FUNC_QUALIFIER vecType
{
return detail::functor2_vec_sca
}
GLM_FUNC_QUALIFIER vecType
{
return detail::functor2
}
template
GLM_FUNC_QUALIFIER genType max(genType x, genType y)
{
GLM_STATIC_ASSERT(std::numeric_limits
}
GLM_FUNC_QUALIFIER vecType
{
return detail::functor2_vec_sca
}
GLM_FUNC_QUALIFIER vecType
{
return detail::functor2
}
template
GLM_FUNC_QUALIFIER genType clamp(genType x, genType minVal, genType maxVal)
{
GLM_STATIC_ASSERT(std::numeric_limits
}
GLM_FUNC_QUALIFIER vecType
{
GLM_STATIC_ASSERT(std::numeric_limits
}
GLM_FUNC_QUALIFIER vecType
{
GLM_STATIC_ASSERT(std::numeric_limits
}
GLM_FUNC_QUALIFIER genTypeT mix(genTypeT x, genTypeT y, genTypeU a)
{
return detail::compute_mix
}
GLM_FUNC_QUALIFIER vecType
{
return detail::compute_mix_scalar
}
GLM_FUNC_QUALIFIER vecType
{
return detail::compute_mix_vector
}
template
GLM_FUNC_QUALIFIER genType step(genType edge, genType x)
{
return mix(static_cast
}
GLM_FUNC_QUALIFIER vecType
{
GLM_STATIC_ASSERT(std::numeric_limits
}
GLM_FUNC_QUALIFIER vecType
{
return mix(vecType
}
template
GLM_FUNC_QUALIFIER genType smoothstep(genType edge0, genType edge1, genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits
return tmp * tmp * (genType(3) – genType(2) * tmp);
}
GLM_FUNC_QUALIFIER vecType
{
GLM_STATIC_ASSERT(std::numeric_limits
return tmp * tmp * (static_cast
}
GLM_FUNC_QUALIFIER vecType
{
GLM_STATIC_ASSERT(std::numeric_limits
return tmp * tmp * (static_cast
}
using std::isnan;
# else
template
GLM_FUNC_QUALIFIER bool isnan(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits
return std::isnan(x);
# elif GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_INTEL)
return _isnan(x) != 0;
# elif GLM_COMPILER & (GLM_COMPILER_GCC | (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM))
# if GLM_PLATFORM & GLM_PLATFORM_ANDROID && __cplusplus < 201103L
return _isnan(x) != 0;
# else
return std::isnan(x);
# endif
# elif GLM_COMPILER & GLM_COMPILER_CUDA
return isnan(x) != 0;
# else
return std::isnan(x);
# endif
}
# endif
template
GLM_FUNC_QUALIFIER vecType
{
GLM_STATIC_ASSERT(std::numeric_limits
}
using std::isinf;
# else
template
GLM_FUNC_QUALIFIER bool isinf(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits
return std::isinf(x);
# elif GLM_COMPILER & (GLM_COMPILER_INTEL | GLM_COMPILER_VC)
return _fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF;
# elif GLM_COMPILER & (GLM_COMPILER_GCC | (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM))
# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID && __cplusplus < 201103L)
return _isinf(x) != 0;
# else
return std::isinf(x);
# endif
# elif GLM_COMPILER & GLM_COMPILER_CUDA
// http://developer.download.nvidia.com/compute/cuda/4_2/rel/toolkit/docs/online/group__CUDA__MATH__DOUBLE_g13431dd2b40b51f9139cbb7f50c18fab.html#g13431dd2b40b51f9139cbb7f50c18fab
return isinf(double(x)) != 0;
# else
return std::isinf(x);
# endif
}
# endif
template
GLM_FUNC_QUALIFIER vecType
{
GLM_STATIC_ASSERT(std::numeric_limits
}
{
return reinterpret_cast
}
GLM_FUNC_QUALIFIER vecType
{
return reinterpret_cast
}
{
return reinterpret_cast
}
GLM_FUNC_QUALIFIER vecType
{
return reinterpret_cast
}
{
return reinterpret_cast
}
GLM_FUNC_QUALIFIER vecType
{
return reinterpret_cast
}
{
return reinterpret_cast
}
GLM_FUNC_QUALIFIER vecType
{
return reinterpret_cast
}
GLM_FUNC_QUALIFIER genType fma(genType const & a, genType const & b, genType const & c)
{
return a * b + c;
}
GLM_FUNC_QUALIFIER genType frexp(genType x, int & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits
}
GLM_FUNC_QUALIFIER tvec1
{
GLM_STATIC_ASSERT(std::numeric_limits
}
GLM_FUNC_QUALIFIER tvec2
{
GLM_STATIC_ASSERT(std::numeric_limits
frexp(x.x, exp.x),
frexp(x.y, exp.y));
}
GLM_FUNC_QUALIFIER tvec3
{
GLM_STATIC_ASSERT(std::numeric_limits
frexp(x.x, exp.x),
frexp(x.y, exp.y),
frexp(x.z, exp.z));
}
GLM_FUNC_QUALIFIER tvec4
{
GLM_STATIC_ASSERT(std::numeric_limits
frexp(x.x, exp.x),
frexp(x.y, exp.y),
frexp(x.z, exp.z),
frexp(x.w, exp.w));
}
GLM_FUNC_QUALIFIER genType ldexp(genType const & x, int const & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits
}
GLM_FUNC_QUALIFIER tvec1
{
GLM_STATIC_ASSERT(std::numeric_limits
ldexp(x.x, exp.x));
}
GLM_FUNC_QUALIFIER tvec2
{
GLM_STATIC_ASSERT(std::numeric_limits
ldexp(x.x, exp.x),
ldexp(x.y, exp.y));
}
GLM_FUNC_QUALIFIER tvec3
{
GLM_STATIC_ASSERT(std::numeric_limits
ldexp(x.x, exp.x),
ldexp(x.y, exp.y),
ldexp(x.z, exp.z));
}
GLM_FUNC_QUALIFIER tvec4
{
GLM_STATIC_ASSERT(std::numeric_limits
ldexp(x.x, exp.x),
ldexp(x.y, exp.y),
ldexp(x.z, exp.z),
ldexp(x.w, exp.w));
}
}//namespace glm