Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquick3dresourceloader.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4
6#include "qquick3dmodel_p.h"
7#include <QtQuick3DRuntimeRender/private/qssgrenderresourceloader_p.h>
8
10
71
72const QList<QUrl> &QQuick3DResourceLoader::meshSources() const
73{
74 return m_meshSources;
75}
76
77void QQuick3DResourceLoader::setMeshSources(const QList<QUrl> &newMeshSources)
78{
79 if (m_meshSources == newMeshSources)
80 return;
81 m_meshSources = newMeshSources;
83 markDirty(QQuick3DResourceLoader::MeshesDirty);
84}
85
86
87QQmlListProperty<QQuick3DGeometry> QQuick3DResourceLoader::geometries()
88{
89 return QQmlListProperty<QQuick3DGeometry>(this,
90 nullptr,
91 QQuick3DResourceLoader::qmlAppendGeometry,
92 QQuick3DResourceLoader::qmlGeometriesCount,
93 QQuick3DResourceLoader::qmlGeometryAt,
94 QQuick3DResourceLoader::qmlClearGeometries);
95}
96
97QQmlListProperty<QQuick3DTexture> QQuick3DResourceLoader::textures()
98{
99 return QQmlListProperty<QQuick3DTexture>(this,
100 nullptr,
101 QQuick3DResourceLoader::qmlAppendTexture,
102 QQuick3DResourceLoader::qmlTexturesCount,
103 QQuick3DResourceLoader::qmlTextureAt,
104 QQuick3DResourceLoader::qmlClearTextures);
105}
106
107void QQuick3DResourceLoader::onGeometryDestroyed(QObject *object)
108{
109 bool found = false;
110 for (int i = 0; i < m_geometries.size(); ++i) {
111 if (m_geometries[i] == object) {
112 m_geometries.removeAt(i--);
113 found = true;
114 }
115 }
116 if (found)
117 markDirty(QQuick3DResourceLoader::GeometriesDirty);
118}
119
120void QQuick3DResourceLoader::onTextureDestroyed(QObject *object)
121{
122 bool found = false;
123 for (int i = 0; i < m_textures.size(); ++i) {
124 if (m_textures[i] == object) {
125 m_textures.removeAt(i--);
126 found = true;
127 }
128 }
129 if (found)
130 markDirty(QQuick3DResourceLoader::TexturesDirty);
131}
132
134{
135 if (!node) {
136 markAllDirty();
137 node = new QSSGRenderResourceLoader();
138 }
140 int dirtyAttribute = 0;
141
142 auto resourceLoaderNode = static_cast<QSSGRenderResourceLoader *>(node);
143 if (m_dirtyAttributes & MeshesDirty) {
144 resourceLoaderNode->meshes.clear();
145 for (const auto &mesh : std::as_const(m_meshSources))
146 resourceLoaderNode->meshes.push_back(QSSGRenderPath(QQuick3DModel::translateMeshSource(mesh, this)));
147 }
148
149 if (m_dirtyAttributes & TexturesDirty) {
150 resourceLoaderNode->textures.clear();
151 for (const auto &texture : std::as_const(m_textures)) {
152 auto graphObject = QQuick3DObjectPrivate::get(texture)->spatialNode;
153 if (graphObject)
154 resourceLoaderNode->textures.push_back(graphObject);
155 else
156 dirtyAttribute |= TexturesDirty;
157 }
158 }
159
160 if (m_dirtyAttributes & GeometriesDirty) {
161 resourceLoaderNode->geometries.clear();
162 for (const auto &geometry : std::as_const(m_geometries)) {
163 auto graphObject = QQuick3DObjectPrivate::get(geometry)->spatialNode;
164 if (graphObject)
165 resourceLoaderNode->geometries.push_back(graphObject);
166 else
167 dirtyAttribute |= GeometriesDirty;
168 }
169 }
170
171 m_dirtyAttributes = dirtyAttribute;
172 return resourceLoaderNode;
173
174}
175
177{
178 m_dirtyAttributes = 0xffffffff;
180}
181
182void QQuick3DResourceLoader::itemChange(ItemChange change, const ItemChangeData &value)
183{
184 if (change == QQuick3DObject::ItemSceneChange)
185 updateSceneManager(value.sceneManager);
186}
187
188void QQuick3DResourceLoader::qmlAppendGeometry(QQmlListProperty<QQuick3DGeometry> *list, QQuick3DGeometry *geometry)
189{
190 if (geometry == nullptr)
191 return;
192 QQuick3DResourceLoader *self = static_cast<QQuick3DResourceLoader *>(list->object);
193 self->m_geometries.push_back(geometry);
194
195 self->markDirty(QQuick3DResourceLoader::GeometriesDirty);
196
197 if (geometry->parentItem() == nullptr) {
198 // If the material has no parent, check if it has a hierarchical parent that's a QQuick3DObject
199 // and re-parent it to that, e.g., inline materials
200 QQuick3DObject *parentItem = qobject_cast<QQuick3DObject *>(geometry->parent());
201 if (parentItem) {
202 geometry->setParentItem(parentItem);
203 } else { // If no valid parent was found, make sure the material refs our scene manager
204 const auto &sceneManager = QQuick3DObjectPrivate::get(self)->sceneManager;
205 if (sceneManager) {
206 QQuick3DObjectPrivate::get(geometry)->refSceneManager(*sceneManager);
207 }
208 }
209 }
210
211 // Make sure geometries are removed when destroyed
212 connect(geometry, &QQuick3DGeometry::destroyed, self, &QQuick3DResourceLoader::onGeometryDestroyed);
213}
214
215QQuick3DGeometry *QQuick3DResourceLoader::qmlGeometryAt(QQmlListProperty<QQuick3DGeometry> *list, qsizetype index)
216{
217 QQuick3DResourceLoader *self = static_cast<QQuick3DResourceLoader *>(list->object);
218
219 if (index >= self->m_geometries.size()) {
220 qWarning("The index exceeds the range of valid geometries.");
221 return nullptr;
222 }
223
224 return self->m_geometries.at(index);
225}
226
227qsizetype QQuick3DResourceLoader::qmlGeometriesCount(QQmlListProperty<QQuick3DGeometry> *list)
228{
229 QQuick3DResourceLoader *self = static_cast<QQuick3DResourceLoader *>(list->object);
230 return self->m_geometries.size();
231}
232
233void QQuick3DResourceLoader::qmlClearGeometries(QQmlListProperty<QQuick3DGeometry> *list)
234{
235 QQuick3DResourceLoader *self = static_cast<QQuick3DResourceLoader *>(list->object);
236 for (const auto &geometry : std::as_const(self->m_geometries)) {
237 if (geometry->parentItem() == nullptr)
238 QQuick3DObjectPrivate::get(geometry)->derefSceneManager();
239 geometry->disconnect(self, SLOT(onMorphTargetDestroyed(QObject*)));
240 }
241
242 self->m_geometries.clear();
243 self->markDirty(QQuick3DResourceLoader::GeometriesDirty);
244}
245
246void QQuick3DResourceLoader::qmlAppendTexture(QQmlListProperty<QQuick3DTexture> *list, QQuick3DTexture *texture)
247{
248 if (texture == nullptr)
249 return;
250 QQuick3DResourceLoader *self = static_cast<QQuick3DResourceLoader *>(list->object);
251 self->m_textures.push_back(texture);
252
253 self->markDirty(QQuick3DResourceLoader::TexturesDirty);
254
255 if (texture->parentItem() == nullptr) {
256 // If the material has no parent, check if it has a hierarchical parent that's a QQuick3DObject
257 // and re-parent it to that, e.g., inline materials
258 QQuick3DObject *parentItem = qobject_cast<QQuick3DObject *>(texture->parent());
259 if (parentItem) {
260 texture->setParentItem(parentItem);
261 } else { // If no valid parent was found, make sure the material refs our scene manager
262 const auto &sceneManager = QQuick3DObjectPrivate::get(self)->sceneManager;
263 if (sceneManager) {
264 QQuick3DObjectPrivate::get(texture)->refSceneManager(*sceneManager);
265 }
266 }
267 }
268 // Make sure TextureData are removed when destroyed
269 connect(texture, &QQuick3DTextureData::destroyed, self, &QQuick3DResourceLoader::onTextureDestroyed);
270}
271
272QQuick3DTexture *QQuick3DResourceLoader::qmlTextureAt(QQmlListProperty<QQuick3DTexture> *list, qsizetype index)
273{
274 QQuick3DResourceLoader *self = static_cast<QQuick3DResourceLoader *>(list->object);
275 if (index >= self->m_textures.size()) {
276 qWarning("The index exceeds the range of valid texture data.");
277 return nullptr;
278 }
279
280 return self->m_textures.at(index);
281}
282
283qsizetype QQuick3DResourceLoader::qmlTexturesCount(QQmlListProperty<QQuick3DTexture> *list)
284{
285 QQuick3DResourceLoader *self = static_cast<QQuick3DResourceLoader *>(list->object);
286 return self->m_textures.size();
287}
288
289void QQuick3DResourceLoader::qmlClearTextures(QQmlListProperty<QQuick3DTexture> *list)
290{
291 QQuick3DResourceLoader *self = static_cast<QQuick3DResourceLoader *>(list->object);
292 for (const auto &data : std::as_const(self->m_textures)) {
293 if (data->parentItem() == nullptr)
294 QQuick3DObjectPrivate::get(data)->derefSceneManager();
295 data->disconnect(self, SLOT(onMorphTargetDestroyed(QObject*)));
296 }
297 self->m_textures.clear();
298 self->markDirty(QQuick3DResourceLoader::TexturesDirty);
299}
300
301void QQuick3DResourceLoader::markDirty(ResourceLoaderDirtyType type)
302{
303 if (!(m_dirtyAttributes & quint32(type))) {
304 m_dirtyAttributes |= quint32(type);
305 update();
306 }
307}
308
309void QQuick3DResourceLoader::updateSceneManager(QQuick3DSceneManager *sceneManager)
310{
311 if (sceneManager) {
312 for (auto &geometry : m_geometries)
313 if (!geometry->parentItem() && !QQuick3DObjectPrivate::get(geometry)->sceneManager)
314 QQuick3DObjectPrivate::refSceneManager(geometry, *sceneManager);
315 for (auto &texture : m_textures)
316 if (!texture->parentItem() && !QQuick3DObjectPrivate::get(texture)->sceneManager)
317 QQuick3DObjectPrivate::refSceneManager(texture, *sceneManager);
318 } else {
319 for (auto &geometry : m_geometries)
320 QQuick3DObjectPrivate::derefSceneManager(geometry);
321 for (auto &texture : m_textures)
322 QQuick3DObjectPrivate::derefSceneManager(texture);
323 }
324}
325
qsizetype size() const noexcept
Definition qlist.h:397
void removeAt(qsizetype i)
Definition qlist.h:590
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
\qmltype Geometry \inherits Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DGeometry
static QString translateMeshSource(const QUrl &source, QObject *contextObject)
static QQuick3DObjectPrivate * get(QQuick3DObject *item)
\qmltype Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DObject \inherits QtObject
QQuick3DObject * parent
\qmlproperty Object3D QtQuick3D::Object3D::parent This property holds the parent of the Object3D in a...
void setParentItem(QQuick3DObject *parentItem)
virtual QSSGRenderGraphObject * updateSpatialNode(QSSGRenderGraphObject *node)
virtual void markAllDirty()
QQmlListProperty< QQuick3DTexture > textures
QSSGRenderGraphObject * updateSpatialNode(QSSGRenderGraphObject *node) override
QQmlListProperty< QQuick3DGeometry > geometries
void setMeshSources(const QList< QUrl > &newMeshSources)
void itemChange(ItemChange change, const ItemChangeData &value) override
QQuick3DResourceLoader(QQuick3DObject *parent=nullptr)
\qmltype ResourceLoader \inqmlmodule QtQuick3D \inherits Object3D
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
void push_back(QChar c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.h:957
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1226
Combined button and popup list for selecting options.
QString self
Definition language.cpp:58
static QDBusError::ErrorType get(const char *name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
#define SLOT(a)
Definition qobjectdefs.h:52
GLuint index
[2]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLenum GLuint texture
#define emit
unsigned int quint32
Definition qtypes.h:50
ptrdiff_t qsizetype
Definition qtypes.h:165
QList< int > list
[14]
if(qFloatDistance(a, b)<(1<< 7))
[0]
QVector< QSSGRenderPath > meshes
Definition moc.h:23