Home | History | Annotate | Download | only in detail
      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 
     34 namespace glm{
     35 namespace 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