qquaternion.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/math3d/qquaternion.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3-
4float QQuaternion::length() const-
5{-
6 return
never executed: return std::sqrt(xp * xp + yp * yp + zp * zp + wp * wp);
std::sqrt(xp * xp + yp * yp + zp * zp + wp * wp);
never executed: return std::sqrt(xp * xp + yp * yp + zp * zp + wp * wp);
0
7}-
8-
9-
10-
11-
12-
13-
14float QQuaternion::lengthSquared() const-
15{-
16 return
never executed: return xp * xp + yp * yp + zp * zp + wp * wp;
xp * xp + yp * yp + zp * zp + wp * wp;
never executed: return xp * xp + yp * yp + zp * zp + wp * wp;
0
17}-
18QQuaternion QQuaternion::normalized() const-
19{-
20-
21 double len = double(xp) * double(xp) +-
22 double(yp) * double(yp) +-
23 double(zp) * double(zp) +-
24 double(wp) * double(wp);-
25 if (qFuzzyIsNull(len - 1.0f)
qFuzzyIsNull(len - 1.0f)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
26 return
never executed: return *this;
*this;
never executed: return *this;
0
27 else if (!qFuzzyIsNull(len)
!qFuzzyIsNull(len)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
28 return
never executed: return *this / std::sqrt(len);
*this / std::sqrt(len);
never executed: return *this / std::sqrt(len);
0
29 else-
30 return
never executed: return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
QQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
never executed: return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
0
31}-
32-
33-
34-
35-
36-
37-
38-
39void QQuaternion::normalize()-
40{-
41-
42 double len = double(xp) * double(xp) +-
43 double(yp) * double(yp) +-
44 double(zp) * double(zp) +-
45 double(wp) * double(wp);-
46 if (qFuzzyIsNull(len - 1.0f)
qFuzzyIsNull(len - 1.0f)Description
TRUEnever evaluated
FALSEnever evaluated
|| qFuzzyIsNull(len)
qFuzzyIsNull(len)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
47 return;
never executed: return;
0
48-
49 len = std::sqrt(len);-
50-
51 xp /= len;-
52 yp /= len;-
53 zp /= len;-
54 wp /= len;-
55}
never executed: end of block
0
56QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const-
57{-
58 return
never executed: return (*this * QQuaternion(0, vector) * conjugated()).vector();
(*this * QQuaternion(0, vector) * conjugated()).vector();
never executed: return (*this * QQuaternion(0, vector) * conjugated()).vector();
0
59}-
60QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, float angle)-
61{-
62-
63-
64-
65-
66 float a = (angle / 2.0f) * 3.14159265358979323846 / 180.0f;-
67 float s = std::sin(a);-
68 float c = std::cos(a);-
69 QVector3D ax = axis.normalized();-
70 return
never executed: return QQuaternion(c, ax.x() * s, ax.y() * s, ax.z() * s).normalized();
QQuaternion(c, ax.x() * s, ax.y() * s, ax.z() * s).normalized();
never executed: return QQuaternion(c, ax.x() * s, ax.y() * s, ax.z() * s).normalized();
0
71}-
72void QQuaternion::getAxisAndAngle(float *x, float *y, float *z, float *angle) const-
73{-
74 ((!(x && y && z && angle)) ? qt_assert("x && y && z && angle",__FILE__,430) : qt_noop());-
75-
76-
77-
78-
79 float length = xp * xp + yp * yp + zp * zp;-
80 if (!qFuzzyIsNull(length)
!qFuzzyIsNull(length)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
81 *x = xp;-
82 *y = yp;-
83 *z = zp;-
84 if (!qFuzzyIsNull(length - 1.0f)
!qFuzzyIsNull(length - 1.0f)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
85 length = std::sqrt(length);-
86 *x /= length;-
87 *y /= length;-
88 *z /= length;-
89 }
never executed: end of block
0
90 *angle = 2.0f * std::acos(wp);-
91 }
never executed: end of block
else {
0
92-
93 *x = *y = *z = *angle = 0.0f;-
94 }
never executed: end of block
0
95-
96 *angle = qRadiansToDegrees(*angle);-
97}
never executed: end of block
0
98-
99-
100-
101-
102-
103-
104-
105QQuaternion QQuaternion::fromAxisAndAngle-
106 (float x, float y, float z, float angle)-
107{-
108 float length = std::sqrt(x * x + y * y + z * z);-
109 if (!qFuzzyIsNull(length - 1.0f)
!qFuzzyIsNull(length - 1.0f)Description
TRUEnever evaluated
FALSEnever evaluated
&& !qFuzzyIsNull(length)
!qFuzzyIsNull(length)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
110 x /= length;-
111 y /= length;-
112 z /= length;-
113 }
never executed: end of block
0
114 float a = (angle / 2.0f) * 3.14159265358979323846 / 180.0f;-
115 float s = std::sin(a);-
116 float c = std::cos(a);-
117 return
never executed: return QQuaternion(c, x * s, y * s, z * s).normalized();
QQuaternion(c, x * s, y * s, z * s).normalized();
never executed: return QQuaternion(c, x * s, y * s, z * s).normalized();
0
118}-
119void QQuaternion::getEulerAngles(float *pitch, float *yaw, float *roll) const-
120{-
121 ((!(pitch && yaw && roll)) ? qt_assert("pitch && yaw && roll",__FILE__,513) : qt_noop());-
122-
123-
124-
125-
126 float xx = xp * xp;-
127 float xy = xp * yp;-
128 float xz = xp * zp;-
129 float xw = xp * wp;-
130 float yy = yp * yp;-
131 float yz = yp * zp;-
132 float yw = yp * wp;-
133 float zz = zp * zp;-
134 float zw = zp * wp;-
135-
136 const float lengthSquared = xx + yy + zz + wp * wp;-
137 if (!qFuzzyIsNull(lengthSquared - 1.0f)
!qFuzzyIsNull(...quared - 1.0f)Description
TRUEnever evaluated
FALSEnever evaluated
&& !qFuzzyIsNull(lengthSquared)
!qFuzzyIsNull(lengthSquared)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
138 xx /= lengthSquared;-
139 xy /= lengthSquared;-
140 xz /= lengthSquared;-
141 xw /= lengthSquared;-
142 yy /= lengthSquared;-
143 yz /= lengthSquared;-
144 yw /= lengthSquared;-
145 zz /= lengthSquared;-
146 zw /= lengthSquared;-
147 }
never executed: end of block
0
148-
149 *pitch = std::asin(-2.0f * (yz - xw));-
150 if (*
*pitch < 1.570...32679489661923Description
TRUEnever evaluated
FALSEnever evaluated
pitch < 1.57079632679489661923
*pitch < 1.570...32679489661923Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
151 if (*
*pitch > -1.57...32679489661923Description
TRUEnever evaluated
FALSEnever evaluated
pitch > -1.57079632679489661923
*pitch > -1.57...32679489661923Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
152 *yaw = std::atan2(2.0f * (xz + yw), 1.0f - 2.0f * (xx + yy));-
153 *roll = std::atan2(2.0f * (xy + zw), 1.0f - 2.0f * (xx + zz));-
154 }
never executed: end of block
else {
0
155-
156 *roll = 0.0f;-
157 *yaw = -std::atan2(-2.0f * (xy - zw), 1.0f - 2.0f * (yy + zz));-
158 }
never executed: end of block
0
159 } else {-
160-
161 *roll = 0.0f;-
162 *yaw = std::atan2(-2.0f * (xy - zw), 1.0f - 2.0f * (yy + zz));-
163 }
never executed: end of block
0
164-
165 *pitch = qRadiansToDegrees(*pitch);-
166 *yaw = qRadiansToDegrees(*yaw);-
167 *roll = qRadiansToDegrees(*roll);-
168}
never executed: end of block
0
169QQuaternion QQuaternion::fromEulerAngles(float pitch, float yaw, float roll)-
170{-
171-
172-
173-
174 pitch = qDegreesToRadians(pitch);-
175 yaw = qDegreesToRadians(yaw);-
176 roll = qDegreesToRadians(roll);-
177-
178 pitch *= 0.5f;-
179 yaw *= 0.5f;-
180 roll *= 0.5f;-
181-
182 const float c1 = std::cos(yaw);-
183 const float s1 = std::sin(yaw);-
184 const float c2 = std::cos(roll);-
185 const float s2 = std::sin(roll);-
186 const float c3 = std::cos(pitch);-
187 const float s3 = std::sin(pitch);-
188 const float c1c2 = c1 * c2;-
189 const float s1s2 = s1 * s2;-
190-
191 const float w = c1c2 * c3 + s1s2 * s3;-
192 const float x = c1c2 * s3 + s1s2 * c3;-
193 const float y = s1 * c2 * c3 - c1 * s2 * s3;-
194 const float z = c1 * s2 * c3 - s1 * c2 * s3;-
195-
196 return
never executed: return QQuaternion(w, x, y, z);
QQuaternion(w, x, y, z);
never executed: return QQuaternion(w, x, y, z);
0
197}-
198QMatrix3x3 QQuaternion::toRotationMatrix() const-
199{-
200-
201-
202-
203 QMatrix3x3 rot3x3(Qt::Uninitialized);-
204-
205 const float f2x = xp + xp;-
206 const float f2y = yp + yp;-
207 const float f2z = zp + zp;-
208 const float f2xw = f2x * wp;-
209 const float f2yw = f2y * wp;-
210 const float f2zw = f2z * wp;-
211 const float f2xx = f2x * xp;-
212 const float f2xy = f2x * yp;-
213 const float f2xz = f2x * zp;-
214 const float f2yy = f2y * yp;-
215 const float f2yz = f2y * zp;-
216 const float f2zz = f2z * zp;-
217-
218 rot3x3(0, 0) = 1.0f - (f2yy + f2zz);-
219 rot3x3(0, 1) = f2xy - f2zw;-
220 rot3x3(0, 2) = f2xz + f2yw;-
221 rot3x3(1, 0) = f2xy + f2zw;-
222 rot3x3(1, 1) = 1.0f - (f2xx + f2zz);-
223 rot3x3(1, 2) = f2yz - f2xw;-
224 rot3x3(2, 0) = f2xz - f2yw;-
225 rot3x3(2, 1) = f2yz + f2xw;-
226 rot3x3(2, 2) = 1.0f - (f2xx + f2yy);-
227-
228 return
never executed: return rot3x3;
rot3x3;
never executed: return rot3x3;
0
229}-
230QQuaternion QQuaternion::fromRotationMatrix(const QMatrix3x3 &rot3x3)-
231{-
232-
233-
234-
235 float scalar;-
236 float axis[3];-
237-
238 const float trace = rot3x3(0, 0) + rot3x3(1, 1) + rot3x3(2, 2);-
239 if (trace > 0.00000001f
trace > 0.00000001fDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
240 const float s = 2.0f * std::sqrt(trace + 1.0f);-
241 scalar = 0.25f * s;-
242 axis[0] = (rot3x3(2, 1) - rot3x3(1, 2)) / s;-
243 axis[1] = (rot3x3(0, 2) - rot3x3(2, 0)) / s;-
244 axis[2] = (rot3x3(1, 0) - rot3x3(0, 1)) / s;-
245 }
never executed: end of block
else {
0
246 static int s_next[3] = { 1, 2, 0 };-
247 int i = 0;-
248 if (rot3x3(1, 1) > rot3x3(0, 0)
rot3x3(1, 1) > rot3x3(0, 0)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
249 i = 1;
never executed: i = 1;
0
250 if (rot3x3(2, 2) > rot3x3(i, i)
rot3x3(2, 2) > rot3x3(i, i)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
251 i = 2;
never executed: i = 2;
0
252 int j = s_next[i];-
253 int k = s_next[j];-
254-
255 const float s = 2.0f * std::sqrt(rot3x3(i, i) - rot3x3(j, j) - rot3x3(k, k) + 1.0f);-
256 axis[i] = 0.25f * s;-
257 scalar = (rot3x3(k, j) - rot3x3(j, k)) / s;-
258 axis[j] = (rot3x3(j, i) + rot3x3(i, j)) / s;-
259 axis[k] = (rot3x3(k, i) + rot3x3(i, k)) / s;-
260 }
never executed: end of block
0
261-
262 return
never executed: return QQuaternion(scalar, axis[0], axis[1], axis[2]);
QQuaternion(scalar, axis[0], axis[1], axis[2]);
never executed: return QQuaternion(scalar, axis[0], axis[1], axis[2]);
0
263}-
264void QQuaternion::getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const-
265{-
266 ((!(xAxis && yAxis && zAxis)) ? qt_assert("xAxis && yAxis && zAxis",__FILE__,700) : qt_noop());-
267-
268 const QMatrix3x3 rot3x3(toRotationMatrix());-
269-
270 *xAxis = QVector3D(rot3x3(0, 0), rot3x3(1, 0), rot3x3(2, 0));-
271 *yAxis = QVector3D(rot3x3(0, 1), rot3x3(1, 1), rot3x3(2, 1));-
272 *zAxis = QVector3D(rot3x3(0, 2), rot3x3(1, 2), rot3x3(2, 2));-
273}
never executed: end of block
0
274QQuaternion QQuaternion::fromAxes(const QVector3D &xAxis, const QVector3D &yAxis, const QVector3D &zAxis)-
275{-
276 QMatrix3x3 rot3x3(Qt::Uninitialized);-
277 rot3x3(0, 0) = xAxis.x();-
278 rot3x3(1, 0) = xAxis.y();-
279 rot3x3(2, 0) = xAxis.z();-
280 rot3x3(0, 1) = yAxis.x();-
281 rot3x3(1, 1) = yAxis.y();-
282 rot3x3(2, 1) = yAxis.z();-
283 rot3x3(0, 2) = zAxis.x();-
284 rot3x3(1, 2) = zAxis.y();-
285 rot3x3(2, 2) = zAxis.z();-
286-
287 return
never executed: return QQuaternion::fromRotationMatrix(rot3x3);
QQuaternion::fromRotationMatrix(rot3x3);
never executed: return QQuaternion::fromRotationMatrix(rot3x3);
0
288}-
289QQuaternion QQuaternion::fromDirection(const QVector3D &direction, const QVector3D &up)-
290{-
291 if (qFuzzyIsNull(direction.x())
qFuzzyIsNull(direction.x())Description
TRUEnever evaluated
FALSEnever evaluated
&& qFuzzyIsNull(direction.y())
qFuzzyIsNull(direction.y())Description
TRUEnever evaluated
FALSEnever evaluated
&& qFuzzyIsNull(direction.z())
qFuzzyIsNull(direction.z())Description
TRUEnever evaluated
FALSEnever evaluated
)
0
292 return
never executed: return QQuaternion();
QQuaternion();
never executed: return QQuaternion();
0
293-
294 const QVector3D zAxis(direction.normalized());-
295 QVector3D xAxis(QVector3D::crossProduct(up, zAxis));-
296 if (qFuzzyIsNull(xAxis.lengthSquared())
qFuzzyIsNull(x...ngthSquared())Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
297-
298 return
never executed: return QQuaternion::rotationTo(QVector3D(0.0f, 0.0f, 1.0f), zAxis);
QQuaternion::rotationTo(QVector3D(0.0f, 0.0f, 1.0f), zAxis);
never executed: return QQuaternion::rotationTo(QVector3D(0.0f, 0.0f, 1.0f), zAxis);
0
299 }-
300-
301 xAxis.normalize();-
302 const QVector3D yAxis(QVector3D::crossProduct(zAxis, xAxis));-
303-
304 return
never executed: return QQuaternion::fromAxes(xAxis, yAxis, zAxis);
QQuaternion::fromAxes(xAxis, yAxis, zAxis);
never executed: return QQuaternion::fromAxes(xAxis, yAxis, zAxis);
0
305}-
306QQuaternion QQuaternion::rotationTo(const QVector3D &from, const QVector3D &to)-
307{-
308-
309-
310 const QVector3D v0(from.normalized());-
311 const QVector3D v1(to.normalized());-
312-
313 float d = QVector3D::dotProduct(v0, v1) + 1.0f;-
314-
315-
316 if (qFuzzyIsNull(d)
qFuzzyIsNull(d)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
317 QVector3D axis = QVector3D::crossProduct(QVector3D(1.0f, 0.0f, 0.0f), v0);-
318 if (qFuzzyIsNull(axis.lengthSquared())
qFuzzyIsNull(a...ngthSquared())Description
TRUEnever evaluated
FALSEnever evaluated
)
0
319 axis = QVector3D::crossProduct(QVector3D(0.0f, 1.0f, 0.0f), v0);
never executed: axis = QVector3D::crossProduct(QVector3D(0.0f, 1.0f, 0.0f), v0);
0
320 axis.normalize();-
321-
322-
323 return
never executed: return QQuaternion(0.0f, axis.x(), axis.y(), axis.z());
QQuaternion(0.0f, axis.x(), axis.y(), axis.z());
never executed: return QQuaternion(0.0f, axis.x(), axis.y(), axis.z());
0
324 }-
325-
326 d = std::sqrt(2.0f * d);-
327 const QVector3D axis(QVector3D::crossProduct(v0, v1) / d);-
328-
329 return
never executed: return QQuaternion(d * 0.5f, axis).normalized();
QQuaternion(d * 0.5f, axis).normalized();
never executed: return QQuaternion(d * 0.5f, axis).normalized();
0
330}-
331QQuaternion QQuaternion::slerp-
332 (const QQuaternion& q1, const QQuaternion& q2, float t)-
333{-
334-
335 if (t <= 0.0f
t <= 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
336 return
never executed: return q1;
q1;
never executed: return q1;
0
337 else if (t >= 1.0f
t >= 1.0fDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
338 return
never executed: return q2;
q2;
never executed: return q2;
0
339-
340-
341 QQuaternion q2b(q2);-
342 float dot = QQuaternion::dotProduct(q1, q2);-
343 if (dot < 0.0f
dot < 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
344 q2b = -q2b;-
345 dot = -dot;-
346 }
never executed: end of block
0
347-
348-
349-
350 float factor1 = 1.0f - t;-
351 float factor2 = t;-
352 if ((
(1.0f - dot) > 0.0000001Description
TRUEnever evaluated
FALSEnever evaluated
1.0f - dot) > 0.0000001
(1.0f - dot) > 0.0000001Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
353 float angle = std::acos(dot);-
354 float sinOfAngle = std::sin(angle);-
355 if (sinOfAngle > 0.0000001
sinOfAngle > 0.0000001Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
356 factor1 = std::sin((1.0f - t) * angle) / sinOfAngle;-
357 factor2 = std::sin(t * angle) / sinOfAngle;-
358 }
never executed: end of block
0
359 }
never executed: end of block
0
360-
361-
362 return
never executed: return q1 * factor1 + q2b * factor2;
q1 * factor1 + q2b * factor2;
never executed: return q1 * factor1 + q2b * factor2;
0
363}-
364QQuaternion QQuaternion::nlerp-
365 (const QQuaternion& q1, const QQuaternion& q2, float t)-
366{-
367-
368 if (t <= 0.0f
t <= 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
369 return
never executed: return q1;
q1;
never executed: return q1;
0
370 else if (t >= 1.0f
t >= 1.0fDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
371 return
never executed: return q2;
q2;
never executed: return q2;
0
372-
373-
374 QQuaternion q2b(q2);-
375 float dot = QQuaternion::dotProduct(q1, q2);-
376 if (dot < 0.0f
dot < 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
377 q2b = -q2b;
never executed: q2b = -q2b;
0
378-
379-
380 return
never executed: return (q1 * (1.0f - t) + q2b * t).normalized();
(q1 * (1.0f - t) + q2b * t).normalized();
never executed: return (q1 * (1.0f - t) + q2b * t).normalized();
0
381}-
382-
383-
384-
385-
386QQuaternion::operator QVariant() const-
387{-
388 return
never executed: return QVariant(QVariant::Quaternion, this);
QVariant(QVariant::Quaternion, this);
never executed: return QVariant(QVariant::Quaternion, this);
0
389}-
390-
391-
392-
393QDebug operator<<(QDebug dbg, const QQuaternion &q)-
394{-
395 QDebugStateSaver saver(dbg);-
396 dbg.nospace() << "QQuaternion(scalar:" << q.scalar()-
397 << ", vector:(" << q.x() << ", "-
398 << q.y() << ", " << q.z() << "))";-
399 return
never executed: return dbg;
dbg;
never executed: return dbg;
0
400}-
401QDataStream &operator<<(QDataStream &stream, const QQuaternion &quaternion)-
402{-
403 stream << quaternion.scalar() << quaternion.x()-
404 << quaternion.y() << quaternion.z();-
405 return
never executed: return stream;
stream;
never executed: return stream;
0
406}-
407QDataStream &operator>>(QDataStream &stream, QQuaternion &quaternion)-
408{-
409 float scalar, x, y, z;-
410 stream >> scalar;-
411 stream >> x;-
412 stream >> y;-
413 stream >> z;-
414 quaternion.setScalar(scalar);-
415 quaternion.setX(x);-
416 quaternion.setY(y);-
417 quaternion.setZ(z);-
418 return
never executed: return stream;
stream;
never executed: return stream;
0
419}-
420-
421-
422-
423-
424-
425-
Switch to Source codePreprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9