Revision control

Copy as Markdown

// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include "qquick3dquaternionutils_p.h"
#include <QtQuick3DUtils/private/qssgutils_p.h>
#include <QtMath>
QT_BEGIN_NAMESPACE
/*!
\qmltype Quaternion
\inqmlmodule QtQuick3D
\since 5.15
\brief Provides utility functions for quaternion.
The \c Quaternion is a global object with utility functions.
It is not instantiable; to use it, call the members of the global \c Quaternion object
directly. For example:
\qml
Node {
rotation: Quaternion.fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45)
}
\endqml
*/
/*!
\qmlmethod quaternion QtQuick3D::Quaternion::fromAxisAndAngle(vector3d axis, real angle)
Creates a quaternion from \a axis and \a angle.
Returns the resulting quaternion.
*/
/*!
\qmlmethod quaternion QtQuick3D::Quaternion::fromAxisAndAngle(real x, real y, real z, real angle)
Creates a quaternion from \a x, \a y, \a z, and \a angle.
Returns the resulting quaternion.
*/
/*!
\qmlmethod quaternion QtQuick3D::Quaternion::fromAxesAndAngles(vector3d axis1, real angle1,
vector3d axis2, real angle2)
Creates a quaternion from \a axis1, \a angle1, \a axis2, and \a angle2.
Returns the resulting quaternion.
*/
/*!
\qmlmethod quaternion QtQuick3D::Quaternion::fromAxesAndAngles(vector3d axis1, real angle1,
vector3d axis2, real angle2,
vector3d axis3, real angle3)
Creates a quaternion from \a axis1, \a angle1, \a axis2, \a angle2, \a axis3, and \a angle3.
Returns the resulting quaternion.
*/
/*!
\qmlmethod quaternion QtQuick3D::Quaternion::fromEulerAngles(vector3d eulerAngles)
Creates a quaternion from \a eulerAngles.
Returns the resulting quaternion.
*/
/*!
\qmlmethod quaternion QtQuick3D::Quaternion::fromEulerAngles(real x, real y, real z)
Creates a quaternion from \a x, \a y, and \a z.
Returns the resulting quaternion.
*/
/*!
\qmlmethod quaternion QtQuick3D::Quaternion::lookAt(vector3d sourcePosition, vector3d targetPosition,
vector3d forwardDirection, vector3d upDirection)
Creates a quaternion from \a sourcePosition, \a targetPosition, \a forwardDirection, and
\a upDirection. This is used for getting a rotation value for pointing at a particular target,
and can be used to point a camera at a position in a scene.
\a forwardDirection defaults to \c Qt.vector3d(0, 0, -1)
\a upDirection defaults to \c Qt.vector3d(0, 1, 0)
Returns the resulting quaternion.
*/
QQuick3DQuaternionUtils::QQuick3DQuaternionUtils(QObject *parent) : QObject(parent)
{
}
QQuaternion QQuick3DQuaternionUtils::fromAxisAndAngle(float x, float y, float z, float angle)
{
return QQuaternion::fromAxisAndAngle(x, y, z, angle);
}
QQuaternion QQuick3DQuaternionUtils::fromAxisAndAngle(const QVector3D &axis, float angle)
{
return QQuaternion::fromAxisAndAngle(axis, angle);
}
QQuaternion QQuick3DQuaternionUtils::fromEulerAngles(float x, float y, float z)
{
return QQuaternion::fromEulerAngles(x, y, z);
}
QQuaternion QQuick3DQuaternionUtils::fromEulerAngles(const QVector3D &eulerAngles)
{
return QQuaternion::fromEulerAngles(eulerAngles);
}
QQuaternion QQuick3DQuaternionUtils::lookAt(const QVector3D &sourcePosition,
const QVector3D &targetPosition,
const QVector3D &forwardDirection,
const QVector3D &upDirection)
{
QVector3D targetDirection = targetPosition - sourcePosition;
targetDirection.normalize();
const QVector3D forwardDirectionNormal = forwardDirection.normalized();
QVector3D rotationAxis = QVector3D::crossProduct(forwardDirectionNormal, targetDirection);
const QVector3D normalizedAxis = rotationAxis.normalized();
if (qFuzzyIsNull(normalizedAxis.lengthSquared()))
rotationAxis = upDirection;
float dot = QVector3D::dotProduct(forwardDirectionNormal, targetDirection);
dot = qBound(-1.0f, dot, 1.0f);
float rotationAngle = qRadiansToDegrees(qAcos(dot));
return QQuaternion::fromAxisAndAngle(rotationAxis, rotationAngle);
}
QQuaternion QQuick3DQuaternionUtils::fromAxesAndAngles(const QVector3D &axis1,
float angle1,
const QVector3D &axis2,
float angle2,
const QVector3D &axis3,
float angle3)
{
const QQuaternion q1 = QQuaternion::fromAxisAndAngle(axis1, angle1);
const QQuaternion q2 = QQuaternion::fromAxisAndAngle(axis2, angle2);
const QQuaternion q3 = QQuaternion::fromAxisAndAngle(axis3, angle3);
return q3 * q2 * q1;
}
QQuaternion QQuick3DQuaternionUtils::fromAxesAndAngles(const QVector3D &axis1,
float angle1,
const QVector3D &axis2,
float angle2)
{
const QQuaternion q1 = QQuaternion::fromAxisAndAngle(axis1, angle1);
const QQuaternion q2 = QQuaternion::fromAxisAndAngle(axis2, angle2);
return q2 * q1;
}
QT_END_NAMESPACE