1/////////////////////////////////////////////////////////////////////////////////// 2/// OpenGL Mathematics (glm.g-truc.net) 3/// 4/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) 5/// Permission is hereby granted, free of charge, to any person obtaining a copy 6/// of this software and associated documentation files (the "Software"), to deal 7/// in the Software without restriction, including without limitation the rights 8/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9/// copies of the Software, and to permit persons to whom the Software is 10/// furnished to do so, subject to the following conditions: 11/// 12/// The above copyright notice and this permission notice shall be included in 13/// all copies or substantial portions of the Software. 14/// 15/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21/// THE SOFTWARE. 22/// 23/// @ref core 24/// @file glm/core/func_exponential.inl 25/// @date 2008-08-03 / 2011-06-15 26/// @author Christophe Riccio 27/////////////////////////////////////////////////////////////////////////////////// 28 29#include "func_vector_relational.hpp" 30#include "_vectorize.hpp" 31#include <limits> 32#include <cassert> 33 34namespace glm{ 35namespace detail 36{ 37 template <bool isFloat> 38 struct compute_log2 39 { 40 template <typename T> 41 T operator() (T const & Value) const; 42 }; 43 44 template <> 45 struct compute_log2<true> 46 { 47 template <typename T> 48 GLM_FUNC_QUALIFIER T operator() (T const & Value) const 49 { 50 return static_cast<T>(::std::log(Value)) * static_cast<T>(1.4426950408889634073599246810019); 51 } 52 }; 53 54 template <template <class, precision> class vecType, typename T, precision P> 55 struct compute_inversesqrt 56 { 57 GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & x) 58 { 59 return static_cast<T>(1) / sqrt(x); 60 } 61 }; 62 63 template <template <class, precision> class vecType> 64 struct compute_inversesqrt<vecType, float, lowp> 65 { 66 GLM_FUNC_QUALIFIER static vecType<float, lowp> call(vecType<float, lowp> const & x) 67 { 68 vecType<float, lowp> tmp(x); 69 vecType<float, lowp> xhalf(tmp * 0.5f); 70 vecType<uint, lowp>* p = reinterpret_cast<vecType<uint, lowp>*>(const_cast<vecType<float, lowp>*>(&x)); 71 vecType<uint, lowp> i = vecType<uint, lowp>(0x5f375a86) - (*p >> vecType<uint, lowp>(1)); 72 vecType<float, lowp>* ptmp = reinterpret_cast<vecType<float, lowp>*>(&i); 73 tmp = *ptmp; 74 tmp = tmp * (1.5f - xhalf * tmp * tmp); 75 return tmp; 76 } 77 }; 78}//namespace detail 79 80 // pow 81 template <typename genType> 82 GLM_FUNC_QUALIFIER genType pow 83 ( 84 genType const & x, 85 genType const & y 86 ) 87 { 88 GLM_STATIC_ASSERT( 89 std::numeric_limits<genType>::is_iec559, 90 "'pow' only accept floating-point inputs"); 91 92 return std::pow(x, y); 93 } 94 95 VECTORIZE_VEC_VEC(pow) 96 97 // exp 98 template <typename genType> 99 GLM_FUNC_QUALIFIER genType exp 100 ( 101 genType const & x 102 ) 103 { 104 GLM_STATIC_ASSERT( 105 std::numeric_limits<genType>::is_iec559, 106 "'exp' only accept floating-point inputs"); 107 108 return std::exp(x); 109 } 110 111 VECTORIZE_VEC(exp) 112 113 // log 114 template <typename genType> 115 GLM_FUNC_QUALIFIER genType log 116 ( 117 genType const & x 118 ) 119 { 120 GLM_STATIC_ASSERT( 121 std::numeric_limits<genType>::is_iec559, 122 "'log' only accept floating-point inputs"); 123 124 return std::log(x); 125 } 126 127 VECTORIZE_VEC(log) 128 129 //exp2, ln2 = 0.69314718055994530941723212145818f 130 template <typename genType> 131 GLM_FUNC_QUALIFIER genType exp2(genType const & x) 132 { 133 GLM_STATIC_ASSERT( 134 std::numeric_limits<genType>::is_iec559, 135 "'exp2' only accept floating-point inputs"); 136 137 return std::exp(static_cast<genType>(0.69314718055994530941723212145818) * x); 138 } 139 140 VECTORIZE_VEC(exp2) 141 142 // log2, ln2 = 0.69314718055994530941723212145818f 143 template <typename genType> 144 GLM_FUNC_QUALIFIER genType log2(genType x) 145 { 146 GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559 || std::numeric_limits<genType>::is_integer, 147 "GLM core 'log2' only accept floating-point inputs. Include <glm/gtx/integer.hpp> for additional integer support."); 148 149 assert(x > genType(0)); // log2 is only defined on the range (0, inf] 150 return detail::compute_log2<std::numeric_limits<genType>::is_iec559>()(x); 151 } 152 153 VECTORIZE_VEC(log2) 154 155 namespace detail 156 { 157 template <template <class, precision> class vecType, typename T, precision P> 158 struct compute_sqrt{}; 159 160 template <typename T, precision P> 161 struct compute_sqrt<detail::tvec1, T, P> 162 { 163 GLM_FUNC_QUALIFIER static detail::tvec1<T, P> call(detail::tvec1<T, P> const & x) 164 { 165 return detail::tvec1<T, P>(std::sqrt(x.x)); 166 } 167 }; 168 169 template <typename T, precision P> 170 struct compute_sqrt<detail::tvec2, T, P> 171 { 172 GLM_FUNC_QUALIFIER static detail::tvec2<T, P> call(detail::tvec2<T, P> const & x) 173 { 174 return detail::tvec2<T, P>(std::sqrt(x.x), std::sqrt(x.y)); 175 } 176 }; 177 178 template <typename T, precision P> 179 struct compute_sqrt<detail::tvec3, T, P> 180 { 181 GLM_FUNC_QUALIFIER static detail::tvec3<T, P> call(detail::tvec3<T, P> const & x) 182 { 183 return detail::tvec3<T, P>(std::sqrt(x.x), std::sqrt(x.y), std::sqrt(x.z)); 184 } 185 }; 186 187 template <typename T, precision P> 188 struct compute_sqrt<detail::tvec4, T, P> 189 { 190 GLM_FUNC_QUALIFIER static detail::tvec4<T, P> call(detail::tvec4<T, P> const & x) 191 { 192 return detail::tvec4<T, P>(std::sqrt(x.x), std::sqrt(x.y), std::sqrt(x.z), std::sqrt(x.w)); 193 } 194 }; 195 }//namespace detail 196 197 // sqrt 198 GLM_FUNC_QUALIFIER float sqrt(float x) 199 { 200# ifdef __CUDACC__ // Wordaround for a CUDA compiler bug up to CUDA6 201 detail::tvec1<float, highp> tmp(detail::compute_sqrt<detail::tvec1, float, highp>::call(x)); 202 return tmp.x; 203# else 204 return detail::compute_sqrt<detail::tvec1, float, highp>::call(x).x; 205# endif 206 } 207 208 GLM_FUNC_QUALIFIER double sqrt(double x) 209 { 210# ifdef __CUDACC__ // Wordaround for a CUDA compiler bug up to CUDA6 211 detail::tvec1<double, highp> tmp(detail::compute_sqrt<detail::tvec1, double, highp>::call(x)); 212 return tmp.x; 213# else 214 return detail::compute_sqrt<detail::tvec1, double, highp>::call(x).x; 215# endif 216 } 217 218 template <typename T, precision P, template <typename, precision> class vecType> 219 GLM_FUNC_QUALIFIER vecType<T, P> sqrt(vecType<T, P> const & x) 220 { 221 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'sqrt' only accept floating-point inputs"); 222 return detail::compute_sqrt<vecType, T, P>::call(x); 223 } 224 225 // inversesqrt 226 GLM_FUNC_QUALIFIER float inversesqrt(float const & x) 227 { 228 return 1.0f / sqrt(x); 229 } 230 231 GLM_FUNC_QUALIFIER double inversesqrt(double const & x) 232 { 233 return 1.0 / sqrt(x); 234 } 235 236 template <template <class, precision> class vecType, typename T, precision P> 237 GLM_FUNC_QUALIFIER vecType<T, P> inversesqrt 238 ( 239 vecType<T, P> const & x 240 ) 241 { 242 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'inversesqrt' only accept floating-point inputs"); 243 return detail::compute_inversesqrt<vecType, T, P>::call(x); 244 } 245 246 VECTORIZE_VEC(inversesqrt) 247}//namespace glm 248