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 | |
26 | QT_BEGIN_NAMESPACE |
27 | |
28 | class QMatrix4x4; |
29 | |
30 | namespace Qt3DCore { |
31 | class QNode; |
32 | class QEntity; |
33 | class QComponent; |
34 | } |
35 | |
36 | namespace Qt3DRender { |
37 | |
38 | class QRenderAspect; |
39 | |
40 | namespace Render { |
41 | |
42 | class Sphere; |
43 | class Renderer; |
44 | class NodeManagers; |
45 | class EntityPrivate; |
46 | |
47 | class Q_3DRENDERSHARED_PRIVATE_EXPORT Entity : public BackendNode |
48 | { |
49 | public: |
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 | |
144 | protected: |
145 | Q_DECLARE_PRIVATE(Entity) |
146 | |
147 | private: |
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 | |
257 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Material, HMaterial) |
258 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(CameraLens, HCamera) |
259 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Transform, HTransform) |
260 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(GeometryRenderer, HGeometryRenderer) |
261 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(ObjectPicker, HObjectPicker) |
262 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(PickingProxy, HPickingProxy) |
263 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(ComputeCommand, HComputeCommand) |
264 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Armature, HArmature) |
265 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Layer, HLayer) |
266 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(LevelOfDetail, HLevelOfDetail) |
267 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(RayCaster, HRayCaster) |
268 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(ShaderData, HShaderData) |
269 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Light, HLight) |
270 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(EnvironmentLight, HEnvironmentLight) |
271 | |
272 | class Q_AUTOTEST_EXPORT RenderEntityFunctor : public Qt3DCore::QBackendNodeMapper |
273 | { |
274 | public: |
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 | |
280 | private: |
281 | NodeManagers *m_nodeManagers; |
282 | AbstractRenderer *m_renderer; |
283 | }; |
284 | |
285 | } // namespace Render |
286 | } // namespace Qt3DRender |
287 | |
288 | QT_END_NAMESPACE |
289 | |
290 | #endif // QT3DRENDER_RENDER_ENTITY_H |
291 | |