| /**************************************************************************** |
| ** |
| ** 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 ¢er, 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 |