1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dquaternionutils_p.h"
5#include <QtQuick3DUtils/private/qssgutils_p.h>
6#include <QtMath>
7
8QT_BEGIN_NAMESPACE
9
10/*!
11 \qmltype Quaternion
12 \inqmlmodule QtQuick3D
13 \since 5.15
14
15 \brief Provides utility functions for quaternion.
16
17 The \c Quaternion is a global object with utility functions.
18
19 It is not instantiable; to use it, call the members of the global \c Quaternion object
20 directly. For example:
21
22 \qml
23 Node {
24 rotation: Quaternion.fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45)
25 }
26 \endqml
27*/
28
29/*!
30 \qmlmethod quaternion QtQuick3D::Quaternion::fromAxisAndAngle(vector3d axis, real angle)
31 Creates a quaternion from \a axis and \a angle.
32 Returns the resulting quaternion.
33 */
34
35/*!
36 \qmlmethod quaternion QtQuick3D::Quaternion::fromAxisAndAngle(real x, real y, real z, real angle)
37 Creates a quaternion from \a x, \a y, \a z, and \a angle.
38 Returns the resulting quaternion.
39 */
40
41/*!
42 \qmlmethod quaternion QtQuick3D::Quaternion::fromAxesAndAngles(vector3d axis1, real angle1,
43 vector3d axis2, real angle2)
44 Creates a quaternion from \a axis1, \a angle1, \a axis2, and \a angle2.
45 Returns the resulting quaternion.
46 */
47
48/*!
49 \qmlmethod quaternion QtQuick3D::Quaternion::fromAxesAndAngles(vector3d axis1, real angle1,
50 vector3d axis2, real angle2,
51 vector3d axis3, real angle3)
52 Creates a quaternion from \a axis1, \a angle1, \a axis2, \a angle2, \a axis3, and \a angle3.
53 Returns the resulting quaternion.
54 */
55
56/*!
57 \qmlmethod quaternion QtQuick3D::Quaternion::fromEulerAngles(vector3d eulerAngles)
58 Creates a quaternion from \a eulerAngles.
59 Returns the resulting quaternion.
60 */
61
62/*!
63 \qmlmethod quaternion QtQuick3D::Quaternion::fromEulerAngles(real x, real y, real z)
64 Creates a quaternion from \a x, \a y, and \a z.
65 Returns the resulting quaternion.
66 */
67
68/*!
69 \qmlmethod quaternion QtQuick3D::Quaternion::lookAt(vector3d sourcePosition, vector3d targetPosition,
70 vector3d forwardDirection, vector3d upDirection)
71 Creates a quaternion from \a sourcePosition, \a targetPosition, \a forwardDirection, and
72 \a upDirection. This is used for getting a rotation value for pointing at a particular target,
73 and can be used to point a camera at a position in a scene.
74
75 \a forwardDirection defaults to \c Qt.vector3d(0, 0, -1)
76 \a upDirection defaults to \c Qt.vector3d(0, 1, 0)
77
78 Returns the resulting quaternion.
79 */
80
81QQuick3DQuaternionUtils::QQuick3DQuaternionUtils(QObject *parent) : QObject(parent)
82{
83
84}
85
86QQuaternion QQuick3DQuaternionUtils::fromAxisAndAngle(float x, float y, float z, float angle)
87{
88 return QQuaternion::fromAxisAndAngle(x, y, z, angle);
89}
90
91QQuaternion QQuick3DQuaternionUtils::fromAxisAndAngle(const QVector3D &axis, float angle)
92{
93 return QQuaternion::fromAxisAndAngle(axis, angle);
94}
95
96QQuaternion QQuick3DQuaternionUtils::fromEulerAngles(float x, float y, float z)
97{
98 return QQuaternion::fromEulerAngles(pitch: x, yaw: y, roll: z);
99}
100
101QQuaternion QQuick3DQuaternionUtils::fromEulerAngles(const QVector3D &eulerAngles)
102{
103 return QQuaternion::fromEulerAngles(eulerAngles);
104}
105
106QQuaternion QQuick3DQuaternionUtils::lookAt(const QVector3D &sourcePosition,
107 const QVector3D &targetPosition,
108 const QVector3D &forwardDirection,
109 const QVector3D &upDirection)
110{
111 QVector3D targetDirection = targetPosition - sourcePosition;
112 targetDirection.normalize();
113
114 QVector3D rotationAxis = QVector3D::crossProduct(v1: forwardDirection, v2: targetDirection);
115
116 const QVector3D normalizedAxis = rotationAxis.normalized();
117 if (qFuzzyIsNull(f: normalizedAxis.lengthSquared()))
118 rotationAxis = upDirection;
119
120 float dot = QVector3D::dotProduct(v1: forwardDirection, v2: targetDirection);
121 float rotationAngle = qRadiansToDegrees(radians: qAcos(v: dot));
122
123 return QQuaternion::fromAxisAndAngle(axis: rotationAxis, angle: rotationAngle);
124}
125
126QQuaternion QQuick3DQuaternionUtils::fromAxesAndAngles(const QVector3D &axis1,
127 float angle1,
128 const QVector3D &axis2,
129 float angle2,
130 const QVector3D &axis3,
131 float angle3)
132{
133 const QQuaternion q1 = QQuaternion::fromAxisAndAngle(axis: axis1, angle: angle1);
134 const QQuaternion q2 = QQuaternion::fromAxisAndAngle(axis: axis2, angle: angle2);
135 const QQuaternion q3 = QQuaternion::fromAxisAndAngle(axis: axis3, angle: angle3);
136 return q3 * q2 * q1;
137}
138
139QQuaternion QQuick3DQuaternionUtils::fromAxesAndAngles(const QVector3D &axis1,
140 float angle1,
141 const QVector3D &axis2,
142 float angle2)
143{
144 const QQuaternion q1 = QQuaternion::fromAxisAndAngle(axis: axis1, angle: angle1);
145 const QQuaternion q2 = QQuaternion::fromAxisAndAngle(axis: axis2, angle: angle2);
146 return q2 * q1;
147}
148
149QT_END_NAMESPACE
150

source code of qtquick3d/src/quick3d/qquick3dquaternionutils.cpp