blob: 767323f74109e7630e98346f71760195133396ae [file] [log] [blame]
Tony-LunarGb0b195d2015-05-13 15:01:06 -06001///////////////////////////////////////////////////////////////////////////////////
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