1 /****************************************************************************
2 **
3 ** Copyright (C) 2008-2012 NVIDIA Corporation.
4 ** Copyright (C) 2019 The Qt Company Ltd.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of Qt Quick 3D.
8 **
9 ** $QT_BEGIN_LICENSE:GPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU
20 ** General Public License version 3 or (at your option) any later version
21 ** approved by the KDE Free Qt Foundation. The licenses are as published by
22 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
23 ** included in the packaging of this file. Please review the following
24 ** information to ensure the GNU General Public License requirements will
25 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
26 **
27 ** $QT_END_LICENSE$
28 **
29 ****************************************************************************/
30 
31 #ifndef QSSG_RENDER_CAMERA_H
32 #define QSSG_RENDER_CAMERA_H
33 
34 //
35 //  W A R N I N G
36 //  -------------
37 //
38 // This file is not part of the Qt API.  It exists purely as an
39 // implementation detail.  This header file may change from version to
40 // version without notice, or even be removed.
41 //
42 // We mean it.
43 //
44 
45 #include <QtQuick3DRuntimeRender/private/qtquick3druntimerenderglobal_p.h>
46 
47 #include <QtQuick3DRuntimeRender/private/qssgrendernode_p.h>
48 #include <QtQuick3DRuntimeRender/private/qssgrenderray_p.h>
49 
50 #include <QtQuick3DRender/private/qssgrenderbasetypes_p.h>
51 
52 QT_BEGIN_NAMESPACE
53 
54 struct QSSGCameraGlobalCalculationResult
55 {
56     bool m_wasDirty;
57     bool m_computeFrustumSucceeded /* = true */;
58 };
59 
60 struct QSSGCuboidRect
61 {
62     float left;
63     float top;
64     float right;
65     float bottom;
66     constexpr QSSGCuboidRect(float l = 0.0f, float t = 0.0f, float r = 0.0f, float b = 0.0f)
leftQSSGCuboidRect67         : left(l), top(t), right(r), bottom(b)
68     {
69     }
translateQSSGCuboidRect70     void translate(QVector2D inTranslation)
71     {
72         left += inTranslation.x();
73         right += inTranslation.x();
74         top += inTranslation.y();
75         bottom += inTranslation.y();
76     }
77 };
78 
79 struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderCamera : public QSSGRenderNode
80 {
81     // Setting these variables should set dirty on the camera.
82     float clipNear;
83     float clipFar;
84 
85     float fov; // Radians
86     bool fovHorizontal;
87 
88     float top = 0.0f;
89     float bottom = 0.0f;
90     float left = 0.0f;
91     float right = 0.0f;
92 
93     QMatrix4x4 projection;
94     // Record some values from creating the projection matrix
95     // to use during mouse picking.
96     QVector2D frustumScale;
97     bool enableFrustumClipping;
98 
99     QRectF previousInViewport;
100 
101     QSSGRenderCamera();
102 
103     QMatrix3x3 getLookAtMatrix(const QVector3D &inUpDir, const QVector3D &inDirection) const;
104     // Set our position, rotation member variables based on the lookat target
105     // Marks this object as dirty.
106     // Need to test this when the camera's local transform is null.
107     // Assumes parent's local transform is the identity, meaning our local transform is
108     // our global transform.
109     void lookAt(const QVector3D &inCameraPos, const QVector3D &inUpDir, const QVector3D &inTargetPos);
110 
111     QSSGCameraGlobalCalculationResult calculateGlobalVariables(const QRectF &inViewport);
112     bool calculateProjection(const QRectF &inViewport);
113     bool computeFrustumOrtho(const QRectF &inViewport);
114     // Used when rendering the widgets in studio.  This scales the widget when in orthographic
115     // mode in order to have
116     // constant size on screen regardless.
117     // Number is always greater than one
118     float getOrthographicScaleFactor(const QRectF &inViewport) const;
119     bool computeFrustumPerspective(const QRectF &inViewport);
120     bool computeCustomFrustum(const QRectF &inViewport);
121 
122     void calculateViewProjectionMatrix(QMatrix4x4 &outMatrix) const;
123 
124     // If this is an orthographic camera, the cuboid properties are the distance from the center
125     // point
126     // to the left, top, right, and bottom edges of the view frustum in world units.
127     // If this is a perspective camera, the cuboid properties are the FOV angles
128     // (left,top,right,bottom)
129     // of the view frustum.
130 
131     // Return a normalized rect that describes the area the camera is rendering to.
132     // This takes into account the various camera properties (scale mode, scale anchor).
133     QSSGCuboidRect getCameraBounds(const QRectF &inViewport) const;
134 
135     // Setup a camera VP projection for rendering offscreen.
136     static void setupOrthographicCameraForOffscreenRender(QSSGRenderTexture2D &inTexture, QMatrix4x4 &outVP);
137 
138     // Unproject a point (x,y) in viewport relative coordinates meaning
139     // left, bottom is 0,0 and values are increasing right,up respectively.
140     QSSGRenderRay unproject(const QVector2D &inLayerRelativeMouseCoords, const QRectF &inViewport) const;
141 
142     // Unproject a given coordinate to a 3d position that lies on the same camera
143     // plane as inGlobalPos.
144     // Expects CalculateGlobalVariables has been called or doesn't need to be.
145     QVector3D unprojectToPosition(const QVector3D &inGlobalPos, const QSSGRenderRay &inRay) const;
146 
147     float verticalFov(float aspectRatio) const;
148     float verticalFov(const QRectF &inViewport) const;
149 };
150 
151 QT_END_NAMESPACE
152 
153 #endif
154