~mir-team/mir/in-process-egl+input-conglomeration

« back to all changes in this revision

Viewing changes to 3rd_party/glm/glm/gtx/quaternion.inl

Merged trunk and fixed issues

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
///////////////////////////////////////////////////////////////////////////////////////////////////
2
 
// OpenGL Mathematics Copyright (c) 2005 - 2012 G-Truc Creation (www.g-truc.net)
3
 
///////////////////////////////////////////////////////////////////////////////////////////////////
4
 
// Created : 2005-12-21
5
 
// Updated : 2008-11-27
6
 
// Licence : This source is under MIT License
7
 
// File    : glm/gtx/quaternion.inl
8
 
///////////////////////////////////////////////////////////////////////////////////////////////////
9
 
 
10
 
#include <limits>
11
 
 
12
 
namespace glm
13
 
{
14
 
        template <typename valType> 
15
 
        GLM_FUNC_QUALIFIER detail::tvec3<valType> cross
16
 
        (
17
 
                detail::tvec3<valType> const & v, 
18
 
                detail::tquat<valType> const & q
19
 
        )
20
 
        {
21
 
                return inverse(q) * v;
22
 
        }
23
 
 
24
 
        template <typename valType> 
25
 
        GLM_FUNC_QUALIFIER detail::tvec3<valType> cross
26
 
        (
27
 
                detail::tquat<valType> const & q, 
28
 
                detail::tvec3<valType> const & v
29
 
        )
30
 
        {
31
 
                return q * v;
32
 
        }
33
 
 
34
 
        template <typename T> 
35
 
        GLM_FUNC_QUALIFIER detail::tquat<T> squad
36
 
        (
37
 
                detail::tquat<T> const & q1, 
38
 
                detail::tquat<T> const & q2, 
39
 
                detail::tquat<T> const & s1, 
40
 
                detail::tquat<T> const & s2, 
41
 
                T const & h)
42
 
        {
43
 
                return mix(mix(q1, q2, h), mix(s1, s2, h), T(2) * h (T(1) - h));
44
 
        }
45
 
 
46
 
        template <typename T> 
47
 
        GLM_FUNC_QUALIFIER detail::tquat<T> intermediate
48
 
        (
49
 
                detail::tquat<T> const & prev, 
50
 
                detail::tquat<T> const & curr, 
51
 
                detail::tquat<T> const & next
52
 
        )
53
 
        {
54
 
                detail::tquat<T> invQuat = inverse(curr);
55
 
                return ext((log(next + invQuat) + log(prev + invQuat)) / T(-4)) * curr;
56
 
        }
57
 
 
58
 
        template <typename T> 
59
 
        GLM_FUNC_QUALIFIER detail::tquat<T> exp
60
 
        (
61
 
                detail::tquat<T> const & q, 
62
 
                T const & exponent
63
 
        )
64
 
        {
65
 
                detail::tvec3<T> u(q.x, q.y, q.z);
66
 
                float a = glm::length(u);
67
 
                detail::tvec3<T> v(u / a);
68
 
                return detail::tquat<T>(cos(a), sin(a) * v);
69
 
        }
70
 
 
71
 
        template <typename T> 
72
 
        GLM_FUNC_QUALIFIER detail::tquat<T> log
73
 
        (
74
 
                detail::tquat<T> const & q
75
 
        )
76
 
        {
77
 
                if((q.x == T(0)) && (q.y == T(0)) && (q.z == T(0)))
78
 
                {
79
 
                        if(q.w > T(0))
80
 
                                return detail::tquat<T>(log(q.w), T(0), T(0), T(0));
81
 
                        else if(q.w < T(0))
82
 
                                return detail::tquat<T>(log(-q.w), T(3.1415926535897932384626433832795), T(0),T(0));
83
 
                        else
84
 
                                return detail::tquat<T>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
85
 
                } 
86
 
                else 
87
 
                {
88
 
                        T Vec3Len = sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
89
 
                        T QuatLen = sqrt(Vec3Len * Vec3Len + q.w * q.w);
90
 
                        T t = atan(Vec3Len, T(q.w)) / Vec3Len;
91
 
                        return detail::tquat<T>(t * q.x, t * q.y, t * q.z, log(QuatLen));
92
 
                }
93
 
        }
94
 
 
95
 
        template <typename T> 
96
 
        GLM_FUNC_QUALIFIER detail::tquat<T> pow
97
 
        (
98
 
                detail::tquat<T> const & x, 
99
 
                T const & y
100
 
        )
101
 
        {
102
 
                if(abs(x.w) > T(0.9999))
103
 
                        return x;
104
 
                float Angle = acos(y);
105
 
                float NewAngle = Angle * y;
106
 
                float Div = sin(NewAngle) / sin(Angle);
107
 
                return detail::tquat<T>(
108
 
                        cos(NewAngle),
109
 
                        x.x * Div,
110
 
                        x.y * Div,
111
 
                        x.z * Div);
112
 
        }
113
 
 
114
 
        //template <typename T> 
115
 
        //GLM_FUNC_QUALIFIER detail::tquat<T> sqrt
116
 
        //(
117
 
        //      detail::tquat<T> const & q
118
 
        //)
119
 
        //{
120
 
        //      T q0 = T(1) - dot(q, q);
121
 
        //      return T(2) * (T(1) + q0) * q;
122
 
        //}
123
 
 
124
 
        template <typename T> 
125
 
        GLM_FUNC_QUALIFIER detail::tvec3<T> rotate
126
 
        (
127
 
                detail::tquat<T> const & q, 
128
 
                detail::tvec3<T> const & v
129
 
        )
130
 
        {
131
 
                return q * v;
132
 
        }
133
 
 
134
 
        template <typename T> 
135
 
        GLM_FUNC_QUALIFIER detail::tvec4<T> rotate
136
 
        (
137
 
                detail::tquat<T> const & q, 
138
 
                detail::tvec4<T> const & v
139
 
        )
140
 
        {
141
 
                return q * v;
142
 
        }
143
 
 
144
 
        template <typename T> 
145
 
        GLM_FUNC_QUALIFIER T angle
146
 
        (
147
 
                detail::tquat<T> const & x
148
 
        )
149
 
        {
150
 
                return glm::degrees(acos(x.w) * T(2));
151
 
        }
152
 
 
153
 
        template <typename T> 
154
 
        GLM_FUNC_QUALIFIER detail::tvec3<T> axis
155
 
        (
156
 
                detail::tquat<T> const & x
157
 
        )
158
 
        {
159
 
                T tmp1 = T(1) - x.w * x.w;
160
 
                if(tmp1 <= T(0))
161
 
                        return detail::tvec3<T>(0, 0, 1);
162
 
                T tmp2 = T(1) / sqrt(tmp1);
163
 
                return detail::tvec3<T>(x.x * tmp2, x.y * tmp2, x.z * tmp2);
164
 
        }
165
 
 
166
 
        template <typename valType> 
167
 
        GLM_FUNC_QUALIFIER detail::tquat<valType> angleAxis
168
 
        (
169
 
                valType const & angle, 
170
 
                valType const & x, 
171
 
                valType const & y, 
172
 
                valType const & z
173
 
        )
174
 
        {
175
 
                return angleAxis(angle, detail::tvec3<valType>(x, y, z));
176
 
        }
177
 
 
178
 
        template <typename valType> 
179
 
        GLM_FUNC_QUALIFIER detail::tquat<valType> angleAxis
180
 
        (
181
 
                valType const & angle, 
182
 
                detail::tvec3<valType> const & v
183
 
        )
184
 
        {
185
 
                detail::tquat<valType> result;
186
 
 
187
 
                valType a = glm::radians(angle);
188
 
                valType s = glm::sin(a * valType(0.5));
189
 
 
190
 
                result.w = glm::cos(a * valType(0.5));
191
 
                result.x = v.x * s;
192
 
                result.y = v.y * s;
193
 
                result.z = v.z * s;
194
 
                return result;
195
 
        }
196
 
 
197
 
        template <typename T> 
198
 
        GLM_FUNC_QUALIFIER T extractRealComponent
199
 
        (
200
 
                detail::tquat<T> const & q
201
 
        )
202
 
        {
203
 
                T w = T(1.0) - q.x * q.x - q.y * q.y - q.z * q.z;
204
 
                if(w < T(0))
205
 
                        return T(0);
206
 
                else
207
 
                        return -sqrt(w);
208
 
        }
209
 
 
210
 
        template <typename valType> 
211
 
        GLM_FUNC_QUALIFIER valType roll
212
 
        (
213
 
                detail::tquat<valType> const & q
214
 
        )
215
 
        {
216
 
                return glm::degrees(atan2(valType(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z));
217
 
        }
218
 
 
219
 
        template <typename valType> 
220
 
        GLM_FUNC_QUALIFIER valType pitch
221
 
        (
222
 
                detail::tquat<valType> const & q
223
 
        )
224
 
        {
225
 
                return glm::degrees(atan2(valType(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z));
226
 
        }
227
 
 
228
 
        template <typename valType> 
229
 
        GLM_FUNC_QUALIFIER valType yaw
230
 
        (
231
 
                detail::tquat<valType> const & q
232
 
        )
233
 
        {
234
 
                return glm::degrees(asin(valType(-2) * (q.x * q.z - q.w * q.y)));
235
 
        }
236
 
 
237
 
        template <typename T>
238
 
        GLM_FUNC_QUALIFIER detail::tquat<T> shortMix
239
 
        (
240
 
                detail::tquat<T> const & x, 
241
 
                detail::tquat<T> const & y, 
242
 
                T const & a
243
 
        )
244
 
        {
245
 
                if(a <= typename detail::tquat<T>::value_type(0)) return x;
246
 
                if(a >= typename detail::tquat<T>::value_type(1)) return y;
247
 
 
248
 
                T fCos = dot(x, y);
249
 
                detail::tquat<T> y2(y); //BUG!!! tquat<T> y2;
250
 
                if(fCos < T(0))
251
 
                {
252
 
                        y2 = -y;
253
 
                        fCos = -fCos;
254
 
                }
255
 
 
256
 
                //if(fCos > 1.0f) // problem
257
 
                T k0, k1;
258
 
                if(fCos > T(0.9999))
259
 
                {
260
 
                        k0 = T(1) - a;
261
 
                        k1 = T(0) + a; //BUG!!! 1.0f + a;
262
 
                }
263
 
                else
264
 
                {
265
 
                        T fSin = sqrt(T(1) - fCos * fCos);
266
 
                        T fAngle = atan(fSin, fCos);
267
 
                        T fOneOverSin = T(1) / fSin;
268
 
                        k0 = sin((T(1) - a) * fAngle) * fOneOverSin;
269
 
                        k1 = sin((T(0) + a) * fAngle) * fOneOverSin;
270
 
                }
271
 
 
272
 
                return detail::tquat<T>(
273
 
                        k0 * x.w + k1 * y2.w,
274
 
                        k0 * x.x + k1 * y2.x,
275
 
                        k0 * x.y + k1 * y2.y,
276
 
                        k0 * x.z + k1 * y2.z);
277
 
        }
278
 
 
279
 
        template <typename T>
280
 
        GLM_FUNC_QUALIFIER detail::tquat<T> fastMix
281
 
        (
282
 
                detail::tquat<T> const & x, 
283
 
                detail::tquat<T> const & y, 
284
 
                T const & a
285
 
        )
286
 
        {
287
 
                return glm::normalize(x * (T(1) - a) + (y * a));
288
 
        }
289
 
}//namespace glm