1// Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
2// Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QT3DRENDER_RENDER_ENTITY_H
6#define QT3DRENDER_RENDER_ENTITY_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 for the convenience
13// of other Qt classes. 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 <Qt3DRender/private/backendnode_p.h>
20#include <Qt3DRender/private/abstractrenderer_p.h>
21#include <Qt3DRender/private/handle_types_p.h>
22#include <Qt3DCore/private/qentity_p.h>
23#include <Qt3DCore/private/qhandle_p.h>
24#include <QList>
25
26QT_BEGIN_NAMESPACE
27
28class QMatrix4x4;
29
30namespace Qt3DCore {
31class QNode;
32class QEntity;
33class QComponent;
34}
35
36namespace Qt3DRender {
37
38class QRenderAspect;
39
40namespace Render {
41
42class Sphere;
43class Renderer;
44class NodeManagers;
45class EntityPrivate;
46
47class Q_3DRENDERSHARED_PRIVATE_EXPORT Entity : public BackendNode
48{
49public:
50 Entity();
51 ~Entity();
52 void cleanup();
53
54 void setParentHandle(HEntity parentHandle);
55 void setNodeManagers(NodeManagers *manager);
56 void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
57
58 void dump() const;
59
60 void setHandle(HEntity handle);
61 HEntity handle() const { return m_handle; }
62 Entity *parent() const;
63 HEntity parentHandle() const { return m_parentHandle; }
64
65 void removeFromParentChildHandles();
66 void appendChildHandle(HEntity childHandle);
67 void removeChildHandle(HEntity childHandle) { m_childrenHandles.removeOne(t: childHandle); }
68 const QList<HEntity> &childrenHandles() const { return m_childrenHandles; }
69 QList<Entity *> children() const;
70 bool hasChildren() const { return !m_childrenHandles.empty(); }
71 void traverse(const std::function<void(Entity *)> &operation);
72 void traverse(const std::function<void(const Entity *)> &operation) const;
73
74 Matrix4x4 *worldTransform();
75 const Matrix4x4 *worldTransform() const;
76 Sphere *localBoundingVolume() const { return m_localBoundingVolume.data(); }
77 Sphere *worldBoundingVolume() const { return m_worldBoundingVolume.data(); }
78 Sphere *worldBoundingVolumeWithChildren() const { return m_worldBoundingVolumeWithChildren.data(); }
79
80 void addComponent(Qt3DCore::QNodeIdTypePair idAndType);
81 void removeComponent(Qt3DCore::QNodeId nodeId);
82
83 bool isBoundingVolumeDirty() const;
84 void unsetBoundingVolumeDirty();
85
86 void setTreeEnabled(bool enabled) { m_treeEnabled = enabled; }
87 bool isTreeEnabled() const { return m_treeEnabled; }
88
89 Qt3DCore::QNodeIdVector layerIds() const { return m_layerComponents + m_recursiveLayerComponents; }
90 void addRecursiveLayerId(const Qt3DCore::QNodeId layerId);
91 void removeRecursiveLayerId(const Qt3DCore::QNodeId layerId);
92 void clearRecursiveLayerIds() { m_recursiveLayerComponents.clear(); }
93
94 template<class Backend>
95 Qt3DCore::QHandle<Backend> componentHandle() const
96 {
97 return Qt3DCore::QHandle<Backend>();
98 }
99
100 template<class Backend>
101 QList<Qt3DCore::QHandle<Backend>> componentsHandle() const
102 {
103 return { };
104 }
105
106 template<class Backend>
107 Backend *renderComponent() const
108 {
109 return nullptr;
110 }
111
112 template<class Backend>
113 std::vector<Backend *> renderComponents() const
114 {
115 // We should never reach this, we expect specialization to have been
116 // specified
117 Q_UNREACHABLE_RETURN({});
118 }
119
120 template<class Backend>
121 Qt3DCore::QNodeId componentUuid() const
122 {
123 return { };
124 }
125
126 template<class Backend>
127 QList<Qt3DCore::QNodeId> componentsUuid() const
128 {
129 return { };
130 }
131
132 template<typename T>
133 bool containsComponentsOfType() const
134 {
135 return !componentUuid<T>().isNull();
136 }
137
138 template<typename T, typename Ts, typename ... Ts2>
139 bool containsComponentsOfType() const
140 {
141 return containsComponentsOfType<T>() && containsComponentsOfType<Ts, Ts2...>();
142 }
143
144protected:
145 Q_DECLARE_PRIVATE(Entity)
146
147private:
148 NodeManagers *m_nodeManagers;
149 HEntity m_handle;
150 HEntity m_parentHandle;
151 QList<HEntity> m_childrenHandles;
152
153 HMatrix m_worldTransform;
154 QSharedPointer<Sphere> m_localBoundingVolume;
155 QSharedPointer<Sphere> m_worldBoundingVolume;
156 QSharedPointer<Sphere> m_worldBoundingVolumeWithChildren;
157
158 // Handles to Components
159 Qt3DCore::QNodeId m_transformComponent;
160 Qt3DCore::QNodeId m_materialComponent;
161 Qt3DCore::QNodeId m_cameraComponent;
162 QList<Qt3DCore::QNodeId> m_layerComponents;
163 QList<Qt3DCore::QNodeId> m_levelOfDetailComponents;
164 QList<Qt3DCore::QNodeId> m_rayCasterComponents;
165 QList<Qt3DCore::QNodeId> m_shaderDataComponents;
166 QList<Qt3DCore::QNodeId> m_lightComponents;
167 QList<Qt3DCore::QNodeId> m_environmentLightComponents;
168 Qt3DCore::QNodeId m_geometryRendererComponent;
169 Qt3DCore::QNodeId m_pickingProxyComponent;
170 Qt3DCore::QNodeId m_objectPickerComponent;
171 Qt3DCore::QNodeId m_boundingVolumeDebugComponent;
172 Qt3DCore::QNodeId m_computeComponent;
173 Qt3DCore::QNodeId m_armatureComponent;
174
175 // Includes recursive layers
176 Qt3DCore::QNodeIdVector m_recursiveLayerComponents;
177
178 QString m_objectName;
179 bool m_boundingDirty;
180 // true only if this and all parent nodes are enabled
181 bool m_treeEnabled;
182};
183
184#define ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Type, Handle) \
185 /* Handle */ \
186 template<> \
187 Q_3DRENDERSHARED_PRIVATE_EXPORT Handle Entity::componentHandle<Type>() const; \
188 /* Component */ \
189 template<> \
190 Q_3DRENDERSHARED_PRIVATE_EXPORT Type *Entity::renderComponent<Type>() const; \
191 /* Uuid */ \
192 template<> \
193 Q_3DRENDERSHARED_PRIVATE_EXPORT Qt3DCore::QNodeId Entity::componentUuid<Type>() const;
194
195
196#define ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Type, Handle) \
197 /* Handle */ \
198 template<> \
199 Q_3DRENDERSHARED_PRIVATE_EXPORT QList<Handle> Entity::componentsHandle<Type>() const; \
200 /* Component */ \
201 template<> \
202 Q_3DRENDERSHARED_PRIVATE_EXPORT std::vector<Type *> Entity::renderComponents<Type>() const; \
203 /* Uuid */ \
204 template<> \
205 Q_3DRENDERSHARED_PRIVATE_EXPORT Qt3DCore::QNodeIdVector Entity::componentsUuid<Type>() const;
206
207#define ENTITY_COMPONENT_TEMPLATE_IMPL(Type, Handle, Manager, variable) \
208 /* Handle */ \
209 template<> \
210 Handle Entity::componentHandle<Type>() const \
211 { \
212 return m_nodeManagers->lookupHandle<Type, Manager, Handle>(variable); \
213 } \
214 /* Component */ \
215 template<> \
216 Type *Entity::renderComponent<Type>() const \
217 { \
218 return m_nodeManagers->lookupResource<Type, Manager>(variable); \
219 } \
220 /* Uuid */ \
221 template<> \
222 Qt3DCore::QNodeId Entity::componentUuid<Type>() const \
223 { \
224 return variable; \
225 }
226
227#define ENTITY_COMPONENT_LIST_TEMPLATE_IMPL(Type, Handle, Manager, variable) \
228 /* Handle */ \
229 template<> \
230 QList<Handle> Entity::componentsHandle<Type>() const \
231 { \
232 Manager *manager = m_nodeManagers->manager<Type, Manager>(); \
233 QList<Handle> entries; \
234 entries.reserve(variable.size()); \
235 for (const QNodeId &id : variable) \
236 entries.push_back(manager->lookupHandle(id)); \
237 return entries; \
238 } \
239 /* Component */ \
240 template<> \
241 std::vector<Type *> Entity::renderComponents<Type>() const \
242 { \
243 Manager *manager = m_nodeManagers->manager<Type, Manager>(); \
244 std::vector<Type *> entries; \
245 entries.reserve(variable.size()); \
246 for (const QNodeId &id : variable) \
247 entries.push_back(manager->lookupResource(id)); \
248 return entries; \
249 } \
250 /* Uuid */ \
251 template<> \
252 Qt3DCore::QNodeIdVector Entity::componentsUuid<Type>() const \
253 { \
254 return variable; \
255 }
256
257ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Material, HMaterial)
258ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(CameraLens, HCamera)
259ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Transform, HTransform)
260ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(GeometryRenderer, HGeometryRenderer)
261ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(ObjectPicker, HObjectPicker)
262ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(PickingProxy, HPickingProxy)
263ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(ComputeCommand, HComputeCommand)
264ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Armature, HArmature)
265ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Layer, HLayer)
266ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(LevelOfDetail, HLevelOfDetail)
267ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(RayCaster, HRayCaster)
268ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(ShaderData, HShaderData)
269ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Light, HLight)
270ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(EnvironmentLight, HEnvironmentLight)
271
272class Q_AUTOTEST_EXPORT RenderEntityFunctor : public Qt3DCore::QBackendNodeMapper
273{
274public:
275 explicit RenderEntityFunctor(AbstractRenderer *renderer, NodeManagers *manager);
276 Qt3DCore::QBackendNode *create(Qt3DCore::QNodeId id) const override;
277 Qt3DCore::QBackendNode *get(Qt3DCore::QNodeId id) const override;
278 void destroy(Qt3DCore::QNodeId id) const override;
279
280private:
281 NodeManagers *m_nodeManagers;
282 AbstractRenderer *m_renderer;
283};
284
285} // namespace Render
286} // namespace Qt3DRender
287
288QT_END_NAMESPACE
289
290#endif // QT3DRENDER_RENDER_ENTITY_H
291

source code of qt3d/src/render/backend/entity_p.h