Line | Source Code | Coverage |
---|
1 | /**************************************************************************** | - |
2 | ** | - |
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). | - |
4 | ** Contact: http://www.qt-project.org/legal | - |
5 | ** | - |
6 | ** This file is part of the QtGui module of the Qt Toolkit. | - |
7 | ** | - |
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - |
9 | ** Commercial License Usage | - |
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - |
11 | ** accordance with the commercial license agreement provided with the | - |
12 | ** Software or, alternatively, in accordance with the terms contained in | - |
13 | ** a written agreement between you and Digia. For licensing terms and | - |
14 | ** conditions see http://qt.digia.com/licensing. For further information | - |
15 | ** use the contact form at http://qt.digia.com/contact-us. | - |
16 | ** | - |
17 | ** GNU Lesser General Public License Usage | - |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - |
19 | ** General Public License version 2.1 as published by the Free Software | - |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the | - |
21 | ** packaging of this file. Please review the following information to | - |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements | - |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | - |
24 | ** | - |
25 | ** In addition, as a special exception, Digia gives you certain additional | - |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception | - |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | - |
28 | ** | - |
29 | ** GNU General Public License Usage | - |
30 | ** Alternatively, this file may be used under the terms of the GNU | - |
31 | ** General Public License version 3.0 as published by the Free Software | - |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the | - |
33 | ** packaging of this file. Please review the following information to | - |
34 | ** ensure the GNU General Public License version 3.0 requirements will be | - |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. | - |
36 | ** | - |
37 | ** | - |
38 | ** $QT_END_LICENSE$ | - |
39 | ** | - |
40 | ****************************************************************************/ | - |
41 | | - |
42 | #include "qquaternion.h" | - |
43 | #include <QtCore/qdatastream.h> | - |
44 | #include <QtCore/qmath.h> | - |
45 | #include <QtCore/qvariant.h> | - |
46 | #include <QtCore/qdebug.h> | - |
47 | | - |
48 | #include <cmath> | - |
49 | | - |
50 | QT_BEGIN_NAMESPACE | - |
51 | | - |
52 | #ifndef QT_NO_QUATERNION | - |
53 | | - |
54 | /*! | - |
55 | \class QQuaternion | - |
56 | \brief The QQuaternion class represents a quaternion consisting of a vector and scalar. | - |
57 | \since 4.6 | - |
58 | \ingroup painting-3D | - |
59 | \inmodule QtGui | - |
60 | | - |
61 | Quaternions are used to represent rotations in 3D space, and | - |
62 | consist of a 3D rotation axis specified by the x, y, and z | - |
63 | coordinates, and a scalar representing the rotation angle. | - |
64 | */ | - |
65 | | - |
66 | /*! | - |
67 | \fn QQuaternion::QQuaternion() | - |
68 | | - |
69 | Constructs an identity quaternion, i.e. with coordinates (1, 0, 0, 0). | - |
70 | */ | - |
71 | | - |
72 | /*! | - |
73 | \fn QQuaternion::QQuaternion(float scalar, float xpos, float ypos, float zpos) | - |
74 | | - |
75 | Constructs a quaternion with the vector (\a xpos, \a ypos, \a zpos) | - |
76 | and \a scalar. | - |
77 | */ | - |
78 | | - |
79 | #ifndef QT_NO_VECTOR3D | - |
80 | | - |
81 | /*! | - |
82 | \fn QQuaternion::QQuaternion(float scalar, const QVector3D& vector) | - |
83 | | - |
84 | Constructs a quaternion vector from the specified \a vector and | - |
85 | \a scalar. | - |
86 | | - |
87 | \sa vector(), scalar() | - |
88 | */ | - |
89 | | - |
90 | /*! | - |
91 | \fn QVector3D QQuaternion::vector() const | - |
92 | | - |
93 | Returns the vector component of this quaternion. | - |
94 | | - |
95 | \sa setVector(), scalar() | - |
96 | */ | - |
97 | | - |
98 | /*! | - |
99 | \fn void QQuaternion::setVector(const QVector3D& vector) | - |
100 | | - |
101 | Sets the vector component of this quaternion to \a vector. | - |
102 | | - |
103 | \sa vector(), setScalar() | - |
104 | */ | - |
105 | | - |
106 | #endif | - |
107 | | - |
108 | /*! | - |
109 | \fn void QQuaternion::setVector(float x, float y, float z) | - |
110 | | - |
111 | Sets the vector component of this quaternion to (\a x, \a y, \a z). | - |
112 | | - |
113 | \sa vector(), setScalar() | - |
114 | */ | - |
115 | | - |
116 | #ifndef QT_NO_VECTOR4D | - |
117 | | - |
118 | /*! | - |
119 | \fn QQuaternion::QQuaternion(const QVector4D& vector) | - |
120 | | - |
121 | Constructs a quaternion from the components of \a vector. | - |
122 | */ | - |
123 | | - |
124 | /*! | - |
125 | \fn QVector4D QQuaternion::toVector4D() const | - |
126 | | - |
127 | Returns this quaternion as a 4D vector. | - |
128 | */ | - |
129 | | - |
130 | #endif | - |
131 | | - |
132 | /*! | - |
133 | \fn bool QQuaternion::isNull() const | - |
134 | | - |
135 | Returns true if the x, y, z, and scalar components of this | - |
136 | quaternion are set to 0.0; otherwise returns false. | - |
137 | */ | - |
138 | | - |
139 | /*! | - |
140 | \fn bool QQuaternion::isIdentity() const | - |
141 | | - |
142 | Returns true if the x, y, and z components of this | - |
143 | quaternion are set to 0.0, and the scalar component is set | - |
144 | to 1.0; otherwise returns false. | - |
145 | */ | - |
146 | | - |
147 | /*! | - |
148 | \fn float QQuaternion::x() const | - |
149 | | - |
150 | Returns the x coordinate of this quaternion's vector. | - |
151 | | - |
152 | \sa setX(), y(), z(), scalar() | - |
153 | */ | - |
154 | | - |
155 | /*! | - |
156 | \fn float QQuaternion::y() const | - |
157 | | - |
158 | Returns the y coordinate of this quaternion's vector. | - |
159 | | - |
160 | \sa setY(), x(), z(), scalar() | - |
161 | */ | - |
162 | | - |
163 | /*! | - |
164 | \fn float QQuaternion::z() const | - |
165 | | - |
166 | Returns the z coordinate of this quaternion's vector. | - |
167 | | - |
168 | \sa setZ(), x(), y(), scalar() | - |
169 | */ | - |
170 | | - |
171 | /*! | - |
172 | \fn float QQuaternion::scalar() const | - |
173 | | - |
174 | Returns the scalar component of this quaternion. | - |
175 | | - |
176 | \sa setScalar(), x(), y(), z() | - |
177 | */ | - |
178 | | - |
179 | /*! | - |
180 | \fn void QQuaternion::setX(float x) | - |
181 | | - |
182 | Sets the x coordinate of this quaternion's vector to the given | - |
183 | \a x coordinate. | - |
184 | | - |
185 | \sa x(), setY(), setZ(), setScalar() | - |
186 | */ | - |
187 | | - |
188 | /*! | - |
189 | \fn void QQuaternion::setY(float y) | - |
190 | | - |
191 | Sets the y coordinate of this quaternion's vector to the given | - |
192 | \a y coordinate. | - |
193 | | - |
194 | \sa y(), setX(), setZ(), setScalar() | - |
195 | */ | - |
196 | | - |
197 | /*! | - |
198 | \fn void QQuaternion::setZ(float z) | - |
199 | | - |
200 | Sets the z coordinate of this quaternion's vector to the given | - |
201 | \a z coordinate. | - |
202 | | - |
203 | \sa z(), setX(), setY(), setScalar() | - |
204 | */ | - |
205 | | - |
206 | /*! | - |
207 | \fn void QQuaternion::setScalar(float scalar) | - |
208 | | - |
209 | Sets the scalar component of this quaternion to \a scalar. | - |
210 | | - |
211 | \sa scalar(), setX(), setY(), setZ() | - |
212 | */ | - |
213 | | - |
214 | /*! | - |
215 | Returns the length of the quaternion. This is also called the "norm". | - |
216 | | - |
217 | \sa lengthSquared(), normalized() | - |
218 | */ | - |
219 | float QQuaternion::length() const | - |
220 | { | - |
221 | return qSqrt(xp * xp + yp * yp + zp * zp + wp * wp); executed: return qSqrt(xp * xp + yp * yp + zp * zp + wp * wp); Execution Count:28 | 28 |
222 | } | - |
223 | | - |
224 | /*! | - |
225 | Returns the squared length of the quaternion. | - |
226 | | - |
227 | \sa length() | - |
228 | */ | - |
229 | float QQuaternion::lengthSquared() const | - |
230 | { | - |
231 | return xp * xp + yp * yp + zp * zp + wp * wp; executed: return xp * xp + yp * yp + zp * zp + wp * wp; Execution Count:10 | 10 |
232 | } | - |
233 | | - |
234 | /*! | - |
235 | Returns the normalized unit form of this quaternion. | - |
236 | | - |
237 | If this quaternion is null, then a null quaternion is returned. | - |
238 | If the length of the quaternion is very close to 1, then the quaternion | - |
239 | will be returned as-is. Otherwise the normalized form of the | - |
240 | quaternion of length 1 will be returned. | - |
241 | | - |
242 | \sa length(), normalize() | - |
243 | */ | - |
244 | QQuaternion QQuaternion::normalized() const | - |
245 | { | - |
246 | // Need some extra precision if the length is very small. | - |
247 | double len = double(xp) * double(xp) + executed (the execution status of this line is deduced): double len = double(xp) * double(xp) + | - |
248 | double(yp) * double(yp) + executed (the execution status of this line is deduced): double(yp) * double(yp) + | - |
249 | double(zp) * double(zp) + executed (the execution status of this line is deduced): double(zp) * double(zp) + | - |
250 | double(wp) * double(wp); executed (the execution status of this line is deduced): double(wp) * double(wp); | - |
251 | if (qFuzzyIsNull(len - 1.0f)) evaluated: qFuzzyIsNull(len - 1.0f) yes Evaluation Count:18 | yes Evaluation Count:61 |
| 18-61 |
252 | return *this; executed: return *this; Execution Count:18 | 18 |
253 | else if (!qFuzzyIsNull(len)) evaluated: !qFuzzyIsNull(len) yes Evaluation Count:60 | yes Evaluation Count:1 |
| 1-60 |
254 | return *this / qSqrt(len); executed: return *this / qSqrt(len); Execution Count:60 | 60 |
255 | else | - |
256 | return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f); executed: return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f); Execution Count:1 | 1 |
257 | } | - |
258 | | - |
259 | /*! | - |
260 | Normalizes the currect quaternion in place. Nothing happens if this | - |
261 | is a null quaternion or the length of the quaternion is very close to 1. | - |
262 | | - |
263 | \sa length(), normalized() | - |
264 | */ | - |
265 | void QQuaternion::normalize() | - |
266 | { | - |
267 | // Need some extra precision if the length is very small. | - |
268 | double len = double(xp) * double(xp) + executed (the execution status of this line is deduced): double len = double(xp) * double(xp) + | - |
269 | double(yp) * double(yp) + executed (the execution status of this line is deduced): double(yp) * double(yp) + | - |
270 | double(zp) * double(zp) + executed (the execution status of this line is deduced): double(zp) * double(zp) + | - |
271 | double(wp) * double(wp); executed (the execution status of this line is deduced): double(wp) * double(wp); | - |
272 | if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) evaluated: qFuzzyIsNull(len - 1.0f) yes Evaluation Count:8 | yes Evaluation Count:2 |
evaluated: qFuzzyIsNull(len) yes Evaluation Count:1 | yes Evaluation Count:1 |
| 1-8 |
273 | return; executed: return; Execution Count:9 | 9 |
274 | | - |
275 | len = qSqrt(len); executed (the execution status of this line is deduced): len = qSqrt(len); | - |
276 | | - |
277 | xp /= len; executed (the execution status of this line is deduced): xp /= len; | - |
278 | yp /= len; executed (the execution status of this line is deduced): yp /= len; | - |
279 | zp /= len; executed (the execution status of this line is deduced): zp /= len; | - |
280 | wp /= len; executed (the execution status of this line is deduced): wp /= len; | - |
281 | } executed: } Execution Count:1 | 1 |
282 | | - |
283 | /*! | - |
284 | \fn QQuaternion QQuaternion::conjugate() const | - |
285 | | - |
286 | Returns the conjugate of this quaternion, which is | - |
287 | (-x, -y, -z, scalar). | - |
288 | */ | - |
289 | | - |
290 | /*! | - |
291 | Rotates \a vector with this quaternion to produce a new vector | - |
292 | in 3D space. The following code: | - |
293 | | - |
294 | \code | - |
295 | QVector3D result = q.rotatedVector(vector); | - |
296 | \endcode | - |
297 | | - |
298 | is equivalent to the following: | - |
299 | | - |
300 | \code | - |
301 | QVector3D result = (q * QQuaternion(0, vector) * q.conjugate()).vector(); | - |
302 | \endcode | - |
303 | */ | - |
304 | QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const | - |
305 | { | - |
306 | return (*this * QQuaternion(0, vector) * conjugate()).vector(); executed: return (*this * QQuaternion(0, vector) * conjugate()).vector(); Execution Count:8 | 8 |
307 | } | - |
308 | | - |
309 | /*! | - |
310 | \fn QQuaternion &QQuaternion::operator+=(const QQuaternion &quaternion) | - |
311 | | - |
312 | Adds the given \a quaternion to this quaternion and returns a reference to | - |
313 | this quaternion. | - |
314 | | - |
315 | \sa operator-=() | - |
316 | */ | - |
317 | | - |
318 | /*! | - |
319 | \fn QQuaternion &QQuaternion::operator-=(const QQuaternion &quaternion) | - |
320 | | - |
321 | Subtracts the given \a quaternion from this quaternion and returns a | - |
322 | reference to this quaternion. | - |
323 | | - |
324 | \sa operator+=() | - |
325 | */ | - |
326 | | - |
327 | /*! | - |
328 | \fn QQuaternion &QQuaternion::operator*=(float factor) | - |
329 | | - |
330 | Multiplies this quaternion's components by the given \a factor, and | - |
331 | returns a reference to this quaternion. | - |
332 | | - |
333 | \sa operator/=() | - |
334 | */ | - |
335 | | - |
336 | /*! | - |
337 | \fn QQuaternion &QQuaternion::operator*=(const QQuaternion &quaternion) | - |
338 | | - |
339 | Multiplies this quaternion by \a quaternion and returns a reference | - |
340 | to this quaternion. | - |
341 | */ | - |
342 | | - |
343 | /*! | - |
344 | \fn QQuaternion &QQuaternion::operator/=(float divisor) | - |
345 | | - |
346 | Divides this quaternion's components by the given \a divisor, and | - |
347 | returns a reference to this quaternion. | - |
348 | | - |
349 | \sa operator*=() | - |
350 | */ | - |
351 | | - |
352 | #ifndef QT_NO_VECTOR3D | - |
353 | | - |
354 | /*! | - |
355 | Creates a normalized quaternion that corresponds to rotating through | - |
356 | \a angle degrees about the specified 3D \a axis. | - |
357 | */ | - |
358 | QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, float angle) | - |
359 | { | - |
360 | // Algorithm from: | - |
361 | // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q56 | - |
362 | // We normalize the result just in case the values are close | - |
363 | // to zero, as suggested in the above FAQ. | - |
364 | float a = (angle / 2.0f) * M_PI / 180.0f; executed (the execution status of this line is deduced): float a = (angle / 2.0f) * 3.14159265358979323846 / 180.0f; | - |
365 | float s = sinf(a); executed (the execution status of this line is deduced): float s = sinf(a); | - |
366 | float c = cosf(a); executed (the execution status of this line is deduced): float c = cosf(a); | - |
367 | QVector3D ax = axis.normalized(); executed (the execution status of this line is deduced): QVector3D ax = axis.normalized(); | - |
368 | return QQuaternion(c, ax.x() * s, ax.y() * s, ax.z() * s).normalized(); executed: return QQuaternion(c, ax.x() * s, ax.y() * s, ax.z() * s).normalized(); Execution Count:21 | 21 |
369 | } | - |
370 | | - |
371 | #endif | - |
372 | | - |
373 | /*! | - |
374 | Creates a normalized quaternion that corresponds to rotating through | - |
375 | \a angle degrees about the 3D axis (\a x, \a y, \a z). | - |
376 | */ | - |
377 | QQuaternion QQuaternion::fromAxisAndAngle | - |
378 | (float x, float y, float z, float angle) | - |
379 | { | - |
380 | float length = qSqrt(x * x + y * y + z * z); executed (the execution status of this line is deduced): float length = qSqrt(x * x + y * y + z * z); | - |
381 | if (!qFuzzyIsNull(length - 1.0f) && !qFuzzyIsNull(length)) { evaluated: !qFuzzyIsNull(length - 1.0f) yes Evaluation Count:32 | yes Evaluation Count:3 |
evaluated: !qFuzzyIsNull(length) yes Evaluation Count:31 | yes Evaluation Count:1 |
| 1-32 |
382 | x /= length; executed (the execution status of this line is deduced): x /= length; | - |
383 | y /= length; executed (the execution status of this line is deduced): y /= length; | - |
384 | z /= length; executed (the execution status of this line is deduced): z /= length; | - |
385 | } executed: } Execution Count:31 | 31 |
386 | float a = (angle / 2.0f) * M_PI / 180.0f; executed (the execution status of this line is deduced): float a = (angle / 2.0f) * 3.14159265358979323846 / 180.0f; | - |
387 | float s = sinf(a); executed (the execution status of this line is deduced): float s = sinf(a); | - |
388 | float c = cosf(a); executed (the execution status of this line is deduced): float c = cosf(a); | - |
389 | return QQuaternion(c, x * s, y * s, z * s).normalized(); executed: return QQuaternion(c, x * s, y * s, z * s).normalized(); Execution Count:35 | 35 |
390 | } | - |
391 | | - |
392 | /*! | - |
393 | \fn bool operator==(const QQuaternion &q1, const QQuaternion &q2) | - |
394 | \relates QQuaternion | - |
395 | | - |
396 | Returns true if \a q1 is equal to \a q2; otherwise returns false. | - |
397 | This operator uses an exact floating-point comparison. | - |
398 | */ | - |
399 | | - |
400 | /*! | - |
401 | \fn bool operator!=(const QQuaternion &q1, const QQuaternion &q2) | - |
402 | \relates QQuaternion | - |
403 | | - |
404 | Returns true if \a q1 is not equal to \a q2; otherwise returns false. | - |
405 | This operator uses an exact floating-point comparison. | - |
406 | */ | - |
407 | | - |
408 | /*! | - |
409 | \fn const QQuaternion operator+(const QQuaternion &q1, const QQuaternion &q2) | - |
410 | \relates QQuaternion | - |
411 | | - |
412 | Returns a QQuaternion object that is the sum of the given quaternions, | - |
413 | \a q1 and \a q2; each component is added separately. | - |
414 | | - |
415 | \sa QQuaternion::operator+=() | - |
416 | */ | - |
417 | | - |
418 | /*! | - |
419 | \fn const QQuaternion operator-(const QQuaternion &q1, const QQuaternion &q2) | - |
420 | \relates QQuaternion | - |
421 | | - |
422 | Returns a QQuaternion object that is formed by subtracting | - |
423 | \a q2 from \a q1; each component is subtracted separately. | - |
424 | | - |
425 | \sa QQuaternion::operator-=() | - |
426 | */ | - |
427 | | - |
428 | /*! | - |
429 | \fn const QQuaternion operator*(float factor, const QQuaternion &quaternion) | - |
430 | \relates QQuaternion | - |
431 | | - |
432 | Returns a copy of the given \a quaternion, multiplied by the | - |
433 | given \a factor. | - |
434 | | - |
435 | \sa QQuaternion::operator*=() | - |
436 | */ | - |
437 | | - |
438 | /*! | - |
439 | \fn const QQuaternion operator*(const QQuaternion &quaternion, float factor) | - |
440 | \relates QQuaternion | - |
441 | | - |
442 | Returns a copy of the given \a quaternion, multiplied by the | - |
443 | given \a factor. | - |
444 | | - |
445 | \sa QQuaternion::operator*=() | - |
446 | */ | - |
447 | | - |
448 | /*! | - |
449 | \fn const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2) | - |
450 | \relates QQuaternion | - |
451 | | - |
452 | Multiplies \a q1 and \a q2 using quaternion multiplication. | - |
453 | The result corresponds to applying both of the rotations specified | - |
454 | by \a q1 and \a q2. | - |
455 | | - |
456 | \sa QQuaternion::operator*=() | - |
457 | */ | - |
458 | | - |
459 | /*! | - |
460 | \fn const QQuaternion operator-(const QQuaternion &quaternion) | - |
461 | \relates QQuaternion | - |
462 | \overload | - |
463 | | - |
464 | Returns a QQuaternion object that is formed by changing the sign of | - |
465 | all three components of the given \a quaternion. | - |
466 | | - |
467 | Equivalent to \c {QQuaternion(0,0,0,0) - quaternion}. | - |
468 | */ | - |
469 | | - |
470 | /*! | - |
471 | \fn const QQuaternion operator/(const QQuaternion &quaternion, float divisor) | - |
472 | \relates QQuaternion | - |
473 | | - |
474 | Returns the QQuaternion object formed by dividing all components of | - |
475 | the given \a quaternion by the given \a divisor. | - |
476 | | - |
477 | \sa QQuaternion::operator/=() | - |
478 | */ | - |
479 | | - |
480 | /*! | - |
481 | \fn bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2) | - |
482 | \relates QQuaternion | - |
483 | | - |
484 | Returns true if \a q1 and \a q2 are equal, allowing for a small | - |
485 | fuzziness factor for floating-point comparisons; false otherwise. | - |
486 | */ | - |
487 | | - |
488 | /*! | - |
489 | Interpolates along the shortest spherical path between the | - |
490 | rotational positions \a q1 and \a q2. The value \a t should | - |
491 | be between 0 and 1, indicating the spherical distance to travel | - |
492 | between \a q1 and \a q2. | - |
493 | | - |
494 | If \a t is less than or equal to 0, then \a q1 will be returned. | - |
495 | If \a t is greater than or equal to 1, then \a q2 will be returned. | - |
496 | | - |
497 | \sa nlerp() | - |
498 | */ | - |
499 | QQuaternion QQuaternion::slerp | - |
500 | (const QQuaternion& q1, const QQuaternion& q2, float t) | - |
501 | { | - |
502 | // Handle the easy cases first. | - |
503 | if (t <= 0.0f) evaluated: t <= 0.0f yes Evaluation Count:2 | yes Evaluation Count:4 |
| 2-4 |
504 | return q1; executed: return q1; Execution Count:2 | 2 |
505 | else if (t >= 1.0f) evaluated: t >= 1.0f yes Evaluation Count:2 | yes Evaluation Count:2 |
| 2 |
506 | return q2; executed: return q2; Execution Count:2 | 2 |
507 | | - |
508 | // Determine the angle between the two quaternions. | - |
509 | QQuaternion q2b; executed (the execution status of this line is deduced): QQuaternion q2b; | - |
510 | float dot; executed (the execution status of this line is deduced): float dot; | - |
511 | dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; executed (the execution status of this line is deduced): dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; | - |
512 | if (dot >= 0.0f) { evaluated: dot >= 0.0f yes Evaluation Count:1 | yes Evaluation Count:1 |
| 1 |
513 | q2b = q2; executed (the execution status of this line is deduced): q2b = q2; | - |
514 | } else { executed: } Execution Count:1 | 1 |
515 | q2b = -q2; executed (the execution status of this line is deduced): q2b = -q2; | - |
516 | dot = -dot; executed (the execution status of this line is deduced): dot = -dot; | - |
517 | } executed: } Execution Count:1 | 1 |
518 | | - |
519 | // Get the scale factors. If they are too small, | - |
520 | // then revert to simple linear interpolation. | - |
521 | float factor1 = 1.0f - t; executed (the execution status of this line is deduced): float factor1 = 1.0f - t; | - |
522 | float factor2 = t; executed (the execution status of this line is deduced): float factor2 = t; | - |
523 | if ((1.0f - dot) > 0.0000001) { partially evaluated: (1.0f - dot) > 0.0000001 yes Evaluation Count:2 | no Evaluation Count:0 |
| 0-2 |
524 | float angle = acosf(dot); executed (the execution status of this line is deduced): float angle = acosf(dot); | - |
525 | float sinOfAngle = sinf(angle); executed (the execution status of this line is deduced): float sinOfAngle = sinf(angle); | - |
526 | if (sinOfAngle > 0.0000001) { partially evaluated: sinOfAngle > 0.0000001 yes Evaluation Count:2 | no Evaluation Count:0 |
| 0-2 |
527 | factor1 = sinf((1.0f - t) * angle) / sinOfAngle; executed (the execution status of this line is deduced): factor1 = sinf((1.0f - t) * angle) / sinOfAngle; | - |
528 | factor2 = sinf(t * angle) / sinOfAngle; executed (the execution status of this line is deduced): factor2 = sinf(t * angle) / sinOfAngle; | - |
529 | } executed: } Execution Count:2 | 2 |
530 | } executed: } Execution Count:2 | 2 |
531 | | - |
532 | // Construct the result quaternion. | - |
533 | return q1 * factor1 + q2b * factor2; executed: return q1 * factor1 + q2b * factor2; Execution Count:2 | 2 |
534 | } | - |
535 | | - |
536 | /*! | - |
537 | Interpolates along the shortest linear path between the rotational | - |
538 | positions \a q1 and \a q2. The value \a t should be between 0 and 1, | - |
539 | indicating the distance to travel between \a q1 and \a q2. | - |
540 | The result will be normalized(). | - |
541 | | - |
542 | If \a t is less than or equal to 0, then \a q1 will be returned. | - |
543 | If \a t is greater than or equal to 1, then \a q2 will be returned. | - |
544 | | - |
545 | The nlerp() function is typically faster than slerp() and will | - |
546 | give approximate results to spherical interpolation that are | - |
547 | good enough for some applications. | - |
548 | | - |
549 | \sa slerp() | - |
550 | */ | - |
551 | QQuaternion QQuaternion::nlerp | - |
552 | (const QQuaternion& q1, const QQuaternion& q2, float t) | - |
553 | { | - |
554 | // Handle the easy cases first. | - |
555 | if (t <= 0.0f) evaluated: t <= 0.0f yes Evaluation Count:2 | yes Evaluation Count:4 |
| 2-4 |
556 | return q1; executed: return q1; Execution Count:2 | 2 |
557 | else if (t >= 1.0f) evaluated: t >= 1.0f yes Evaluation Count:2 | yes Evaluation Count:2 |
| 2 |
558 | return q2; executed: return q2; Execution Count:2 | 2 |
559 | | - |
560 | // Determine the angle between the two quaternions. | - |
561 | QQuaternion q2b; executed (the execution status of this line is deduced): QQuaternion q2b; | - |
562 | float dot; executed (the execution status of this line is deduced): float dot; | - |
563 | dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; executed (the execution status of this line is deduced): dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; | - |
564 | if (dot >= 0.0f) evaluated: dot >= 0.0f yes Evaluation Count:1 | yes Evaluation Count:1 |
| 1 |
565 | q2b = q2; executed: q2b = q2; Execution Count:1 | 1 |
566 | else | - |
567 | q2b = -q2; executed: q2b = -q2; Execution Count:1 | 1 |
568 | | - |
569 | // Perform the linear interpolation. | - |
570 | return (q1 * (1.0f - t) + q2b * t).normalized(); executed: return (q1 * (1.0f - t) + q2b * t).normalized(); Execution Count:2 | 2 |
571 | } | - |
572 | | - |
573 | /*! | - |
574 | Returns the quaternion as a QVariant. | - |
575 | */ | - |
576 | QQuaternion::operator QVariant() const | - |
577 | { | - |
578 | return QVariant(QVariant::Quaternion, this); executed: return QVariant(QVariant::Quaternion, this); Execution Count:1 | 1 |
579 | } | - |
580 | | - |
581 | #ifndef QT_NO_DEBUG_STREAM | - |
582 | | - |
583 | QDebug operator<<(QDebug dbg, const QQuaternion &q) | - |
584 | { | - |
585 | dbg.nospace() << "QQuaternion(scalar:" << q.scalar() executed (the execution status of this line is deduced): dbg.nospace() << "QQuaternion(scalar:" << q.scalar() | - |
586 | << ", vector:(" << q.x() << ", " executed (the execution status of this line is deduced): << ", vector:(" << q.x() << ", " | - |
587 | << q.y() << ", " << q.z() << "))"; executed (the execution status of this line is deduced): << q.y() << ", " << q.z() << "))"; | - |
588 | return dbg.space(); executed: return dbg.space(); Execution Count:1 | 1 |
589 | } | - |
590 | | - |
591 | #endif | - |
592 | | - |
593 | #ifndef QT_NO_DATASTREAM | - |
594 | | - |
595 | /*! | - |
596 | \fn QDataStream &operator<<(QDataStream &stream, const QQuaternion &quaternion) | - |
597 | \relates QQuaternion | - |
598 | | - |
599 | Writes the given \a quaternion to the given \a stream and returns a | - |
600 | reference to the stream. | - |
601 | | - |
602 | \sa {Serializing Qt Data Types} | - |
603 | */ | - |
604 | | - |
605 | QDataStream &operator<<(QDataStream &stream, const QQuaternion &quaternion) | - |
606 | { | - |
607 | stream << quaternion.scalar() << quaternion.x() never executed (the execution status of this line is deduced): stream << quaternion.scalar() << quaternion.x() | - |
608 | << quaternion.y() << quaternion.z(); never executed (the execution status of this line is deduced): << quaternion.y() << quaternion.z(); | - |
609 | return stream; never executed: return stream; | 0 |
610 | } | - |
611 | | - |
612 | /*! | - |
613 | \fn QDataStream &operator>>(QDataStream &stream, QQuaternion &quaternion) | - |
614 | \relates QQuaternion | - |
615 | | - |
616 | Reads a quaternion from the given \a stream into the given \a quaternion | - |
617 | and returns a reference to the stream. | - |
618 | | - |
619 | \sa {Serializing Qt Data Types} | - |
620 | */ | - |
621 | | - |
622 | QDataStream &operator>>(QDataStream &stream, QQuaternion &quaternion) | - |
623 | { | - |
624 | float scalar, x, y, z; never executed (the execution status of this line is deduced): float scalar, x, y, z; | - |
625 | stream >> scalar; never executed (the execution status of this line is deduced): stream >> scalar; | - |
626 | stream >> x; never executed (the execution status of this line is deduced): stream >> x; | - |
627 | stream >> y; never executed (the execution status of this line is deduced): stream >> y; | - |
628 | stream >> z; never executed (the execution status of this line is deduced): stream >> z; | - |
629 | quaternion.setScalar(scalar); never executed (the execution status of this line is deduced): quaternion.setScalar(scalar); | - |
630 | quaternion.setX(x); never executed (the execution status of this line is deduced): quaternion.setX(x); | - |
631 | quaternion.setY(y); never executed (the execution status of this line is deduced): quaternion.setY(y); | - |
632 | quaternion.setZ(z); never executed (the execution status of this line is deduced): quaternion.setZ(z); | - |
633 | return stream; never executed: return stream; | 0 |
634 | } | - |
635 | | - |
636 | #endif // QT_NO_DATASTREAM | - |
637 | | - |
638 | #endif | - |
639 | | - |
640 | QT_END_NAMESPACE | - |
641 | | - |
| | |