1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2019 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
5#ifndef QSSG_RENDER_CAMERA_H
6#define QSSG_RENDER_CAMERA_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtQuick3DRuntimeRender/private/qtquick3druntimerenderglobal_p.h>
20
21#include <QtQuick3DRuntimeRender/private/qssgrendernode_p.h>
22#include <QtQuick3DRuntimeRender/private/qssgrenderray_p.h>
23
24#include <QtQuick3DUtils/private/qssgrenderbasetypes_p.h>
25
26QT_BEGIN_NAMESPACE
27
28struct QSSGCameraGlobalCalculationResult
29{
30 bool m_wasDirty;
31 bool m_computeFrustumSucceeded /* = true */;
32};
33
34struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderCamera : public QSSGRenderNode
35{
36 enum class DirtyFlag : quint8
37 {
38 CameraDirty = 0x1
39 };
40 using FlagT = std::underlying_type_t<DirtyFlag>;
41
42 static constexpr DirtyFlag DirtyMask { std::numeric_limits<FlagT>::max() };
43
44 // Setting these variables should set dirty on the camera.
45 float clipNear;
46 float clipFar;
47
48 float fov; // Radians
49 bool fovHorizontal;
50
51 float top = 0.0f;
52 float bottom = 0.0f;
53 float left = 0.0f;
54 float right = 0.0f;
55
56 float horizontalMagnification = 1.0f;
57 float verticalMagnification = 1.0f;
58
59 float dpr = 1.0f;
60
61 QMatrix4x4 projection;
62 // Record some values from creating the projection matrix
63 // to use during mouse picking.
64 QVector2D frustumScale;
65 bool enableFrustumClipping;
66 FlagT cameraDirtyFlags = 0;
67
68 float levelOfDetailPixelThreshold = 1.0;
69
70 QRectF previousInViewport;
71
72 explicit QSSGRenderCamera(QSSGRenderGraphObject::Type type);
73
74 QMatrix3x3 getLookAtMatrix(const QVector3D &inUpDir, const QVector3D &inDirection) const;
75 // Set our position, rotation member variables based on the lookat target
76 // Marks this object as dirty.
77 // Need to test this when the camera's local transform is null.
78 // Assumes parent's local transform is the identity, meaning our local transform is
79 // our global transform.
80 void lookAt(const QVector3D &inCameraPos, const QVector3D &inUpDir, const QVector3D &inTargetPos, const QVector3D &pivot);
81
82 QSSGCameraGlobalCalculationResult calculateGlobalVariables(const QRectF &inViewport);
83 bool calculateProjection(const QRectF &inViewport);
84 bool computeFrustumOrtho(const QRectF &inViewport);
85 // Used when rendering the widgets in studio. This scales the widget when in orthographic
86 // mode in order to have
87 // constant size on screen regardless.
88 // Number is always greater than one
89 float getOrthographicScaleFactor(const QRectF &inViewport) const;
90 bool computeFrustumPerspective(const QRectF &inViewport);
91 bool computeCustomFrustum(const QRectF &inViewport);
92
93 void calculateViewProjectionMatrix(QMatrix4x4 &outMatrix) const;
94
95 void calculateViewProjectionWithoutTranslation(float near, float far, QMatrix4x4 &outMatrix) const;
96
97 // Unproject a point (x,y) in viewport relative coordinates meaning
98 // left, bottom is 0,0 and values are increasing right,up respectively.
99 QSSGRenderRay unproject(const QVector2D &inLayerRelativeMouseCoords, const QRectF &inViewport) const;
100
101 // Unproject a given coordinate to a 3d position that lies on the same camera
102 // plane as inGlobalPos.
103 // Expects CalculateGlobalVariables has been called or doesn't need to be.
104 QVector3D unprojectToPosition(const QVector3D &inGlobalPos, const QSSGRenderRay &inRay) const;
105
106 float verticalFov(float aspectRatio) const;
107 float verticalFov(const QRectF &inViewport) const;
108
109 [[nodiscard]] inline bool isDirty(DirtyFlag dirtyFlag = DirtyMask) const
110 {
111 return ((cameraDirtyFlags & FlagT(dirtyFlag)) != 0)
112 || ((dirtyFlag == DirtyMask) && QSSGRenderNode::isDirty());
113 }
114 void markDirty(DirtyFlag dirtyFlag);
115 void clearDirty(DirtyFlag dirtyFlag);
116
117 float getLevelOfDetailMultiplier() const;
118};
119
120QT_END_NAMESPACE
121
122#endif
123

source code of qtquick3d/src/runtimerender/graphobjects/qssgrendercamera_p.h