blob: 4d4e5bf4d1eb9482dd972926807a2169c889e69e [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qcamera.h"
#include "qcamera_p.h"
#include <QtMath>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
/*!
* \internal
*/
QCameraPrivate::QCameraPrivate()
: Qt3DCore::QEntityPrivate()
, m_position(0.0f, 0.0f, 0.0f)
, m_viewCenter(0.0f, 0.0f, -100.0f)
, m_upVector(0.0f, 1.0f, 0.0f)
, m_cameraToCenter(m_viewCenter - m_position)
, m_viewMatrixDirty(false)
, m_lens(new QCameraLens())
, m_transform(new Qt3DCore::QTransform())
{
updateViewMatrixAndTransform(false);
}
void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
{
Q_Q(QCamera);
const QVector3D viewDirection = (m_viewCenter - m_position).normalized();
QMatrix4x4 transformMatrix;
transformMatrix.translate(m_position);
// Negative viewDirection because OpenGL convention is looking down -Z
transformMatrix.rotate(QQuaternion::fromDirection(-viewDirection, m_upVector.normalized()));
m_transform->setMatrix(transformMatrix);
QMatrix4x4 viewMatrix;
viewMatrix.lookAt(m_position, m_viewCenter, m_upVector);
m_viewMatrix = viewMatrix;
if (doEmit)
emit q->viewMatrixChanged();
}
/*!
* \class Qt3DRender::QCamera
* \inheaderfile Qt3DRender/QCamera
* \brief The QCamera class defines a view point through which the scene will be
* rendered.
* \inmodule Qt3DRender
* \since 5.5
*/
/*!
* \qmltype Camera
* \instantiates Qt3DRender::QCamera
* \inherits Entity
* \inqmlmodule Qt3D.Render
* \since 5.5
* \brief Defines a view point through which the scene will be rendered.
*/
/*!
* \enum Qt3DRender::QCamera::CameraTranslationOption
*
* This enum specifies how camera view center is translated
* \value TranslateViewCenter Translate the view center causing the view direction to remain the same
* \value DontTranslateViewCenter Don't translate the view center causing the view direction to change
*/
/*!
* \qmlmethod quaternion Qt3D.Render::Camera::tiltRotation(real angle)
*
* Returns the calculated tilt rotation in relation to the \a angle in degrees taken in
* to adjust the camera's tilt or up/down rotation on the X axis.
*/
/*!
* \qmlmethod quaternion Qt3D.Render::Camera::panRotation(real angle)
*
* Returns the calculated pan rotation in relation to the \a angle in degrees taken in
* to adjust the camera's pan or left/right rotation on the Y axis.
*/
/*!
* \qmlmethod quaternion Qt3D.Render::Camera::rollRotation(real angle)
*
* Returns the calculated roll rotation in relation to the \a angle in degrees taken in
* to adjust the camera's roll or lean left/right rotation on the Z axis.
*/
/*!
* \qmlmethod quaternion Qt3D.Render::Camera::rotation(real angle, vector3d axis)
*
* Returns the calculated rotation in relation to the \a angle in degrees and
* chosen \a axis taken in.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::translate(vector3d vLocal, enumeration option)
*
* Translates the camera's position and its view vector by \a vLocal in local coordinates.
* The \a option allows for toggling whether the view center should be translated.
* \list
* \li Camera.TranslateViewCenter
* \li Camera.DontTranslateViewCenter
* \endlist
* \sa Qt3DRender::QCamera::CameraTranslationOption
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::translateWorld(vector3d vWorld, enumeration option)
*
* Translates the camera's position and its view vector by \a vWorld in world coordinates.
* The \a option allows for toggling whether the view center should be translated.
* \list
* \li Camera.TranslateViewCenter
* \li Camera.DontTranslateViewCenter
* \endlist
* \sa Qt3DRender::QCamera::CameraTranslationOption
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::tilt(real angle)
*
* Adjusts the tilt angle of the camera by \a angle in degrees.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::pan(real angle)
*
* Adjusts the pan angle of the camera by \a angle in degrees.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::pan(real angle, vector3d axis)
*
* Adjusts the camera pan about view center by \a angle in degrees on \a axis.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::roll(real angle)
*
* Adjusts the camera roll by \a angle in degrees.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::tiltAboutViewCenter(real angle)
*
* Adjusts the camera tilt about view center by \a angle in degrees.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::panAboutViewCenter(real angle)
*
* Adjusts the camera pan about view center by \a angle in degrees.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::panAboutViewCenter(real angle, vector3d axis)
*
* Adjusts the camera pan about view center by \a angle in degrees on \a axis.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::rollAboutViewCenter(real angle)
*
* Adjusts the camera roll about view center by \a angle in degrees.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::rotate(quaternion q)
*
* Rotates the camera with the use of a Quaternion in \a q.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::rotateAboutViewCenter(quaternion q)
*
* Rotates the camera about the view center with the use of a Quaternion in \a q.
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::viewAll()
*
* Rotates and moves the camera so that it's viewCenter is the center of the scene's bounding volume
* and the entire scene fits in the view port.
*
* \note Only works if the lens is in perspective or orthographic projection mode.
* \sa Qt3D.Render::Camera::projectionType
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::viewEntity(Entity entity)
*
* Rotates and moves the camera so that it's viewCenter is the center of the entity's bounding volume
* and the entire \a entity fits in the view port.
*
* \note Only works if the lens is in perspective or orthographic projection mode.
* \sa Qt3D.Render::Camera::projectionType
*/
/*!
* \qmlmethod void Qt3D.Render::Camera::viewSphere(vector3d center, real radius)
*
* Rotates and moves the camera so that it's viewCenter is \a center
* and a sphere of \a radius fits in the view port.
*
* \note Only works if the lens is in perspective or orthographic projection mode.
* \sa Qt3D.Render::Camera::projectionType
*/
/*!
* \qmlproperty enumeration Qt3D.Render::Camera::projectionType
*
* Holds the type of the camera projection. The default value is
* CameraLens.PerspectiveProjection.
*
* \list
* \li CameraLens.OrthographicProjection - Parallel lines appear parallel. Objects appear
* the same size regardless of distance.
* \li CameraLens.PerspectiveProjection - Parallel lines appear to meet in the distance.
* Objects appear to shrink the farther they are from the camera.
* \li CameraLens.FrustumProjection
* \li CameraLens.CustomProjection
* \endlist
* \sa Qt3DRender::QCameraLens::ProjectionType
*/
/*!
* \qmlproperty real Qt3D.Render::Camera::nearPlane
* Holds the current camera near plane of the camera. Objects that
* are closer to the camera than the nearPlane will not be rendered.
*/
/*!
* \qmlproperty real Qt3D.Render::Camera::farPlane
* Holds the current camera far plane of the camera. Objects that
* are farther from the camera than the farPlane will not be rendered.
*/
/*!
* \qmlproperty Qt3DRender::QCameraLens QCamera::lens
* Holds the CameraLens component of the camera.
* \since 5.14
*/
/*!
* \qmlproperty Qt3DCore::QTransform QCamera::transform
* Holds the Transform component of the camera.
* \since 5.14
*/
/*!
* \qmlproperty real Qt3D.Render::Camera::fieldOfView
* Holds the current vertical field of view of the camera in degrees.
*
* Along with \l aspectRatio, this property determines how much of
* the scene is visible to the camera. In that respect you might
* think of it as analogous to choosing a wide angle (wide horizontal
* field of view) or telephoto (narrow horizontal field of view) lens,
* depending on how much of a scene you want to capture.
*
* fieldOfView is only relevant when \l projectionType is
* CameraLens.PerspectiveProjection.
*/
/*!
* \qmlproperty real Qt3D.Render::Camera::aspectRatio
* Holds the current aspect ratio of the camera.
*/
/*!
*\qmlproperty real Qt3D.Render::Camera::left
* Holds the current left of the camera.
*
* This property is only relevant when \l projectionType is
* CameraLens.OrthographicProjection.
*/
/*!
* \qmlproperty real Qt3D.Render::Camera::right
* Holds the current right of the camera.
*
* This property is only relevant when \l projectionType is
* CameraLens.OrthographicProjection.
*/
/*!
* \qmlproperty real Qt3D.Render::Camera::bottom
* Holds the current bottom of the camera.
*
* This property is only relevant when \l projectionType is
* CameraLens.OrthographicProjection.
*/
/*!
* \qmlproperty real Qt3D.Render::Camera::top
* Holds the current top of the camera.
*
* This property is only relevant when \l projectionType is
* CameraLens.OrthographicProjection.
*/
/*!
* \qmlproperty matrix4x4 Qt3D.Render::Camera::projectionMatrix
* Holds the current projection matrix of the camera.
*/
/*!
* \qmlproperty real Qt3D.Render::Camera::exposure
* Holds the current exposure of the camera.
*
* The default value is 0.0.
*
* The MetalRoughMaterial in Qt 3D Extras is currently the only provided
* material that makes use of camera exposure. Negative values will cause
* the material to be darker, and positive values will cause it to be lighter.
*
* Custom materials may choose to interpret the value differently.
*/
/*!
* \qmlproperty vector3d Qt3D.Render::Camera::position
* Holds the current position of the camera in coordinates relative to
* the parent entity.
*/
/*!
* \qmlproperty vector3d Qt3D.Render::Camera::upVector
* Holds the current up vector of the camera in coordinates relative to
* the parent entity.
*
* The up vector indicates which direction the top of the camera is
* facing. Think of taking a picture: after positioning yourself
* and pointing the camera at your target, you might rotate the camera
* left or right, giving you a portrait or landscape (or angled!)
* shot. upVector allows you to control this type of movement.
*/
/*!
* \qmlproperty vector3d Qt3D.Render::Camera::viewCenter
* Holds the current view center of the camera in coordinates relative to
* the parent entity.
*
* Intuitively, the viewCenter is the location the camera is pointing at.
*/
/*!
* \qmlproperty vector3d Qt3D.Render::Camera::viewVector
* Holds the camera's view vector in coordinates relative to
* the parent entity.
*
* This vector decribes the displacement from the camera (\l position)
* to its target (\l viewCenter).
* \readonly
*/
/*!
* \qmlproperty matrix4x4 Qt3D.Render::Camera::viewMatrix
* \deprecated
* Holds the camera's view matrix in coordinates relative
* to the parent entity.
* \readonly
*/
/*!
* \property QCamera::projectionType
*
* Holds the type of the camera projection. The default value is
* QCameraLens::PerspectiveProjection.
*
* \list
* \li QCameraLens::OrthographicProjection - Parallel lines appear parallel. Objects appear
* the same size regardless of distance.
* \li QCameraLens::PerspectiveProjection - Parallel lines appear to meet in the distance.
* Objects appear to shrink the farther they are from the camera.
* \li QCameraLens::FrustumProjection
* \li QCameraLens::CustomProjection
* \endlist
* \sa Qt3DRender::QCameraLens::ProjectionType
*/
/*!
* \property QCamera::nearPlane
* Holds the current camera near plane. Objects that are closer to the
* camera than the nearPlane will not be rendered.
*/
/*!
* \property QCamera::farPlane
* Holds the current camera far plane. Objects that are farther from the
* camera than the farPlane will not be rendered.
*/
/*!
* \property QCamera::lens
* Holds the Qt3DRender::QCameraLens component of the camera.
* \since 5.14
*/
/*!
* \property QCamera::transform
* Holds the Qt3DCore::QTransform component of the camera.
* \since 5.14
*/
/*!
* \property QCamera::fieldOfView
* Holds the current vertical field of view in degrees.
*
* Along with \l aspectRatio, this property determines how much of
* the scene is visible to the camera. In that respect you might
* think of it as analogous to choosing a wide angle (wide horizontal
* field of view) or telephoto (narrow horizontal field of view) lens
* depending on how much of a scene you want to capture.
*
* fieldOfView is only relevant when \l projectionType is
* QCameraLens::PerspectiveProjection.
*/
/*!
* \property QCamera::aspectRatio
* Holds the current aspect ratio.
*/
/*!
*\property QCamera::left
* Holds the current left of the camera.
*
* This property is only relevant when \l projectionType is
* QCameraLens::OrthographicProjection.
*/
/*!
* \property QCamera::right
* Holds the current right of the camera.
*
* This property is only relevant when \l projectionType is
* QCameraLens::OrthographicProjection.
*/
/*!
* \property QCamera::bottom
* Holds the current bottom of the camera.
*
* This property is only relevant when \l projectionType is
* QCameraLens::OrthographicProjection.
*/
/*!
* \property QCamera::top
* Holds the current top of the camera.
*
* This property is only relevant when \l projectionType is
* QCameraLens::OrthographicProjection.
*/
/*!
* \property QCamera::projectionMatrix
* Holds the current projection matrix of the camera.
*/
/*!
* \property QCamera::exposure
* Holds the current exposure of the camera.
*
* The default value is 0.0.
*
* The MetalRoughMaterial in Qt 3D Extras is currently the only provided
* material that makes use of camera exposure. Negative values will cause
* the material to be darker, and positive values will cause it to be lighter.
*
* Custom materials may choose to interpret the value differently.
*/
/*!
* \property QCamera::position
* Holds the camera's position in coordinates relative to
* the parent entity.
*/
/*!
* \property QCamera::upVector
* Holds the camera's up vector in coordinates relative to
* the parent entity.
*
* The up vector indicates which direction the top of the camera is
* facing. Think of taking a picture: after positioning yourself
* and pointing the camera at your target, you might rotate the camera
* left or right, giving you a portrait or landscape (or angled!)
* shot. upVector allows you to control this type of movement.
*/
/*!
* \property QCamera::viewCenter
* Holds the camera's view center in coordinates relative to
* the parent entity.
*
* Intuitively, the viewCenter is the location the camera is pointing at.
*/
/*!
* \property QCamera::viewVector
* Holds the camera's view vector in coordinates relative to
* the parent entity.
*
* This vector decribes the displacement from the camera (\l position)
* to its target (\l viewCenter).
*/
/*!
* \property QCamera::viewMatrix
* \deprecated
* Holds the camera's view matrix in coordinates relative to
* the parent entity.
*/
/*!
* Creates a new QCamera instance with the
* specified \a parent.
*/
QCamera::QCamera(Qt3DCore::QNode *parent)
: Qt3DCore::QEntity(*new QCameraPrivate, parent)
{
QObject::connect(d_func()->m_lens, SIGNAL(projectionTypeChanged(QCameraLens::ProjectionType)), this, SIGNAL(projectionTypeChanged(QCameraLens::ProjectionType)));
QObject::connect(d_func()->m_lens, SIGNAL(nearPlaneChanged(float)), this, SIGNAL(nearPlaneChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(farPlaneChanged(float)), this, SIGNAL(farPlaneChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(fieldOfViewChanged(float)), this, SIGNAL(fieldOfViewChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(aspectRatioChanged(float)), this, SIGNAL(aspectRatioChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(leftChanged(float)), this, SIGNAL(leftChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(rightChanged(float)), this, SIGNAL(rightChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(bottomChanged(float)), this, SIGNAL(bottomChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(topChanged(float)), this, SIGNAL(topChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(projectionMatrixChanged(const QMatrix4x4 &)), this, SIGNAL(projectionMatrixChanged(const QMatrix4x4 &)));
QObject::connect(d_func()->m_lens, SIGNAL(exposureChanged(float)), this, SIGNAL(exposureChanged(float)));
QObject::connect(d_func()->m_lens, &QCameraLens::viewSphere, this, &QCamera::viewSphere);
addComponent(d_func()->m_lens);
addComponent(d_func()->m_transform);
}
/*!
* \internal
*/
QCamera::~QCamera()
{
}
/*!
* \internal
*/
QCamera::QCamera(QCameraPrivate &dd, Qt3DCore::QNode *parent)
: Qt3DCore::QEntity(dd, parent)
{
QObject::connect(d_func()->m_lens, SIGNAL(projectionTypeChanged(QCameraLens::ProjectionType)), this, SIGNAL(projectionTypeChanged(QCameraLens::ProjectionType)));
QObject::connect(d_func()->m_lens, SIGNAL(nearPlaneChanged(float)), this, SIGNAL(nearPlaneChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(farPlaneChanged(float)), this, SIGNAL(farPlaneChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(fieldOfViewChanged(float)), this, SIGNAL(fieldOfViewChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(aspectRatioChanged(float)), this, SIGNAL(aspectRatioChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(leftChanged(float)), this, SIGNAL(leftChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(rightChanged(float)), this, SIGNAL(rightChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(bottomChanged(float)), this, SIGNAL(bottomChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(topChanged(float)), this, SIGNAL(topChanged(float)));
QObject::connect(d_func()->m_lens, SIGNAL(projectionMatrixChanged(const QMatrix4x4 &)), this, SIGNAL(projectionMatrixChanged(const QMatrix4x4 &)));
QObject::connect(d_func()->m_lens, &QCameraLens::viewSphere, this, &QCamera::viewSphere);
addComponent(d_func()->m_lens);
addComponent(d_func()->m_transform);
}
/*!
* Returns the current lens.
*/
QCameraLens *QCamera::lens() const
{
Q_D(const QCamera);
return d->m_lens;
}
/*!
* Returns the camera's position via transform.
*/
Qt3DCore::QTransform *QCamera::transform() const
{
Q_D(const QCamera);
return d->m_transform;
}
/*!
* Translates the camera's position and its view vector by \a vLocal in local coordinates.
* The \a option allows for toggling whether the view center should be translated.
*/
void QCamera::translate(const QVector3D &vLocal, CameraTranslationOption option)
{
QVector3D viewVector = viewCenter() - position(); // From "camera" position to view center
// Calculate the amount to move by in world coordinates
QVector3D vWorld;
if (!qFuzzyIsNull(vLocal.x())) {
// Calculate the vector for the local x axis
const QVector3D x = QVector3D::crossProduct(viewVector, upVector()).normalized();
vWorld += vLocal.x() * x;
}
if (!qFuzzyIsNull(vLocal.y()))
vWorld += vLocal.y() * upVector();
if (!qFuzzyIsNull(vLocal.z()))
vWorld += vLocal.z() * viewVector.normalized();
// Update the camera position using the calculated world vector
setPosition(position() + vWorld);
// May be also update the view center coordinates
if (option == TranslateViewCenter)
setViewCenter(viewCenter() + vWorld);
// Refresh the camera -> view center vector
viewVector = viewCenter() - position();
// Calculate a new up vector. We do this by:
// 1) Calculate a new local x-direction vector from the cross product of the new
// camera to view center vector and the old up vector.
// 2) The local x vector is the normal to the plane in which the new up vector
// must lay. So we can take the cross product of this normal and the new
// x vector. The new normal vector forms the last part of the orthonormal basis
const QVector3D x = QVector3D::crossProduct(viewVector, upVector()).normalized();
setUpVector(QVector3D::crossProduct(x, viewVector).normalized());
}
/*!
* Translates the camera's position and its view vector by \a vWorld in world coordinates.
* The \a option allows for toggling whether the view center should be translated.
*/
void QCamera::translateWorld(const QVector3D &vWorld, CameraTranslationOption option)
{
// Update the camera position using the calculated world vector
setPosition(position() + vWorld);
// May be also update the view center coordinates
if (option == TranslateViewCenter)
setViewCenter(viewCenter() + vWorld);
}
/*!
* Returns the calculated tilt rotation in relation to the \a angle in degrees taken in
* to adjust the camera's tilt or up/down rotation on the X axis.
*/
QQuaternion QCamera::tiltRotation(float angle) const
{
const QVector3D viewVector = viewCenter() - position();
const QVector3D xBasis = QVector3D::crossProduct(upVector(), viewVector.normalized()).normalized();
return QQuaternion::fromAxisAndAngle(xBasis, -angle);
}
/*!
* Returns the calculated pan rotation in relation to the \a angle in degrees taken in
* to adjust the camera's pan or left/right rotation on the Y axis.
*/
QQuaternion QCamera::panRotation(float angle) const
{
return QQuaternion::fromAxisAndAngle(upVector(), angle);
}
/*!
* Returns the calculated roll rotation in relation to the \a angle in degrees taken in
* to adjust the camera's roll or lean left/right rotation on the Z axis.
*/
QQuaternion QCamera::rollRotation(float angle) const
{
QVector3D viewVector = viewCenter() - position();
return QQuaternion::fromAxisAndAngle(viewVector, -angle);
}
/*!
* Returns the calculated rotation in relation to the \a angle in degrees and
* chosen \a axis taken in.
*/
QQuaternion QCamera::rotation(float angle, const QVector3D &axis) const
{
return QQuaternion::fromAxisAndAngle(axis, angle);
}
/*!
* Adjusts the tilt angle of the camera by \a angle in degrees.
*/
void QCamera::tilt(float angle)
{
QQuaternion q = tiltRotation(angle);
rotate(q);
}
/*!
* Adjusts the pan angle of the camera by \a angle in degrees.
*/
void QCamera::pan(float angle)
{
QQuaternion q = panRotation(-angle);
rotate(q);
}
/*!
* Adjusts the pan angle of the camera by \a angle in degrees on a chosen \a axis.
*/
void QCamera::pan(float angle, const QVector3D &axis)
{
QQuaternion q = rotation(-angle, axis);
rotate(q);
}
/*!
* Adjusts the camera roll by \a angle in degrees.
*/
void QCamera::roll(float angle)
{
QQuaternion q = rollRotation(-angle);
rotate(q);
}
/*!
* Adjusts the camera tilt about view center by \a angle in degrees.
*/
void QCamera::tiltAboutViewCenter(float angle)
{
QQuaternion q = tiltRotation(-angle);
rotateAboutViewCenter(q);
}
/*!
* Adjusts the camera pan about view center by \a angle in degrees.
*/
void QCamera::panAboutViewCenter(float angle)
{
QQuaternion q = panRotation(angle);
rotateAboutViewCenter(q);
}
/*!
* Adjusts the camera pan about view center by \a angle in degrees on \a axis.
*/
void QCamera::panAboutViewCenter(float angle, const QVector3D &axis)
{
QQuaternion q = rotation(angle, axis);
rotateAboutViewCenter(q);
}
/*!
* Adjusts the camera roll about view center by \a angle in degrees.
*/
void QCamera::rollAboutViewCenter(float angle)
{
QQuaternion q = rollRotation(angle);
rotateAboutViewCenter(q);
}
/*!
* Rotates the camera with the use of a Quaternion in \a q.
*/
void QCamera::rotate(const QQuaternion& q)
{
setUpVector(q * upVector());
QVector3D viewVector = viewCenter() - position();
QVector3D cameraToCenter = q * viewVector;
setViewCenter(position() + cameraToCenter);
}
/*!
* Rotates the camera about the view center with the use of a Quaternion
* in \a q.
*/
void QCamera::rotateAboutViewCenter(const QQuaternion& q)
{
setUpVector(q * upVector());
QVector3D viewVector = viewCenter() - position();
QVector3D cameraToCenter = q * viewVector;
setPosition(viewCenter() - cameraToCenter);
setViewCenter(position() + cameraToCenter);
}
/*!
* Rotates and moves the camera so that it's viewCenter is the center of the scene's bounding volume
* and the entire scene fits in the view port.
*
* \note Only works if the lens is in perspective or orthographic projection mode.
* \sa Qt3D.Render::Camera::projectionType
*/
void QCamera::viewAll()
{
Q_D(QCamera);
d->m_lens->viewAll(id());
}
/*!
* Rotates and moves the camera so that it's viewCenter is \a center
* and a sphere of \a radius fits in the view port.
*
* \note Only works if the lens is in perspective or orthographic projection mode.
* \sa Qt3D.Render::Camera::projectionType
*/
void QCamera::viewSphere(const QVector3D &center, float radius)
{
Q_D(QCamera);
if ((d->m_lens->projectionType() != QCameraLens::PerspectiveProjection &&
d->m_lens->projectionType() != QCameraLens::OrthographicProjection) ||
radius <= 0.f)
return;
// Ensure the sphere fits in the view port even if aspect ratio < 1 (i.e. width < height)
float height = (1.05f * radius) / (d->m_lens->aspectRatio() < 1.0f ? d->m_lens->aspectRatio() : 1.0f);
float dist = 1.0f;
if (d->m_lens->projectionType() == QCameraLens::PerspectiveProjection) {
dist = height / std::sin(qDegreesToRadians(d->m_lens->fieldOfView()) / 2.0f);
}
else if (d->m_lens->projectionType() == QCameraLens::OrthographicProjection) {
d->m_lens->setOrthographicProjection(-height * d->m_lens->aspectRatio(), height * d->m_lens->aspectRatio(), -height, height,
nearPlane(), farPlane());
dist = height / std::sin(qDegreesToRadians(d->m_lens->fieldOfView()) / 2.0f);
}
else {
dist = (d->m_viewCenter - d->m_position).length();
}
QVector3D dir = (d->m_viewCenter - d->m_position).normalized();
QVector3D newPos = center - (dir * dist);
setViewCenter(center);
setPosition(newPos);
}
/*!
* Rotates and moves the camera so that it's viewCenter is the center of the
* \a {entity}'s bounding volume and the entire entity fits in the view port.
*
* \note Only works if the lens is in perspective or orthographic projection mode.
* \sa {Qt3D.Render::Camera::projectionType}{Camera.projectionType}
*/
void QCamera::viewEntity(Qt3DCore::QEntity *entity)
{
if (!entity)
return;
Q_D(QCamera);
d->m_lens->viewEntity(entity->id(), id());
}
/*!
* Sets the camera's projection type to \a type.
*/
void QCamera::setProjectionType(QCameraLens::ProjectionType type)
{
Q_D(QCamera);
d->m_lens->setProjectionType(type);
}
QCameraLens::ProjectionType QCamera::projectionType() const
{
Q_D(const QCamera);
return d->m_lens->projectionType();
}
/*!
* Sets the camera's near plane to \a nearPlane.
*/
void QCamera::setNearPlane(float nearPlane)
{
Q_D(QCamera);
d->m_lens->setNearPlane(nearPlane);
}
float QCamera::nearPlane() const
{
Q_D(const QCamera);
return d->m_lens->nearPlane();
}
/*!
* Sets the camera's far plane to \a farPlane
*/
void QCamera::setFarPlane(float farPlane)
{
Q_D(QCamera);
d->m_lens->setFarPlane(farPlane);
}
float QCamera::farPlane() const
{
Q_D(const QCamera);
return d->m_lens->farPlane();
}
/*!
* Sets the camera's field of view to \a fieldOfView in degrees.
*/
void QCamera::setFieldOfView(float fieldOfView)
{
Q_D(QCamera);
d->m_lens->setFieldOfView(fieldOfView);
}
float QCamera::fieldOfView() const
{
Q_D(const QCamera);
return d->m_lens->fieldOfView();
}
/*!
* Sets the camera's aspect ratio to \a aspectRatio.
*/
void QCamera::setAspectRatio(float aspectRatio)
{
Q_D(QCamera);
d->m_lens->setAspectRatio(aspectRatio);
}
float QCamera::aspectRatio() const
{
Q_D(const QCamera);
return d->m_lens->aspectRatio();
}
/*!
* Sets the left of the camera to \a left.
*/
void QCamera::setLeft(float left)
{
Q_D(QCamera);
d->m_lens->setLeft(left);
}
float QCamera::left() const
{
Q_D(const QCamera);
return d->m_lens->left();
}
/*!
* Sets the right of the camera to \a right.
*/
void QCamera::setRight(float right)
{
Q_D(QCamera);
d->m_lens->setRight(right);
}
float QCamera::right() const
{
Q_D(const QCamera);
return d->m_lens->right();
}
/*!
* Sets the bottom of the camera to \a bottom.
*/
void QCamera::setBottom(float bottom)
{
Q_D(QCamera);
d->m_lens->setBottom(bottom);
}
float QCamera::bottom() const
{
Q_D(const QCamera);
return d->m_lens->bottom();
}
/*!
* Sets the top of the camera to \a top.
*/
void QCamera::setTop(float top)
{
Q_D(QCamera);
d->m_lens->setTop(top);
}
float QCamera::top() const
{
Q_D(const QCamera);
return d->m_lens->top();
}
/*!
* Sets the camera's projection matrix to \a projectionMatrix.
*/
void QCamera::setProjectionMatrix(const QMatrix4x4 &projectionMatrix)
{
Q_D(QCamera);
d->m_lens->setProjectionMatrix(projectionMatrix);
}
/*!
* Sets the camera's exposure to \a exposure.
*/
void QCamera::setExposure(float exposure)
{
Q_D(QCamera);
d->m_lens->setExposure(exposure);
}
QMatrix4x4 QCamera::projectionMatrix() const
{
Q_D(const QCamera);
return d->m_lens->projectionMatrix();
}
float QCamera::exposure() const
{
Q_D(const QCamera);
return d->m_lens->exposure();
}
/*!
* Sets the camera's position in 3D space to \a position.
*/
void QCamera::setPosition(const QVector3D &position)
{
Q_D(QCamera);
if (!qFuzzyCompare(d->m_position, position)) {
d->m_position = position;
d->m_cameraToCenter = d->m_viewCenter - position;
d->m_viewMatrixDirty = true;
emit positionChanged(position);
emit viewVectorChanged(d->m_cameraToCenter);
d->updateViewMatrixAndTransform();
}
}
QVector3D QCamera::position() const
{
Q_D(const QCamera);
return d->m_position;
}
/*!
* Sets the camera's up vector to \a upVector.
*/
void QCamera::setUpVector(const QVector3D &upVector)
{
Q_D(QCamera);
if (!qFuzzyCompare(d->m_upVector, upVector)) {
d->m_upVector = upVector;
d->m_viewMatrixDirty = true;
emit upVectorChanged(upVector);
d->updateViewMatrixAndTransform();
}
}
QVector3D QCamera::upVector() const
{
Q_D(const QCamera);
return d->m_upVector;
}
/*!
* Sets the camera's view center to \a viewCenter.
*/
void QCamera::setViewCenter(const QVector3D &viewCenter)
{
Q_D(QCamera);
if (!qFuzzyCompare(d->m_viewCenter, viewCenter)) {
d->m_viewCenter = viewCenter;
d->m_cameraToCenter = viewCenter - d->m_position;
d->m_viewMatrixDirty = true;
emit viewCenterChanged(viewCenter);
emit viewVectorChanged(d->m_cameraToCenter);
d->updateViewMatrixAndTransform();
}
}
QVector3D QCamera::viewCenter() const
{
Q_D(const QCamera);
return d->m_viewCenter;
}
QVector3D QCamera::viewVector() const
{
Q_D(const QCamera);
return d->m_cameraToCenter;
}
QMatrix4x4 QCamera::viewMatrix() const
{
Q_D(const QCamera);
return d->m_viewMatrix;
}
} // Qt3DRender
QT_END_NAMESPACE