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 bool isParentLessTransform() const { return m_parentLessTransform; }
77 void setParentLessTransform(bool v) { m_parentLessTransform = v; }
78 Sphere *localBoundingVolume() const { return m_localBoundingVolume.data(); }
79 Sphere *worldBoundingVolume() const { return m_worldBoundingVolume.data(); }
80 Sphere *worldBoundingVolumeWithChildren() const { return m_worldBoundingVolumeWithChildren.data(); }
81
82 void addComponent(Qt3DCore::QNodeIdTypePair idAndType);
83 void removeComponent(Qt3DCore::QNodeId nodeId);
84
85 bool isBoundingVolumeDirty() const;
86 void unsetBoundingVolumeDirty();
87
88 void setTreeEnabled(bool enabled) { m_treeEnabled = enabled; }
89 bool isTreeEnabled() const { return m_treeEnabled; }
90
91 Qt3DCore::QNodeIdVector layerIds() const { return m_layerComponents + m_recursiveLayerComponents; }
92 void addRecursiveLayerId(const Qt3DCore::QNodeId layerId);
93 void removeRecursiveLayerId(const Qt3DCore::QNodeId layerId);
94 void clearRecursiveLayerIds() { m_recursiveLayerComponents.clear(); }
95
96 template<class Backend>
97 Qt3DCore::QHandle<Backend> componentHandle() const
98 {
99 return Qt3DCore::QHandle<Backend>();
100 }
101
102 template<class Backend>
103 QList<Qt3DCore::QHandle<Backend>> componentsHandle() const
104 {
105 return { };
106 }
107
108 template<class Backend>
109 Backend *renderComponent() const
110 {
111 return nullptr;
112 }
113
114 template<class Backend>
115 std::vector<Backend *> renderComponents() const
116 {
117 // We should never reach this, we expect specialization to have been
118 // specified
119 Q_UNREACHABLE_RETURN({});
120 }
121
122 template<class Backend>
123 Qt3DCore::QNodeId componentUuid() const
124 {
125 return { };
126 }
127
128 template<class Backend>
129 QList<Qt3DCore::QNodeId> componentsUuid() const
130 {
131 return { };
132 }
133
134 template<typename T>
135 bool containsComponentsOfType() const
136 {
137 return !componentUuid<T>().isNull();
138 }
139
140 template<typename T, typename Ts, typename ... Ts2>
141 bool containsComponentsOfType() const
142 {
143 return containsComponentsOfType<T>() && containsComponentsOfType<Ts, Ts2...>();
144 }
145
146protected:
147 Q_DECLARE_PRIVATE(Entity)
148
149private:
150 NodeManagers *m_nodeManagers;
151 HEntity m_handle;
152 HEntity m_parentHandle;
153 QList<HEntity> m_childrenHandles;
154
155 HMatrix m_worldTransform;
156 bool m_parentLessTransform;
157 QSharedPointer<Sphere> m_localBoundingVolume;
158 QSharedPointer<Sphere> m_worldBoundingVolume;
159 QSharedPointer<Sphere> m_worldBoundingVolumeWithChildren;
160
161 // Handles to Components
162 Qt3DCore::QNodeId m_transformComponent;
163 Qt3DCore::QNodeId m_materialComponent;
164 Qt3DCore::QNodeId m_cameraComponent;
165 QList<Qt3DCore::QNodeId> m_layerComponents;
166 QList<Qt3DCore::QNodeId> m_levelOfDetailComponents;
167 QList<Qt3DCore::QNodeId> m_rayCasterComponents;
168 QList<Qt3DCore::QNodeId> m_shaderDataComponents;
169 QList<Qt3DCore::QNodeId> m_lightComponents;
170 QList<Qt3DCore::QNodeId> m_environmentLightComponents;
171 Qt3DCore::QNodeId m_geometryRendererComponent;
172 Qt3DCore::QNodeId m_pickingProxyComponent;
173 Qt3DCore::QNodeId m_objectPickerComponent;
174 Qt3DCore::QNodeId m_boundingVolumeDebugComponent;
175 Qt3DCore::QNodeId m_computeComponent;
176 Qt3DCore::QNodeId m_armatureComponent;
177
178 // Includes recursive layers
179 Qt3DCore::QNodeIdVector m_recursiveLayerComponents;
180
181 QString m_objectName;
182 bool m_boundingDirty;
183 // true only if this and all parent nodes are enabled
184 bool m_treeEnabled;
185};
186
187#define ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Type, Handle) \
188 /* Handle */ \
189 template<> \
190 Q_3DRENDERSHARED_PRIVATE_EXPORT Handle Entity::componentHandle<Type>() const; \
191 /* Component */ \
192 template<> \
193 Q_3DRENDERSHARED_PRIVATE_EXPORT Type *Entity::renderComponent<Type>() const; \
194 /* Uuid */ \
195 template<> \
196 Q_3DRENDERSHARED_PRIVATE_EXPORT Qt3DCore::QNodeId Entity::componentUuid<Type>() const;
197
198
199#define ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Type, Handle) \
200 /* Handle */ \
201 template<> \
202 Q_3DRENDERSHARED_PRIVATE_EXPORT QList<Handle> Entity::componentsHandle<Type>() const; \
203 /* Component */ \
204 template<> \
205 Q_3DRENDERSHARED_PRIVATE_EXPORT std::vector<Type *> Entity::renderComponents<Type>() const; \
206 /* Uuid */ \
207 template<> \
208 Q_3DRENDERSHARED_PRIVATE_EXPORT Qt3DCore::QNodeIdVector Entity::componentsUuid<Type>() const;
209
210#define ENTITY_COMPONENT_TEMPLATE_IMPL(Type, Handle, Manager, variable) \
211 /* Handle */ \
212 template<> \
213 Handle Entity::componentHandle<Type>() const \
214 { \
215 return m_nodeManagers->lookupHandle<Type, Manager, Handle>(variable); \
216 } \
217 /* Component */ \
218 template<> \
219 Type *Entity::renderComponent<Type>() const \
220 { \
221 return m_nodeManagers->lookupResource<Type, Manager>(variable); \
222 } \
223 /* Uuid */ \
224 template<> \
225 Qt3DCore::QNodeId Entity::componentUuid<Type>() const \
226 { \
227 return variable; \
228 }
229
230#define ENTITY_COMPONENT_LIST_TEMPLATE_IMPL(Type, Handle, Manager, variable) \
231 /* Handle */ \
232 template<> \
233 QList<Handle> Entity::componentsHandle<Type>() const \
234 { \
235 Manager *manager = m_nodeManagers->manager<Type, Manager>(); \
236 QList<Handle> entries; \
237 entries.reserve(variable.size()); \
238 for (const QNodeId &id : variable) \
239 entries.push_back(manager->lookupHandle(id)); \
240 return entries; \
241 } \
242 /* Component */ \
243 template<> \
244 std::vector<Type *> Entity::renderComponents<Type>() const \
245 { \
246 Manager *manager = m_nodeManagers->manager<Type, Manager>(); \
247 std::vector<Type *> entries; \
248 entries.reserve(variable.size()); \
249 for (const QNodeId &id : variable) \
250 entries.push_back(manager->lookupResource(id)); \
251 return entries; \
252 } \
253 /* Uuid */ \
254 template<> \
255 Qt3DCore::QNodeIdVector Entity::componentsUuid<Type>() const \
256 { \
257 return variable; \
258 }
259
260ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Material, HMaterial)
261ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(CameraLens, HCamera)
262ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Transform, HTransform)
263ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(GeometryRenderer, HGeometryRenderer)
264ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(ObjectPicker, HObjectPicker)
265ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(PickingProxy, HPickingProxy)
266ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(ComputeCommand, HComputeCommand)
267ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Armature, HArmature)
268ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Layer, HLayer)
269ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(LevelOfDetail, HLevelOfDetail)
270ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(RayCaster, HRayCaster)
271ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(ShaderData, HShaderData)
272ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Light, HLight)
273ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(EnvironmentLight, HEnvironmentLight)
274
275class Q_AUTOTEST_EXPORT RenderEntityFunctor : public Qt3DCore::QBackendNodeMapper
276{
277public:
278 explicit RenderEntityFunctor(AbstractRenderer *renderer, NodeManagers *manager);
279 Qt3DCore::QBackendNode *create(Qt3DCore::QNodeId id) const override;
280 Qt3DCore::QBackendNode *get(Qt3DCore::QNodeId id) const override;
281 void destroy(Qt3DCore::QNodeId id) const override;
282
283private:
284 NodeManagers *m_nodeManagers;
285 AbstractRenderer *m_renderer;
286};
287
288} // namespace Render
289} // namespace Qt3DRender
290
291QT_END_NAMESPACE
292
293#endif // QT3DRENDER_RENDER_ENTITY_H
294

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