1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). |
4 | ** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). |
5 | ** Contact: https://www.qt.io/licensing/ |
6 | ** |
7 | ** This file is part of the Qt3D module of the Qt Toolkit. |
8 | ** |
9 | ** $QT_BEGIN_LICENSE:LGPL$ |
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 Lesser General Public License Usage |
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
20 | ** General Public License version 3 as published by the Free Software |
21 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
22 | ** packaging of this file. Please review the following information to |
23 | ** ensure the GNU Lesser General Public License version 3 requirements |
24 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
25 | ** |
26 | ** GNU General Public License Usage |
27 | ** Alternatively, this file may be used under the terms of the GNU |
28 | ** General Public License version 2.0 or (at your option) the GNU General |
29 | ** Public license version 3 or any later version approved by the KDE Free |
30 | ** Qt Foundation. The licenses are as published by the Free Software |
31 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
32 | ** included in the packaging of this file. Please review the following |
33 | ** information to ensure the GNU General Public License requirements will |
34 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
35 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
36 | ** |
37 | ** $QT_END_LICENSE$ |
38 | ** |
39 | ****************************************************************************/ |
40 | |
41 | #ifndef QT3DRENDER_RENDER_ENTITY_H |
42 | #define QT3DRENDER_RENDER_ENTITY_H |
43 | |
44 | // |
45 | // W A R N I N G |
46 | // ------------- |
47 | // |
48 | // This file is not part of the Qt API. It exists for the convenience |
49 | // of other Qt classes. This header file may change from version to |
50 | // version without notice, or even be removed. |
51 | // |
52 | // We mean it. |
53 | // |
54 | |
55 | #include <Qt3DRender/private/backendnode_p.h> |
56 | #include <Qt3DRender/private/abstractrenderer_p.h> |
57 | #include <Qt3DRender/private/handle_types_p.h> |
58 | #include <Qt3DCore/qnodecreatedchange.h> |
59 | #include <Qt3DCore/private/qentity_p.h> |
60 | #include <Qt3DCore/private/qhandle_p.h> |
61 | #include <QVector> |
62 | |
63 | QT_BEGIN_NAMESPACE |
64 | |
65 | class QMatrix4x4; |
66 | |
67 | namespace Qt3DCore { |
68 | class QNode; |
69 | class QEntity; |
70 | class QComponent; |
71 | } |
72 | |
73 | namespace Qt3DRender { |
74 | |
75 | class QRenderAspect; |
76 | |
77 | namespace Render { |
78 | |
79 | class Sphere; |
80 | class Renderer; |
81 | class NodeManagers; |
82 | class EntityPrivate; |
83 | |
84 | class Q_3DRENDERSHARED_PRIVATE_EXPORT Entity : public BackendNode |
85 | { |
86 | public: |
87 | Entity(); |
88 | ~Entity(); |
89 | void cleanup(); |
90 | |
91 | void setParentHandle(HEntity parentHandle); |
92 | void setNodeManagers(NodeManagers *manager); |
93 | void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; |
94 | |
95 | void dump() const; |
96 | |
97 | void setHandle(HEntity handle); |
98 | HEntity handle() const { return m_handle; } |
99 | Entity *parent() const; |
100 | HEntity parentHandle() const { return m_parentHandle; } |
101 | |
102 | void removeFromParentChildHandles(); |
103 | void appendChildHandle(HEntity childHandle); |
104 | void removeChildHandle(HEntity childHandle) { m_childrenHandles.removeOne(t: childHandle); } |
105 | QVector<HEntity> childrenHandles() const { return m_childrenHandles; } |
106 | QVector<Entity *> children() const; |
107 | bool hasChildren() const { return !m_childrenHandles.empty(); } |
108 | void traverse(const std::function<void(Entity *)> &operation); |
109 | void traverse(const std::function<void(const Entity *)> &operation) const; |
110 | |
111 | Matrix4x4 *worldTransform(); |
112 | const Matrix4x4 *worldTransform() const; |
113 | Sphere *localBoundingVolume() const { return m_localBoundingVolume.data(); } |
114 | Sphere *worldBoundingVolume() const { return m_worldBoundingVolume.data(); } |
115 | Sphere *worldBoundingVolumeWithChildren() const { return m_worldBoundingVolumeWithChildren.data(); } |
116 | |
117 | void addComponent(Qt3DCore::QNodeIdTypePair idAndType); |
118 | void removeComponent(Qt3DCore::QNodeId nodeId); |
119 | |
120 | bool isBoundingVolumeDirty() const; |
121 | void unsetBoundingVolumeDirty(); |
122 | |
123 | void setTreeEnabled(bool enabled) { m_treeEnabled = enabled; } |
124 | bool isTreeEnabled() const { return m_treeEnabled; } |
125 | |
126 | Qt3DCore::QNodeIdVector layerIds() const { return m_layerComponents + m_recursiveLayerComponents; } |
127 | void addRecursiveLayerId(const Qt3DCore::QNodeId layerId); |
128 | void removeRecursiveLayerId(const Qt3DCore::QNodeId layerId); |
129 | void clearRecursiveLayerIds() { m_recursiveLayerComponents.clear(); } |
130 | |
131 | template<class Backend> |
132 | Qt3DCore::QHandle<Backend> componentHandle() const |
133 | { |
134 | return Qt3DCore::QHandle<Backend>(); |
135 | } |
136 | |
137 | template<class Backend> |
138 | QVector<Qt3DCore::QHandle<Backend> > componentsHandle() const |
139 | { |
140 | return QVector<Qt3DCore::QHandle<Backend> >(); |
141 | } |
142 | |
143 | template<class Backend> |
144 | Backend *renderComponent() const |
145 | { |
146 | return nullptr; |
147 | } |
148 | |
149 | template<class Backend> |
150 | QVector<Backend *> renderComponents() const |
151 | { |
152 | return QVector<Backend *>(); |
153 | } |
154 | |
155 | template<class Backend> |
156 | Qt3DCore::QNodeId componentUuid() const |
157 | { |
158 | return Qt3DCore::QNodeId(); |
159 | } |
160 | |
161 | template<class Backend> |
162 | QVector<Qt3DCore::QNodeId> componentsUuid() const |
163 | { |
164 | return QVector<Qt3DCore::QNodeId>(); |
165 | } |
166 | |
167 | template<typename T> |
168 | bool containsComponentsOfType() const |
169 | { |
170 | return !componentUuid<T>().isNull(); |
171 | } |
172 | |
173 | template<typename T, typename Ts, typename ... Ts2> |
174 | bool containsComponentsOfType() const |
175 | { |
176 | return containsComponentsOfType<T>() && containsComponentsOfType<Ts, Ts2...>(); |
177 | } |
178 | |
179 | protected: |
180 | Q_DECLARE_PRIVATE(Entity) |
181 | |
182 | private: |
183 | NodeManagers *m_nodeManagers; |
184 | HEntity m_handle; |
185 | HEntity m_parentHandle; |
186 | QVector<HEntity > m_childrenHandles; |
187 | |
188 | HMatrix m_worldTransform; |
189 | QSharedPointer<Sphere> m_localBoundingVolume; |
190 | QSharedPointer<Sphere> m_worldBoundingVolume; |
191 | QSharedPointer<Sphere> m_worldBoundingVolumeWithChildren; |
192 | |
193 | // Handles to Components |
194 | Qt3DCore::QNodeId m_transformComponent; |
195 | Qt3DCore::QNodeId m_materialComponent; |
196 | Qt3DCore::QNodeId m_cameraComponent; |
197 | QVector<Qt3DCore::QNodeId> m_layerComponents; |
198 | QVector<Qt3DCore::QNodeId> m_levelOfDetailComponents; |
199 | QVector<Qt3DCore::QNodeId> m_rayCasterComponents; |
200 | QVector<Qt3DCore::QNodeId> m_shaderDataComponents; |
201 | QVector<Qt3DCore::QNodeId> m_lightComponents; |
202 | QVector<Qt3DCore::QNodeId> m_environmentLightComponents; |
203 | Qt3DCore::QNodeId m_geometryRendererComponent; |
204 | Qt3DCore::QNodeId m_objectPickerComponent; |
205 | Qt3DCore::QNodeId m_boundingVolumeDebugComponent; |
206 | Qt3DCore::QNodeId m_computeComponent; |
207 | Qt3DCore::QNodeId m_armatureComponent; |
208 | |
209 | // Includes recursive layers |
210 | Qt3DCore::QNodeIdVector m_recursiveLayerComponents; |
211 | |
212 | QString m_objectName; |
213 | bool m_boundingDirty; |
214 | // true only if this and all parent nodes are enabled |
215 | bool m_treeEnabled; |
216 | }; |
217 | |
218 | #define ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Type, Handle) \ |
219 | /* Handle */ \ |
220 | template<> \ |
221 | Q_3DRENDERSHARED_PRIVATE_EXPORT Handle Entity::componentHandle<Type>() const; \ |
222 | /* Component */ \ |
223 | template<> \ |
224 | Q_3DRENDERSHARED_PRIVATE_EXPORT Type *Entity::renderComponent<Type>() const; \ |
225 | /* Uuid */ \ |
226 | template<> \ |
227 | Q_3DRENDERSHARED_PRIVATE_EXPORT Qt3DCore::QNodeId Entity::componentUuid<Type>() const; |
228 | |
229 | |
230 | #define ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Type, Handle) \ |
231 | /* Handle */ \ |
232 | template<> \ |
233 | Q_3DRENDERSHARED_PRIVATE_EXPORT QVector<Handle> Entity::componentsHandle<Type>() const; \ |
234 | /* Component */ \ |
235 | template<> \ |
236 | Q_3DRENDERSHARED_PRIVATE_EXPORT QVector<Type *> Entity::renderComponents<Type>() const; \ |
237 | /* Uuid */ \ |
238 | template<> \ |
239 | Q_3DRENDERSHARED_PRIVATE_EXPORT Qt3DCore::QNodeIdVector Entity::componentsUuid<Type>() const; |
240 | |
241 | #define ENTITY_COMPONENT_TEMPLATE_IMPL(Type, Handle, Manager, variable) \ |
242 | /* Handle */ \ |
243 | template<> \ |
244 | Handle Entity::componentHandle<Type>() const \ |
245 | { \ |
246 | return m_nodeManagers->lookupHandle<Type, Manager, Handle>(variable); \ |
247 | } \ |
248 | /* Component */ \ |
249 | template<> \ |
250 | Type *Entity::renderComponent<Type>() const \ |
251 | { \ |
252 | return m_nodeManagers->lookupResource<Type, Manager>(variable); \ |
253 | } \ |
254 | /* Uuid */ \ |
255 | template<> \ |
256 | Qt3DCore::QNodeId Entity::componentUuid<Type>() const \ |
257 | { \ |
258 | return variable; \ |
259 | } |
260 | |
261 | #define ENTITY_COMPONENT_LIST_TEMPLATE_IMPL(Type, Handle, Manager, variable) \ |
262 | /* Handle */ \ |
263 | template<> \ |
264 | QVector<Handle> Entity::componentsHandle<Type>() const \ |
265 | { \ |
266 | Manager *manager = m_nodeManagers->manager<Type, Manager>(); \ |
267 | QVector<Handle> entries; \ |
268 | entries.reserve(variable.size()); \ |
269 | for (const QNodeId id : variable) \ |
270 | entries.push_back(manager->lookupHandle(id)); \ |
271 | return entries; \ |
272 | } \ |
273 | /* Component */ \ |
274 | template<> \ |
275 | QVector<Type *> Entity::renderComponents<Type>() const \ |
276 | { \ |
277 | Manager *manager = m_nodeManagers->manager<Type, Manager>(); \ |
278 | QVector<Type *> entries; \ |
279 | entries.reserve(variable.size()); \ |
280 | for (const QNodeId id : variable) \ |
281 | entries.push_back(manager->lookupResource(id)); \ |
282 | return entries; \ |
283 | } \ |
284 | /* Uuid */ \ |
285 | template<> \ |
286 | Qt3DCore::QNodeIdVector Entity::componentsUuid<Type>() const \ |
287 | { \ |
288 | return variable; \ |
289 | } |
290 | |
291 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Material, HMaterial) |
292 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(CameraLens, HCamera) |
293 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Transform, HTransform) |
294 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(GeometryRenderer, HGeometryRenderer) |
295 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(ObjectPicker, HObjectPicker) |
296 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(ComputeCommand, HComputeCommand) |
297 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Armature, HArmature) |
298 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Layer, HLayer) |
299 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(LevelOfDetail, HLevelOfDetail) |
300 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(RayCaster, HRayCaster) |
301 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(ShaderData, HShaderData) |
302 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Light, HLight) |
303 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(EnvironmentLight, HEnvironmentLight) |
304 | |
305 | class Q_AUTOTEST_EXPORT RenderEntityFunctor : public Qt3DCore::QBackendNodeMapper |
306 | { |
307 | public: |
308 | explicit RenderEntityFunctor(AbstractRenderer *renderer, NodeManagers *manager); |
309 | Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const override; |
310 | Qt3DCore::QBackendNode *get(Qt3DCore::QNodeId id) const override; |
311 | void destroy(Qt3DCore::QNodeId id) const override; |
312 | |
313 | private: |
314 | NodeManagers *m_nodeManagers; |
315 | AbstractRenderer *m_renderer; |
316 | }; |
317 | |
318 | } // namespace Render |
319 | } // namespace Qt3DRender |
320 | |
321 | QT_END_NAMESPACE |
322 | |
323 | #endif // QT3DRENDER_RENDER_ENTITY_H |
324 | |