/////////////////////////////////////////////////////////////////////////////////////////////////// // 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 inline genFIType abs( genFIType const & x) { return detail::Abs_::is_signed>::get(x); } //template //inline detail::tvec1 abs( // detail::tvec1 const & v) //{ // return detail::tvec1( // abs(v.x)); //} template inline detail::tvec2 abs( detail::tvec2 const & v) { return detail::tvec2( abs(v.x), abs(v.y)); } template inline detail::tvec3 abs( detail::tvec3 const & v) { return detail::tvec3( abs(v.x), abs(v.y), abs(v.z)); } template inline 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 inline 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 inline detail::tvec2 sign( detail::tvec2 const & x) { return detail::tvec2( sign(x.x), sign(x.y)); } template inline detail::tvec3 sign( detail::tvec3 const & x) { return detail::tvec3( sign(x.x), sign(x.y), sign(x.z)); } template inline detail::tvec4 sign( detail::tvec4 const & x) { return detail::tvec4( sign(x.x), sign(x.y), sign(x.z), sign(x.w)); } // floor template <> inline detail::thalf floor(detail::thalf const& x) { return detail::thalf(::std::floor(float(x))); } template inline genType floor(genType const& x) { GLM_STATIC_ASSERT(detail::type::is_float, "'floor' only accept floating-point inputs"); return ::std::floor(x); } template inline detail::tvec2 floor(detail::tvec2 const& x) { return detail::tvec2( floor(x.x), floor(x.y)); } template inline detail::tvec3 floor(detail::tvec3 const& x) { return detail::tvec3( floor(x.x), floor(x.y), floor(x.z)); } template inline detail::tvec4 floor(detail::tvec4 const& x) { return detail::tvec4( floor(x.x), floor(x.y), floor(x.z), floor(x.w)); } // trunc template inline 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 inline detail::tvec2 trunc(detail::tvec2 const & x) { return detail::tvec2( trunc(x.x), trunc(x.y)); } template inline detail::tvec3 trunc(detail::tvec3 const & x) { return detail::tvec3( trunc(x.x), trunc(x.y), trunc(x.z)); } template inline detail::tvec4 trunc(detail::tvec4 const & x) { return detail::tvec4( trunc(x.x), trunc(x.y), trunc(x.z), trunc(x.w)); } // round template inline 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 inline detail::tvec2 round(detail::tvec2 const& x) { return detail::tvec2( round(x.x), round(x.y)); } template inline detail::tvec3 round(detail::tvec3 const& x) { return detail::tvec3( round(x.x), round(x.y), round(x.z)); } template inline detail::tvec4 round(detail::tvec4 const& x) { return detail::tvec4( round(x.x), round(x.y), round(x.z), round(x.w)); } // roundEven template inline 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 inline detail::tvec2 roundEven(detail::tvec2 const& x) { return detail::tvec2( roundEven(x.x), roundEven(x.y)); } template inline detail::tvec3 roundEven(detail::tvec3 const& x) { return detail::tvec3( roundEven(x.x), roundEven(x.y), roundEven(x.z)); } template inline detail::tvec4 roundEven(detail::tvec4 const& x) { return detail::tvec4( roundEven(x.x), roundEven(x.y), roundEven(x.z), roundEven(x.w)); } // ceil template inline genType ceil(genType const & x) { GLM_STATIC_ASSERT(detail::type::is_float, "'ceil' only accept floating-point inputs"); return ::std::ceil(x); } template inline detail::tvec2 ceil(detail::tvec2 const & x) { return detail::tvec2( ceil(x.x), ceil(x.y)); } template inline detail::tvec3 ceil(detail::tvec3 const & x) { return detail::tvec3( ceil(x.x), ceil(x.y), ceil(x.z)); } template inline detail::tvec4 ceil(detail::tvec4 const & x) { return detail::tvec4( ceil(x.x), ceil(x.y), ceil(x.z), ceil(x.w)); } // fract template inline genType fract ( genType const & x ) { GLM_STATIC_ASSERT(detail::type::is_float, "'fract' only accept floating-point inputs"); return x - ::std::floor(x); } template inline detail::tvec2 fract ( detail::tvec2 const & x ) { return detail::tvec2( fract(x.x), fract(x.y)); } template inline detail::tvec3 fract ( detail::tvec3 const & x ) { return detail::tvec3( fract(x.x), fract(x.y), fract(x.z)); } template inline detail::tvec4 fract ( detail::tvec4 const & x ) { return detail::tvec4( fract(x.x), fract(x.y), fract(x.z), fract(x.w)); } // mod template inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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 inline detail::tvec3 clamp ( detail::tvec3 const & x, typename detail::tvec3::value_type const & minVal, typename detail::tvec3::value_type const & maxVal ) { return detail::tvec3( clamp(x.x, minVal, maxVal), clamp(x.y, minVal, maxVal), clamp(x.z, minVal, maxVal)); } template inline detail::tvec4 clamp ( detail::tvec4 const & x, typename detail::tvec4::value_type const & minVal, typename detail::tvec4::value_type const & maxVal ) { return detail::tvec4( clamp(x.x, minVal, maxVal), clamp(x.y, minVal, maxVal), clamp(x.z, minVal, maxVal), clamp(x.w, minVal, maxVal)); } template inline detail::tvec2 clamp ( detail::tvec2 const & x, detail::tvec2 const & minVal, detail::tvec2 const & maxVal ) { return detail::tvec2( clamp(x.x, minVal.x, maxVal.x), clamp(x.y, minVal.y, maxVal.y)); } template inline detail::tvec3 clamp ( detail::tvec3 const & x, detail::tvec3 const & minVal, detail::tvec3 const & maxVal ) { return detail::tvec3( clamp(x.x, minVal.x, maxVal.x), clamp(x.y, minVal.y, maxVal.y), clamp(x.z, minVal.z, maxVal.z)); } template inline detail::tvec4 clamp ( detail::tvec4 const & x, detail::tvec4 const & minVal, detail::tvec4 const & maxVal ) { return detail::tvec4( clamp(x.x, minVal.x, maxVal.x), clamp(x.y, minVal.y, maxVal.y), clamp(x.z, minVal.z, maxVal.z), clamp(x.w, minVal.w, maxVal.w)); } // mix template inline genTypeT mix ( genTypeT const & x, genTypeT const & y, genTypeU const & a ) { // It could be a vector too //GLM_STATIC_ASSERT( // detail::type::is_float && // detail::type::is_float); //return x + a * (y - x); return genTypeT(genTypeU(x) + a * genTypeU(y - x)); } template inline detail::tvec2 mix ( detail::tvec2 const & x, detail::tvec2 const & y, valTypeB const & a ) { return detail::tvec2( detail::tvec2(x) + a * detail::tvec2(y - x)); } template inline detail::tvec3 mix ( detail::tvec3 const & x, detail::tvec3 const & y, valTypeB const & a ) { return detail::tvec3( detail::tvec3(x) + a * detail::tvec3(y - x)); } template inline detail::tvec4 mix ( detail::tvec4 const & x, detail::tvec4 const & y, valTypeB const & a ) { return detail::tvec4( detail::tvec4(x) + a * detail::tvec4(y - x)); } template inline detail::tvec2 mix ( detail::tvec2 const & x, detail::tvec2 const & y, detail::tvec2 const & a ) { return detail::tvec2( detail::tvec2(x) + a * detail::tvec2(y - x)); } template inline detail::tvec3 mix ( detail::tvec3 const & x, detail::tvec3 const & y, detail::tvec3 const & a ) { return detail::tvec3( detail::tvec3(x) + a * detail::tvec3(y - x)); } template inline detail::tvec4 mix ( detail::tvec4 const & x, detail::tvec4 const & y, detail::tvec4 const & a ) { return detail::tvec4( detail::tvec4(x) + a * detail::tvec4(y - x)); } //template //inline genTypeT mix //( // genTypeT const & x, // genTypeT const & y, // float const & a //) //{ // // It could be a vector too // //GLM_STATIC_ASSERT( // // detail::type::is_float && // // detail::type::is_float); // return x + a * (y - x); //} template inline genType mix ( genType const & x, genType const & y, bool a ) { GLM_STATIC_ASSERT(detail::type::is_float, "'mix' only accept floating-point inputs"); return a ? x : y; } template inline detail::tvec2 mix ( detail::tvec2 const & x, detail::tvec2 const & y, typename detail::tvec2::bool_type a ) { GLM_STATIC_ASSERT(detail::type::is_float, "'mix' only accept floating-point inputs"); detail::tvec2 result; for ( typename detail::tvec2::size_type i = 0; i < detail::tvec2::value_size(); ++i ) { result[i] = a[i] ? x[i] : y[i]; } return result; } template inline detail::tvec3 mix ( detail::tvec3 const & x, detail::tvec3 const & y, typename detail::tvec3::bool_type a ) { GLM_STATIC_ASSERT(detail::type::is_float, "'mix' only accept floating-point inputs"); detail::tvec3 result; for ( typename detail::tvec3::size_type i = 0; i < detail::tvec3::value_size(); ++i ) { result[i] = a[i] ? x[i] : y[i]; } return result; } template inline detail::tvec4 mix ( detail::tvec4 const & x, detail::tvec4 const & y, typename detail::tvec4::bool_type a ) { GLM_STATIC_ASSERT(detail::type::is_float, "'mix' only accept floating-point inputs"); detail::tvec4 result; for ( typename detail::tvec4::size_type i = 0; i < detail::tvec4::value_size(); ++i ) { result[i] = a[i] ? x[i] : y[i]; } return result; } // step template inline genType step ( genType const & edge, genType const & x ) { GLM_STATIC_ASSERT(detail::type::is_float, "'mix' only accept floating-point inputs"); return x <= edge ? genType(0) : genType(1); } template inline detail::tvec2 step ( typename detail::tvec2::value_type const & edge, detail::tvec2 const & x ) { return detail::tvec2( x.x <= edge ? T(0) : T(1), x.y <= edge ? T(0) : T(1)); } template inline detail::tvec3 step ( typename detail::tvec3::value_type const & edge, detail::tvec3 const & x ) { return detail::tvec3( x.x <= edge ? T(0) : T(1), x.y <= edge ? T(0) : T(1), x.z <= edge ? T(0) : T(1)); } template inline detail::tvec4 step ( typename detail::tvec4::value_type const & edge, detail::tvec4 const & x ) { return detail::tvec4( x.x <= edge ? T(0) : T(1), x.y <= edge ? T(0) : T(1), x.z <= edge ? T(0) : T(1), x.w <= edge ? T(0) : T(1)); } template inline detail::tvec2 step ( detail::tvec2 const & edge, detail::tvec2 const & x ) { return detail::tvec2( x.x <= edge.x ? T(0) : T(1), x.y <= edge.y ? T(0) : T(1)); } template inline detail::tvec3 step ( detail::tvec3 const & edge, detail::tvec3 const & x ) { return detail::tvec3( x.x <= edge.x ? T(0) : T(1), x.y <= edge.y ? T(0) : T(1), x.z <= edge.z ? T(0) : T(1)); } template inline detail::tvec4 step ( detail::tvec4 const & edge, detail::tvec4 const & x ) { return detail::tvec4( x.x <= edge.x ? T(0) : T(1), x.y <= edge.y ? T(0) : T(1), x.z <= edge.z ? T(0) : T(1), x.w <= edge.w ? T(0) : T(1)); } // smoothstep template inline genType smoothstep ( genType const & edge0, genType const & edge1, genType const & x ) { GLM_STATIC_ASSERT(detail::type::is_float, "'mix' only accept floating-point inputs"); genType tmp = clamp((x - edge0) / (edge1 - edge0), genType(0), genType(1)); return tmp * tmp * (genType(3) - genType(2) * tmp); } template inline detail::tvec2 smoothstep ( typename detail::tvec2::value_type const & edge0, typename detail::tvec2::value_type const & edge1, detail::tvec2 const & x ) { return detail::tvec2( smoothstep(edge0, edge1, x.x), smoothstep(edge0, edge1, x.y)); } template inline detail::tvec3 smoothstep ( typename detail::tvec3::value_type const & edge0, typename detail::tvec3::value_type const & edge1, detail::tvec3 const & x ) { return detail::tvec3( smoothstep(edge0, edge1, x.x), smoothstep(edge0, edge1, x.y), smoothstep(edge0, edge1, x.z)); } template inline detail::tvec4 smoothstep ( typename detail::tvec4::value_type const & edge0, typename detail::tvec4::value_type const & edge1, detail::tvec4 const & x ) { return detail::tvec4( smoothstep(edge0, edge1, x.x), smoothstep(edge0, edge1, x.y), smoothstep(edge0, edge1, x.z), smoothstep(edge0, edge1, x.w)); } template inline detail::tvec2 smoothstep ( detail::tvec2 const & edge0, detail::tvec2 const & edge1, detail::tvec2 const & x ) { return detail::tvec2( smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y)); } template inline detail::tvec3 smoothstep ( detail::tvec3 const & edge0, detail::tvec3 const & edge1, detail::tvec3 const & x ) { return detail::tvec3( smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y), smoothstep(edge0.z, edge1.z, x.z)); } template inline detail::tvec4 smoothstep ( detail::tvec4 const & edge0, detail::tvec4 const & edge1, detail::tvec4 const & x ) { return detail::tvec4( smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y), smoothstep(edge0.z, edge1.z, x.z), smoothstep(edge0.w, edge1.w, x.w)); } template inline typename genType::bool_type isnan ( genType const & x ) { GLM_STATIC_ASSERT(detail::type::is_float, "'mix' only accept floating-point inputs"); #if(GLM_COMPILER & GLM_COMPILER_VC) return typename genType::bool_type(_isnan(x)); #else return typename genType::bool_type(std::isnan(x)); #endif } template inline typename detail::tvec2::bool_type isnan ( detail::tvec2 const & x ) { return typename detail::tvec2::bool_type( isnan(x.x), isnan(x.y)); } template inline typename detail::tvec3::bool_type isnan ( detail::tvec3 const & x ) { return typename detail::tvec3::bool_type( isnan(x.x), isnan(x.y), isnan(x.z)); } template inline typename detail::tvec4::bool_type isnan ( detail::tvec4 const & x ) { return typename detail::tvec4::bool_type( isnan(x.x), isnan(x.y), isnan(x.z), isnan(x.w)); } template inline typename genType::bool_type isinf ( genType const & x ) { GLM_STATIC_ASSERT(detail::type::is_float, "'isinf' only accept floating-point inputs"); #if(GLM_COMPILER & GLM_COMPILER_VC) return typename genType::bool_type(_fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF); #else return typename genType::bool_type(std::isinf(x)); #endif } template inline typename detail::tvec2::bool_type isinf ( detail::tvec2 const & x ) { return typename detail::tvec2::bool_type( isnan(x.x), isnan(x.y)); } template inline typename detail::tvec3::bool_type isinf ( detail::tvec3 const & x ) { return typename detail::tvec3::bool_type( isnan(x.x), isnan(x.y), isnan(x.z)); } template inline typename detail::tvec4::bool_type isinf ( detail::tvec4 const & x ) { return typename detail::tvec4::bool_type( isnan(x.x), isnan(x.y), isnan(x.z), isnan(x.w)); } inline int floatBitsToInt(float const & value) { union { float f; int i; } fi; fi.f = value; return fi.i; } template inline detail::tvec2 floatBitsToInt ( detail::tvec2 const & value ) { return detail::tvec2( floatBitsToInt(value.x), floatBitsToInt(value.y)); } template inline detail::tvec3 floatBitsToInt ( detail::tvec3 const & value ) { return detail::tvec3( floatBitsToInt(value.x), floatBitsToInt(value.y)); } template inline detail::tvec4 floatBitsToInt ( detail::tvec4 const & value ) { return detail::tvec4( floatBitsToInt(value.x), floatBitsToInt(value.y)); } inline uint floatBitsToUint(float const & value) { union { float f; uint u; } fu; fu.f = value; return fu.u; } template inline detail::tvec2 floatBitsToUint ( detail::tvec2 const & value ) { return detail::tvec2( floatBitsToUint(value.x), floatBitsToUint(value.y)); } template inline detail::tvec3 floatBitsToUint ( detail::tvec3 const & value ) { return detail::tvec3( floatBitsToUint(value.x), floatBitsToUint(value.y)); } template inline detail::tvec4 floatBitsToUint ( detail::tvec4 const & value ) { return detail::tvec4( floatBitsToUint(value.x), floatBitsToUint(value.y)); } inline float intBitsToFloat(int const & value) { union { float f; int i; } fi; fi.i = value; return fi.f; } inline float intBitsToFloat(uint const & value) { union { float f; uint u; } fu; fu.u = value; return fu.f; } template inline detail::tvec2 intBitsToFloat ( detail::tvec2 const & value ) { return detail::tvec2( intBitsToFloat(value.x), intBitsToFloat(value.y)); } template inline detail::tvec3 intBitsToFloat ( detail::tvec3 const & value ) { return detail::tvec3( intBitsToFloat(value.x), intBitsToFloat(value.y)); } template inline detail::tvec4 intBitsToFloat ( detail::tvec4 const & value ) { return detail::tvec4( intBitsToFloat(value.x), intBitsToFloat(value.y)); } template inline genType fma ( genType const & a, genType const & b, genType const & c ) { return a * b + c; } template genType frexp ( genType const & x, int & exp ) { return std::frexp(x, exp); } template detail::tvec2 frexp ( detail::tvec2 const & x, detail::tvec2 & exp ) { return std::frexp(x, exp); } template detail::tvec3 frexp ( detail::tvec3 const & x, detail::tvec3 & exp ) { return std::frexp(x, exp); } template detail::tvec4 frexp ( detail::tvec4 const & x, detail::tvec4 & exp ) { return std::frexp(x, exp); } template genType ldexp ( genType const & x, int const & exp ) { return std::frexp(x, exp); } template detail::tvec2 ldexp ( detail::tvec2 const & x, detail::tvec2 const & exp ) { return std::frexp(x, exp); } template detail::tvec3 ldexp ( detail::tvec3 const & x, detail::tvec3 const & exp ) { return std::frexp(x, exp); } template detail::tvec4 ldexp ( detail::tvec4 const & x, detail::tvec4 const & exp ) { return std::frexp(x, exp); } }//namespace common }//namespace function }//namespace core }//namespace glm