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_NODE_H |
6 | #define QSSG_RENDER_NODE_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/qssgrendergraphobject_p.h> |
20 | |
21 | #include <QtQuick3DUtils/private/qssgbounds3_p.h> |
22 | #include <QtQuick3DUtils/private/qssginvasivelinkedlist_p.h> |
23 | |
24 | #include <QtGui/QMatrix4x4> |
25 | #include <QtGui/QVector3D> |
26 | |
27 | QT_BEGIN_NAMESPACE |
28 | |
29 | struct QSSGRenderModel; |
30 | struct QSSGRenderLight; |
31 | struct QSSGRenderCamera; |
32 | struct QSSGRenderText; |
33 | struct QSSGRenderNode; |
34 | class QSSGBufferManager; |
35 | |
36 | struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderNode : public QSSGRenderGraphObject |
37 | { |
38 | enum class LocalState : quint8 |
39 | { |
40 | Active = 1 << 0, |
41 | Pickable = 1 << 1 |
42 | }; |
43 | |
44 | enum class GlobalState : quint8 |
45 | { |
46 | Active = 1 << 2, |
47 | Pickable = 1 << 3 |
48 | }; |
49 | |
50 | enum class DirtyFlag : quint32 |
51 | { |
52 | TransformDirty = 1 << 4, |
53 | OpacityDirty = 1 << 5, |
54 | ActiveDirty = 1 << 6, |
55 | PickableDirty = 1 << 7, |
56 | SubNodeDirty = 1 << 8, // Sub-nodes should set/unest this if they "extend" the dirty flags provided by the node |
57 | |
58 | GlobalValuesDirty = TransformDirty | OpacityDirty | ActiveDirty | PickableDirty, |
59 | DirtyMask = GlobalValuesDirty | SubNodeDirty |
60 | }; |
61 | using FlagT = std::underlying_type_t<DirtyFlag>; |
62 | |
63 | static constexpr QVector3D initScale { 1.0f, 1.0f, 1.0f }; |
64 | |
65 | // changing any one of these means you have to |
66 | // set this object dirty |
67 | QVector3D pivot; |
68 | int staticFlags = 0; |
69 | |
70 | // This only sets dirty, not transform dirty |
71 | // Opacity of 1 means opaque, opacity of zero means transparent. |
72 | float localOpacity = 1.0f; |
73 | |
74 | // Nodes are initially dirty and locally active! |
75 | FlagT flags { FlagT(DirtyFlag::GlobalValuesDirty) | FlagT(LocalState::Active) }; |
76 | // These end up right handed |
77 | QMatrix4x4 localTransform; |
78 | QMatrix4x4 globalTransform; |
79 | QMatrix4x4 localInstanceTransform; |
80 | QMatrix4x4 globalInstanceTransform; |
81 | float globalOpacity = 1.0f; |
82 | |
83 | // node graph members. |
84 | QSSGRenderNode *parent = nullptr; |
85 | QSSGRenderNode *nextSibling = nullptr; |
86 | QSSGRenderNode *previousSibling = nullptr; |
87 | QSSGRenderNode *instanceRoot = nullptr; |
88 | // Property maintained solely by the render system. |
89 | // Depth-first-search index assigned and maintained by render system. |
90 | quint32 dfsIndex = 0; |
91 | |
92 | using ChildList = QSSGInvasiveLinkedList<QSSGRenderNode, &QSSGRenderNode::previousSibling, &QSSGRenderNode::nextSibling>; |
93 | ChildList children; |
94 | |
95 | QString debugObjectName; |
96 | |
97 | QSSGRenderNode(); |
98 | explicit QSSGRenderNode(Type type); |
99 | ~QSSGRenderNode() override; |
100 | |
101 | // Sets this object dirty and walks down the graph setting all |
102 | // children who are not dirty to be dirty. |
103 | void markDirty(DirtyFlag dirtyFlag); |
104 | void clearDirty(DirtyFlag dirtyFlag); |
105 | [[nodiscard]] inline constexpr bool isDirty(DirtyFlag dirtyFlag = DirtyFlag::DirtyMask) const { return ((flags & FlagT(dirtyFlag)) != 0); } |
106 | void setState(LocalState state, bool on = true); |
107 | [[nodiscard]] inline constexpr bool getLocalState(LocalState stateFlag) const { return ((flags & FlagT(stateFlag)) != 0); } |
108 | [[nodiscard]] inline constexpr bool getGlobalState(GlobalState stateFlag) const { return ((flags & FlagT(stateFlag)) != 0); } |
109 | |
110 | void addChild(QSSGRenderNode &inChild); |
111 | void removeChild(QSSGRenderNode &inChild); |
112 | |
113 | // Remove this node from the graph. |
114 | // It is no longer the the parent's child lists |
115 | // and all of its children no longer have a parent |
116 | // finally they are no longer siblings of each other. |
117 | void removeFromGraph(); |
118 | |
119 | // Calculate global transform and opacity |
120 | // Walks up the graph ensure all parents are not dirty so they have |
121 | // valid global transforms. |
122 | bool calculateGlobalVariables(); |
123 | |
124 | // Calculates a tranform matrix based on the position, scale, pivot and rotation arguments. |
125 | // NOTE!!!: This function does not update or mark any nodes as dirty, if the returned matrix is set on a node then |
126 | // markDirty, calculateGlobalVariables etc. needs to be called as needed! |
127 | [[nodiscard]] static QMatrix4x4 calculateTransformMatrix(QVector3D position, QVector3D scale, QVector3D pivot, QQuaternion rotation); |
128 | |
129 | // Get the bounds of us and our children in our local space. |
130 | QSSGBounds3 getBounds(QSSGBufferManager &inManager, |
131 | bool inIncludeChildren = true) const; |
132 | QSSGBounds3 getChildBounds(QSSGBufferManager &inManager) const; |
133 | // Assumes CalculateGlobalVariables has already been called. |
134 | QVector3D getGlobalPos() const { return QVector3D(globalTransform(0, 3), globalTransform(1, 3), globalTransform(2, 3)); } |
135 | QVector3D getGlobalPivot() const; |
136 | // Pulls the 3rd column out of the global transform. |
137 | QVector3D getDirection() const; |
138 | // Multiplies (0,0,-1) by the inverse transpose of the upper 3x3 of the global transform. |
139 | // This is correct w/r/t to scaling and which the above getDirection is not. |
140 | QVector3D getScalingCorrectDirection() const; |
141 | |
142 | // outMVP and outNormalMatrix are returned ready to upload to openGL, meaning they are |
143 | // row-major. |
144 | void calculateMVPAndNormalMatrix(const QMatrix4x4 &inViewProjection, QMatrix4x4 &outMVP, QMatrix3x3 &outNormalMatrix) const; |
145 | |
146 | // This should be in a utility file somewhere |
147 | QMatrix3x3 calculateNormalMatrix() const; |
148 | |
149 | // The Squared value of \a val |
150 | // This is mainly used for setting the sorting bias on models and particles |
151 | // since we're using the squared distance when sorting. |
152 | [[nodiscard]] static inline float signedSquared(float val) |
153 | { |
154 | const float sign = (val >= 0.0f) ? 1.0f : -1.0f; |
155 | return sign * val * val; |
156 | } |
157 | }; |
158 | |
159 | QT_END_NAMESPACE |
160 | |
161 | #endif |
162 | |