blob: 621b227780d061900461b22c664a7d6dc5041e14 [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 "qcameralens.h"
#include "qcameralens_p.h"
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
/*!
* \class Qt3DRender::QCameraLens
* \inheaderfile Qt3DRender/QCameraLens
* \inmodule Qt3DRender
*
* \brief Qt3DRender::QCameraLens specifies the projection matrix that will be used to
* define a Camera for a 3D scene.
*
* \since 5.5
*/
/*!
* \qmltype CameraLens
* \instantiates Qt3DRender::QCameraLens
* \inqmlmodule Qt3D.Render
* \inherits Component3D
* \since 5.5
* \brief Provides the projection matrix that is used to define a Camera for 3D scene.
*/
/*!
* \enum Qt3DRender::QCameraLens::ProjectionType
*
* Specifies which parameters of Qt3DRender::QCameraLens are used to compute the projection matrix.
*
* \value OrthographicProjection Orthogonal projection
* \value PerspectiveProjection Perspective projection
* \value FrustumProjection Frustum projection
* \value CustomProjection Custom user-defined projection
*/
/*!
* \qmlproperty enumeration CameraLens::projectionType
*
* Holds the type of the camera projection.
*
* \list
* \li CameraLens.OrthographicProjection
* \li CameraLens.PerspectiveProjection
* \li CameraLens.FrustumProjection
* \li CameraLens.CustomProjection
* \endlist
* \sa Qt3DRender::QCameraLens::ProjectionType
*/
/*!
* \qmlproperty real CameraLens::nearPlane
* Holds the current near plane of the camera lens.
*/
/*!
* \qmlproperty real CameraLens::farPlane
* Holds the current near plane of the camera lens.
*/
/*!
* \qmlproperty real CameraLens::fieldOfView
* Holds the current field of view of the camera lens in degrees.
*/
/*!
* \qmlproperty real CameraLens::aspectRatio
* Holds the current aspect ratio of the camera lens.
*/
/*!
* \qmlproperty real CameraLens::left
* Holds the current left plane of the camera lens.
*/
/*!
* \qmlproperty real CameraLens::right
* Holds the current right plane of the camera lens.
*/
/*!
* \qmlproperty real CameraLens::bottom
* Holds the current bottom plane of the camera lens.
*/
/*!
* \qmlproperty real CameraLens::top
* Holds the current top plane of the camera lens.
*/
/*!
* \qmlproperty matrix4x4 CameraLens::projectionMatrix
* Holds the current projection matrix of the camera lens.
*
* \note This will set the projection type to
* Qt3DRender::QCameraLens::CustomProjection and thus ignore all other camera
* parameters that might have been specified.
* \readonly
*/
/*!
* \property QCameraLens::projectionType
*
* Holds the type of the camera projection.
* \sa Qt3DRender::QCameraLens::ProjectionType
*/
/*!
* \property QCameraLens::nearPlane
* Holds the current near plane of the camera lens.
*/
/*!
* \property QCameraLens::farPlane
* Holds the current near plane of the camera lens.
*/
/*!
* \property QCameraLens::fieldOfView
* Holds the current field of view of the camera lens.
* \note: The return value may be undefined if the projection type is not
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
/*!
* \property QCameraLens::aspectRatio
* Holds the current aspect ratio of the camera lens.
* \note: The return value may be undefined if the projection type is not
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
/*!
* \property QCameraLens::left
* Holds the current left plane of the camera lens.
* \note The return value may be undefined if the projection type is
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
/*!
* \property QCameraLens::right
* Holds the current right plane of the camera lens.
* \note The return value may be undefined if the projection type is
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
/*!
* \property QCameraLens::bottom
* Holds the current bottom plane of the camera lens.
* \note The return value may be undefined if the projection type is
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
/*!
* \property QCameraLens::top
* Holds the current top plane of the camera lens.
* \note The return value may be undefined if the projection type is
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
/*!
* \property QCameraLens::projectionMatrix
* Holds the current projection matrix of the camera lens.
* \readonly
*/
/*!
* \property QCameraLens::exposure
* Holds the current exposure of the camera lens.
*/
/*!
* \internal
*/
QCameraLensPrivate::QCameraLensPrivate()
: Qt3DCore::QComponentPrivate()
, m_projectionType(QCameraLens::PerspectiveProjection)
, m_nearPlane(0.1f)
, m_farPlane(1024.0f)
, m_fieldOfView(25.0f)
, m_aspectRatio(1.0f)
, m_left(-0.5f)
, m_right(0.5f)
, m_bottom(-0.5f)
, m_top(0.5f)
, m_exposure(0.0f)
{
}
void QCameraLens::viewAll(Qt3DCore::QNodeId cameraId)
{
Q_D(QCameraLens);
if (d->m_projectionType == PerspectiveProjection || d->m_projectionType == OrthographicProjection) {
d->m_pendingViewAllRequest = {Qt3DCore::QNodeId::createId(), cameraId, {}};
d->update();
}
}
void QCameraLens::viewEntity(Qt3DCore::QNodeId entityId, Qt3DCore::QNodeId cameraId)
{
Q_D(QCameraLens);
if (d->m_projectionType == PerspectiveProjection || d->m_projectionType == OrthographicProjection) {
d->m_pendingViewAllRequest = {Qt3DCore::QNodeId::createId(), cameraId, entityId};
d->update();
}
}
void QCameraLensPrivate::processViewAllResult(Qt3DCore::QNodeId requestId, const QVector3D &center, float radius)
{
Q_Q(QCameraLens);
if (!m_pendingViewAllRequest || m_pendingViewAllRequest.requestId != requestId)
return;
Q_EMIT q->viewSphere(center, radius);
m_pendingViewAllRequest = {};
}
/*!
* Constructs a QCameraLens with given \a parent
*/
QCameraLens::QCameraLens(QNode *parent)
: Qt3DCore::QComponent(*new QCameraLensPrivate, parent)
{
Q_D(QCameraLens);
d->updateProjectionMatrix();
}
/*! \internal */
QCameraLens::~QCameraLens()
{
}
QCameraLens::QCameraLens(QCameraLensPrivate &dd, QNode *parent)
: QComponent(dd, parent)
{
Q_D(QCameraLens);
d->updateOrthographicProjection();
}
/*!
* Sets the lens' projection type \a projectionType.
*
* \note Qt3DRender::QCameraLens::Frustum and
* Qt3DRender::QCameraLens::PerspectiveProjection are two different ways of
* specifying the same projection.
*/
void QCameraLens::setProjectionType(QCameraLens::ProjectionType projectionType)
{
Q_D(QCameraLens);
if (d->m_projectionType != projectionType) {
d->m_projectionType = projectionType;
const bool wasBlocked = blockNotifications(true);
emit projectionTypeChanged(projectionType);
blockNotifications(wasBlocked);
d->updateProjectionMatrix();
}
}
QCameraLens::ProjectionType QCameraLens::projectionType() const
{
Q_D(const QCameraLens);
return d->m_projectionType;
}
/*!
* Defines an orthographic projection based on \a left, \a right, \a bottom, \a
* top, \a nearPlane, \a farPlane.
*/
void QCameraLens::setOrthographicProjection(float left, float right,
float bottom, float top,
float nearPlane, float farPlane)
{
Q_D(QCameraLens);
bool block = blockNotifications(true);
setLeft(left);
setRight(right);
setBottom(bottom);
setTop(top);
setNearPlane(nearPlane);
setFarPlane(farPlane);
setProjectionType(OrthographicProjection);
blockNotifications(block);
d->updateProjectionMatrix();
}
/*!
* Defines an orthographic projection based on \a left, \a right, \a bottom, \a
* top, \a nearPlane, \a farPlane.
*/
void QCameraLens::setFrustumProjection(float left, float right,
float bottom, float top,
float nearPlane, float farPlane)
{
Q_D(QCameraLens);
bool block = blockNotifications(true);
setLeft(left);
setRight(right);
setBottom(bottom);
setTop(top);
setNearPlane(nearPlane);
setFarPlane(farPlane);
setProjectionType(FrustumProjection);
blockNotifications(block);
d->updateProjectionMatrix();
}
/*!
* Defines a perspective projection based on \a fieldOfView, \a aspectRatio, \a
* nearPlane, \a farPlane.
*/
void QCameraLens::setPerspectiveProjection(float fieldOfView, float aspectRatio,
float nearPlane, float farPlane)
{
Q_D(QCameraLens);
bool block = blockNotifications(true);
setFieldOfView(fieldOfView);
setAspectRatio(aspectRatio);
setNearPlane(nearPlane);
setFarPlane(farPlane);
setProjectionType(PerspectiveProjection);
blockNotifications(block);
d->updateProjectionMatrix();
}
/*!
* Sets the projection's near plane to \a nearPlane. This triggers a projection
* matrix update.
*/
void QCameraLens::setNearPlane(float nearPlane)
{
Q_D(QCameraLens);
if (qFuzzyCompare(d->m_nearPlane, nearPlane))
return;
d->m_nearPlane = nearPlane;
const bool wasBlocked = blockNotifications(true);
emit nearPlaneChanged(nearPlane);
blockNotifications(wasBlocked);
d->updateProjectionMatrix();
}
float QCameraLens::nearPlane() const
{
Q_D(const QCameraLens);
return d->m_nearPlane;
}
/*!
* Sets the projection's far plane to \a farPlane. This triggers a projection
* matrix update.
*/
void QCameraLens::setFarPlane(float farPlane)
{
Q_D(QCameraLens);
if (qFuzzyCompare(d->m_farPlane, farPlane))
return;
d->m_farPlane = farPlane;
const bool wasBlocked = blockNotifications(true);
emit farPlaneChanged(farPlane);
blockNotifications(wasBlocked);
d->updateProjectionMatrix();
}
float QCameraLens::farPlane() const
{
Q_D(const QCameraLens);
return d->m_farPlane;
}
/*!
* Sets the projection's field of view to \a fieldOfView degrees. This triggers
* a projection matrix update.
*
* \note this has no effect if the projection type is not
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
void QCameraLens::setFieldOfView(float fieldOfView)
{
Q_D(QCameraLens);
if (qFuzzyCompare(d->m_fieldOfView, fieldOfView))
return;
d->m_fieldOfView = fieldOfView;
const bool wasBlocked = blockNotifications(true);
emit fieldOfViewChanged(fieldOfView);
blockNotifications(wasBlocked);
d->updateProjectionMatrix();
}
float QCameraLens::fieldOfView() const
{
Q_D(const QCameraLens);
return d->m_fieldOfView;
}
/*!
* Sets the projection's aspect ratio to \a aspectRatio. This triggers a projection
* matrix update.
*
* \note this has no effect if the projection type is not
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
void QCameraLens::setAspectRatio(float aspectRatio)
{
Q_D(QCameraLens);
if (qFuzzyCompare(d->m_aspectRatio, aspectRatio))
return;
d->m_aspectRatio = aspectRatio;
const bool wasBlocked = blockNotifications(true);
emit aspectRatioChanged(aspectRatio);
blockNotifications(wasBlocked);
d->updateProjectionMatrix();
}
float QCameraLens::aspectRatio() const
{
Q_D(const QCameraLens);
return d->m_aspectRatio;
}
/*!
* Sets the projection's lower left window coordinate to \a left. This
* triggers a projection matrix update.
*
* \note this has no effect if the projection type is
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
void QCameraLens::setLeft(float left)
{
Q_D(QCameraLens);
if (qFuzzyCompare(d->m_left, left))
return;
d->m_left = left;
const bool wasBlocked = blockNotifications(true);
emit leftChanged(left);
blockNotifications(wasBlocked);
d->updateProjectionMatrix();
}
float QCameraLens::left() const
{
Q_D(const QCameraLens);
return d->m_left;
}
/*!
* Sets the projection's upper right window coordinate to \a right. This triggers
* a projection matrix update.
*
* \note this has no effect if the projection type is
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
void QCameraLens::setRight(float right)
{
Q_D(QCameraLens);
if (qFuzzyCompare(d->m_right, right))
return;
d->m_right = right;
const bool wasBlocked = blockNotifications(true);
emit rightChanged(right);
blockNotifications(wasBlocked);
d->updateProjectionMatrix();
}
float QCameraLens::right() const
{
Q_D(const QCameraLens);
return d->m_right;
}
/*!
* Sets the projection's bottom window coordinate to \a bottom. This triggers a
* projection matrix update.
*
* \note this has no effect if the projection type is
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
void QCameraLens::setBottom(float bottom)
{
Q_D(QCameraLens);
if (qFuzzyCompare(d->m_bottom, bottom))
return;
d->m_bottom = bottom;
const bool wasBlocked = blockNotifications(true);
emit bottomChanged(bottom);
blockNotifications(wasBlocked);
d->updateProjectionMatrix();
}
float QCameraLens::bottom() const
{
Q_D(const QCameraLens);
return d->m_bottom;
}
/*!
* Sets the projection's top window coordinate to \a top. This triggers a
* projection matrix update.
*
* \note this has no effect if the projection type is
* Qt3DRender::QCameraLens::PerspectiveProjection.
*/
void QCameraLens::setTop(float top)
{
Q_D(QCameraLens);
if (qFuzzyCompare(d->m_top, top))
return;
d->m_top = top;
const bool wasBlocked = blockNotifications(true);
emit topChanged(top);
blockNotifications(wasBlocked);
d->updateProjectionMatrix();
}
float QCameraLens::top() const
{
Q_D(const QCameraLens);
return d->m_top;
}
/*!
* Sets the project matrix to \a projectionMatrix.
*
* \note This will set the projection type to Qt3DRender::QCameraLens::CustomProjection and thus
* ignore all other camera parameters that might have been specified.
*/
void QCameraLens::setProjectionMatrix(const QMatrix4x4 &projectionMatrix)
{
Q_D(QCameraLens);
setProjectionType(CustomProjection);
if (qFuzzyCompare(d->m_projectionMatrix, projectionMatrix))
return;
d->m_projectionMatrix = projectionMatrix;
emit projectionMatrixChanged(projectionMatrix);
}
QMatrix4x4 QCameraLens::projectionMatrix() const
{
Q_D(const QCameraLens);
return d->m_projectionMatrix;
}
/*!
* Sets the camera lens' \a exposure
*/
void QCameraLens::setExposure(float exposure)
{
Q_D(QCameraLens);
if (qFuzzyCompare(d->m_exposure, exposure))
return;
d->m_exposure = exposure;
emit exposureChanged(exposure);
}
float QCameraLens::exposure() const
{
Q_D(const QCameraLens);
return d->m_exposure;
}
Qt3DCore::QNodeCreatedChangeBasePtr QCameraLens::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QCameraLensData>::create(this);
auto &data = creationChange->data;
data.projectionMatrix = d_func()->m_projectionMatrix;
data.exposure = d_func()->m_exposure;
return creationChange;
}
void QCameraLens::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
{
Q_UNUSED(change)
}
} // Qt3DRender
QT_END_NAMESPACE