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 | 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 | |
146 | protected: |
147 | Q_DECLARE_PRIVATE(Entity) |
148 | |
149 | private: |
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 | |
260 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Material, HMaterial) |
261 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(CameraLens, HCamera) |
262 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Transform, HTransform) |
263 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(GeometryRenderer, HGeometryRenderer) |
264 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(ObjectPicker, HObjectPicker) |
265 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(PickingProxy, HPickingProxy) |
266 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(ComputeCommand, HComputeCommand) |
267 | ENTITY_COMPONENT_TEMPLATE_SPECIALIZATION(Armature, HArmature) |
268 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Layer, HLayer) |
269 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(LevelOfDetail, HLevelOfDetail) |
270 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(RayCaster, HRayCaster) |
271 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(ShaderData, HShaderData) |
272 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Light, HLight) |
273 | ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(EnvironmentLight, HEnvironmentLight) |
274 | |
275 | class Q_AUTOTEST_EXPORT RenderEntityFunctor : public Qt3DCore::QBackendNodeMapper |
276 | { |
277 | public: |
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 | |
283 | private: |
284 | NodeManagers *m_nodeManagers; |
285 | AbstractRenderer *m_renderer; |
286 | }; |
287 | |
288 | } // namespace Render |
289 | } // namespace Qt3DRender |
290 | |
291 | QT_END_NAMESPACE |
292 | |
293 | #endif // QT3DRENDER_RENDER_ENTITY_H |
294 | |