9#include <QtQuick3DRuntimeRender/private/qssgrenderresourceloader_p.h>
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
44
45
46
47
48
49
50
51
54
55
56
57
58
59
62
63
64
65
66
67
69QQuick3DResourceLoader::QQuick3DResourceLoader(QQuick3DObject *parent)
70 : QQuick3DObject(*(
new QQuick3DObjectPrivate(QQuick3DObjectPrivate::Type::ResourceLoader)), parent)
74const QList<QUrl> &QQuick3DResourceLoader::meshSources()
const
79void QQuick3DResourceLoader::setMeshSources(
const QList<QUrl> &newMeshSources)
81 if (m_meshSources == newMeshSources)
83 m_meshSources = newMeshSources;
84 emit meshSourcesChanged();
85 markDirty(QQuick3DResourceLoader::MeshesDirty);
89QQmlListProperty<QQuick3DGeometry> QQuick3DResourceLoader::geometries()
91 return QQmlListProperty<QQuick3DGeometry>(
this,
93 QQuick3DResourceLoader::qmlAppendGeometry,
94 QQuick3DResourceLoader::qmlGeometriesCount,
95 QQuick3DResourceLoader::qmlGeometryAt,
96 QQuick3DResourceLoader::qmlClearGeometries);
99QQmlListProperty<QQuick3DTexture> QQuick3DResourceLoader::textures()
101 return QQmlListProperty<QQuick3DTexture>(
this,
103 QQuick3DResourceLoader::qmlAppendTexture,
104 QQuick3DResourceLoader::qmlTexturesCount,
105 QQuick3DResourceLoader::qmlTextureAt,
106 QQuick3DResourceLoader::qmlClearTextures);
109void QQuick3DResourceLoader::onGeometryDestroyed(QObject *object)
112 for (
int i = 0; i < m_geometries.size(); ++i) {
113 if (m_geometries[i] == object) {
114 m_geometries.removeAt(i--);
119 markDirty(QQuick3DResourceLoader::GeometriesDirty);
122void QQuick3DResourceLoader::onTextureDestroyed(QObject *object)
125 for (
int i = 0; i < m_textures.size(); ++i) {
126 if (m_textures[i] == object) {
127 m_textures.removeAt(i--);
132 markDirty(QQuick3DResourceLoader::TexturesDirty);
135QSSGRenderGraphObject *QQuick3DResourceLoader::updateSpatialNode(QSSGRenderGraphObject *node)
139 node =
new QSSGRenderResourceLoader();
141 QQuick3DObject::updateSpatialNode(node);
142 int dirtyAttribute = 0;
144 auto resourceLoaderNode =
static_cast<QSSGRenderResourceLoader *>(node);
145 if (m_dirtyAttributes & MeshesDirty) {
146 resourceLoaderNode->meshes.clear();
147 for (
const auto &mesh : std::as_const(m_meshSources))
148 resourceLoaderNode->meshes.push_back(QSSGRenderPath(QQuick3DModel::translateMeshSource(mesh,
this)));
151 if (m_dirtyAttributes & TexturesDirty) {
152 resourceLoaderNode->textures.clear();
153 for (
const auto &texture : std::as_const(m_textures)) {
154 auto graphObject = QQuick3DObjectPrivate::get(texture)->spatialNode;
156 resourceLoaderNode->textures.push_back(graphObject);
158 dirtyAttribute |= TexturesDirty;
162 if (m_dirtyAttributes & GeometriesDirty) {
163 resourceLoaderNode->geometries.clear();
164 for (
const auto &geometry : std::as_const(m_geometries)) {
165 auto graphObject = QQuick3DObjectPrivate::get(geometry)->spatialNode;
167 resourceLoaderNode->geometries.push_back(graphObject);
169 dirtyAttribute |= GeometriesDirty;
173 m_dirtyAttributes = dirtyAttribute;
174 return resourceLoaderNode;
178void QQuick3DResourceLoader::markAllDirty()
180 m_dirtyAttributes = 0xffffffff;
181 QQuick3DObject::markAllDirty();
184void QQuick3DResourceLoader::itemChange(ItemChange change,
const ItemChangeData &value)
186 if (change == QQuick3DObject::ItemSceneChange)
187 updateSceneManager(value.sceneManager);
190void QQuick3DResourceLoader::qmlAppendGeometry(QQmlListProperty<QQuick3DGeometry> *list, QQuick3DGeometry *geometry)
192 if (geometry ==
nullptr)
194 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
195 self->m_geometries.push_back(geometry);
197 self->markDirty(QQuick3DResourceLoader::GeometriesDirty);
199 if (geometry->parentItem() ==
nullptr) {
202 QQuick3DObject *parentItem = qobject_cast<QQuick3DObject *>(geometry->parent());
204 geometry->setParentItem(parentItem);
206 const auto &sceneManager = QQuick3DObjectPrivate::get(self)->sceneManager;
208 QQuick3DObjectPrivate::get(geometry)->refSceneManager(*sceneManager);
214 connect(geometry, &QQuick3DGeometry::destroyed, self, &QQuick3DResourceLoader::onGeometryDestroyed);
217QQuick3DGeometry *QQuick3DResourceLoader::qmlGeometryAt(QQmlListProperty<QQuick3DGeometry> *list, qsizetype index)
219 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
221 if (index >= self->m_geometries.size()) {
222 qWarning(
"The index exceeds the range of valid geometries.");
226 return self->m_geometries.at(index);
229qsizetype QQuick3DResourceLoader::qmlGeometriesCount(QQmlListProperty<QQuick3DGeometry> *list)
231 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
232 return self->m_geometries.size();
235void QQuick3DResourceLoader::qmlClearGeometries(QQmlListProperty<QQuick3DGeometry> *list)
237 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
238 for (
const auto &geometry : std::as_const(self->m_geometries)) {
239 if (geometry->parentItem() ==
nullptr)
240 QQuick3DObjectPrivate::get(geometry)->derefSceneManager();
241 disconnect(geometry, &QQuick3DGeometry::destroyed, self, &QQuick3DResourceLoader::onGeometryDestroyed);
244 self->m_geometries.clear();
245 self->markDirty(QQuick3DResourceLoader::GeometriesDirty);
248void QQuick3DResourceLoader::qmlAppendTexture(QQmlListProperty<QQuick3DTexture> *list, QQuick3DTexture *texture)
250 if (texture ==
nullptr)
252 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
253 self->m_textures.push_back(texture);
255 self->markDirty(QQuick3DResourceLoader::TexturesDirty);
257 if (texture->parentItem() ==
nullptr) {
260 QQuick3DObject *parentItem = qobject_cast<QQuick3DObject *>(texture->parent());
262 texture->setParentItem(parentItem);
264 const auto &sceneManager = QQuick3DObjectPrivate::get(self)->sceneManager;
266 QQuick3DObjectPrivate::get(texture)->refSceneManager(*sceneManager);
271 connect(texture, &QQuick3DTextureData::destroyed, self, &QQuick3DResourceLoader::onTextureDestroyed);
274QQuick3DTexture *QQuick3DResourceLoader::qmlTextureAt(QQmlListProperty<QQuick3DTexture> *list, qsizetype index)
276 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
277 if (index >= self->m_textures.size()) {
278 qWarning(
"The index exceeds the range of valid texture data.");
282 return self->m_textures.at(index);
285qsizetype QQuick3DResourceLoader::qmlTexturesCount(QQmlListProperty<QQuick3DTexture> *list)
287 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
288 return self->m_textures.size();
291void QQuick3DResourceLoader::qmlClearTextures(QQmlListProperty<QQuick3DTexture> *list)
293 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
294 for (
const auto &data : std::as_const(self->m_textures)) {
295 if (data->parentItem() ==
nullptr)
296 QQuick3DObjectPrivate::get(data)->derefSceneManager();
297 disconnect(data, &QQuick3DTextureData::destroyed, self, &QQuick3DResourceLoader::onTextureDestroyed);
299 self->m_textures.clear();
300 self->markDirty(QQuick3DResourceLoader::TexturesDirty);
303void QQuick3DResourceLoader::markDirty(ResourceLoaderDirtyType type)
305 if (!(m_dirtyAttributes & quint32(type))) {
306 m_dirtyAttributes |= quint32(type);
311void QQuick3DResourceLoader::updateSceneManager(QQuick3DSceneManager *sceneManager)
314 for (
auto &geometry : m_geometries)
315 if (!geometry->parentItem() && !QQuick3DObjectPrivate::get(geometry)->sceneManager)
316 QQuick3DObjectPrivate::refSceneManager(geometry, *sceneManager);
317 for (
auto &texture : m_textures)
318 if (!texture->parentItem() && !QQuick3DObjectPrivate::get(texture)->sceneManager)
319 QQuick3DObjectPrivate::refSceneManager(texture, *sceneManager);
321 for (
auto &geometry : m_geometries)
322 QQuick3DObjectPrivate::derefSceneManager(geometry);
323 for (
auto &texture : m_textures)
324 QQuick3DObjectPrivate::derefSceneManager(texture);