1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dperspectivecamera_p.h"
5
6#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
7
8#include <QtMath>
9#include <QtQuick3DUtils/private/qssgutils_p.h>
10
11#include "qquick3dutils_p.h"
12
13#include "qquick3dnode_p_p.h"
14
15QT_BEGIN_NAMESPACE
16
17/*!
18 \qmltype PerspectiveCamera
19 \inherits Camera
20 \inqmlmodule QtQuick3D
21 \brief Defines a Perspective Camera for viewing the content of a 3D scene.
22
23 A \l Camera defines how the content of the 3D scene is projected onto a 2D surface,
24 such as a View3D. A scene needs at least one \l Camera in order to visualize its
25 contents.
26
27 It is possible to position and rotate the \l Camera like any other spatial \l{QtQuick3D::Node}{Node} in
28 the scene. The \l{QtQuick3D::Node}{Node}'s location and orientation determines where the \l Camera is in
29 the scene, and what direction it is facing. The default orientation of the \l Camera
30 has its forward vector pointing along the negative Z axis and its up vector along
31 the positive Y axis.
32
33 \image perspectivecamera.png
34
35 PerspectiveCamera is the standard \l Camera type. It gives a realistic projection of the
36 scene, where distant objects are perceived as smaller. The frustum is defined by
37 the fieldOfView property as well as near and far clip planes.
38
39 The following example creates a PerspectiveCamera at position [0, 200, 300] in the scene, a
40 field of view of 90 degrees and with a 30 degree downward pitch.
41 \code
42 PerspectiveCamera {
43 position: Qt.vector3d(0, 200, 300)
44 eulerRotation.x: -30
45 fieldOfView: 90
46 }
47 \endcode
48
49 \sa {Qt Quick 3D - View3D Example}, OrthographicCamera, FrustumCamera, CustomCamera
50*/
51
52/*!
53 \internal
54*/
55QQuick3DPerspectiveCamera::QQuick3DPerspectiveCamera(QQuick3DNodePrivate &dd, QQuick3DNode *parent)
56 : QQuick3DCamera(dd, parent)
57{}
58
59/*!
60 \internal
61*/
62QQuick3DPerspectiveCamera::QQuick3DPerspectiveCamera(QQuick3DNode *parent)
63 : QQuick3DPerspectiveCamera(*(new QQuick3DNodePrivate(QQuick3DNodePrivate::Type::PerspectiveCamera)), parent)
64{}
65
66/*!
67 \qmlproperty real PerspectiveCamera::clipNear
68
69 This property defines the near clip plane of the PerspectiveCamera's frustum. Geometry which
70 is closer to the \l Camera than the near clip plane will not be visible.
71
72 The default value is 10.0. The unit depends on the user's geometry units,
73 and the value is relative to the global camera position.
74*/
75
76float QQuick3DPerspectiveCamera::clipNear() const
77{
78 return m_clipNear;
79}
80
81/*!
82 \qmlproperty real PerspectiveCamera::clipFar
83
84 This property defines the far clip plane of the PerspectiveCamera's frustum. Geometry which
85 is further away from the \l Camera than the far clip plane will not be visible.
86
87 The default value is 10000.0. The unit depends on the user's geometry units,
88 and the value is relative to the global camera position.
89*/
90
91float QQuick3DPerspectiveCamera::clipFar() const
92{
93 return m_clipFar;
94}
95
96/*!
97 \qmlproperty enumeration PerspectiveCamera::fieldOfViewOrientation
98
99 This property holds the orientation in which camera field of view is given.
100
101 \value PerspectiveCamera.Vertical
102 The provided field of view is vertical, meaning the field of view is the angle between
103 the line traced from the camera to the center top of the viewport and the line from
104 the camera to the center bottom of the viewport. The horizontal aspect ratio will be
105 adjusted to maintain aspect ratio.
106 \value PerspectiveCamera.Horizontal
107 The provided field of view is horizontal, meaning the field of view is the angle between
108 the line traced from the camera to the center left side of the viewport and the line from
109 the camera to the center right side of the viewport. The vertical aspect ratio will be
110 adjusted to maintain aspect ratio.
111
112
113 The default value is \c {PerspectiveCamera.Vertical}.
114 */
115
116/*!
117 \qmlproperty real PerspectiveCamera::fieldOfView
118
119 This property holds the field of view of the camera in degrees. This can be either the
120 vertical or horizontal field of view depending on whether the fieldOfViewOrientation property
121 is set to \c {PerspectiveCamera.Vertical} or \c {PerspectiveCamera.Horizontal}.
122
123 The default value is 60.0.
124 */
125
126float QQuick3DPerspectiveCamera::fieldOfView() const
127{
128 return m_fieldOfView;
129}
130
131QQuick3DPerspectiveCamera::FieldOfViewOrientation QQuick3DPerspectiveCamera::fieldOfViewOrientation() const
132{
133 return m_fieldOfViewOrientation;
134}
135
136void QQuick3DPerspectiveCamera::setClipNear(float clipNear)
137{
138 if (qFuzzyCompare(p1: m_clipNear, p2: clipNear))
139 return;
140
141 m_clipNear = clipNear;
142 emit clipNearChanged();
143 update();
144}
145
146void QQuick3DPerspectiveCamera::setClipFar(float clipFar)
147{
148 if (qFuzzyCompare(p1: m_clipFar, p2: clipFar))
149 return;
150
151 m_clipFar = clipFar;
152 emit clipFarChanged();
153 update();
154}
155
156void QQuick3DPerspectiveCamera::setFieldOfView(float fieldOfView)
157{
158 if (qFuzzyCompare(p1: m_fieldOfView, p2: fieldOfView))
159 return;
160
161 m_fieldOfView = fieldOfView;
162 emit fieldOfViewChanged();
163 update();
164}
165
166void QQuick3DPerspectiveCamera::setFieldOfViewOrientation(QQuick3DPerspectiveCamera::FieldOfViewOrientation
167 fieldOfViewOrientation)
168{
169 if (m_fieldOfViewOrientation == fieldOfViewOrientation)
170 return;
171
172 m_fieldOfViewOrientation = fieldOfViewOrientation;
173 emit fieldOfViewOrientationChanged();
174 update();
175}
176
177QSSGRenderGraphObject *QQuick3DPerspectiveCamera::updateSpatialNode(QSSGRenderGraphObject *node)
178{
179 QSSGRenderCamera *camera = static_cast<QSSGRenderCamera *>(QQuick3DCamera::updateSpatialNode(node));
180 if (camera) {
181 const bool changed = ((int(qUpdateIfNeeded(orig&: camera->clipNear, updated: m_clipNear))
182 | int(qUpdateIfNeeded(orig&: camera->clipFar, updated: m_clipFar))
183 | int(qUpdateIfNeeded(orig&: camera->fov, updated: qDegreesToRadians(degrees: m_fieldOfView)))
184 | int(qUpdateIfNeeded(orig&: camera->fovHorizontal, updated: m_fieldOfViewOrientation == QQuick3DPerspectiveCamera::FieldOfViewOrientation::Horizontal))) != 0);
185 if (changed)
186 camera->markDirty(dirtyFlag: QSSGRenderCamera::DirtyFlag::CameraDirty);
187 }
188
189 return camera;
190}
191
192QT_END_NAMESPACE
193

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