7#include <QtQuick3DRuntimeRender/private/qssgrenderresourceloader_p.h>
12
13
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
42
43
44
45
46
47
48
49
52
53
54
55
56
57
60
61
62
63
64
65
67QQuick3DResourceLoader::QQuick3DResourceLoader(QQuick3DObject *parent)
68 : QQuick3DObject(*(
new QQuick3DObjectPrivate(QQuick3DObjectPrivate::Type::ResourceLoader)), parent)
72const QList<QUrl> &QQuick3DResourceLoader::meshSources()
const
77void QQuick3DResourceLoader::setMeshSources(
const QList<QUrl> &newMeshSources)
79 if (m_meshSources == newMeshSources)
81 m_meshSources = newMeshSources;
82 emit meshSourcesChanged();
83 markDirty(QQuick3DResourceLoader::MeshesDirty);
87QQmlListProperty<QQuick3DGeometry> QQuick3DResourceLoader::geometries()
89 return QQmlListProperty<QQuick3DGeometry>(
this,
91 QQuick3DResourceLoader::qmlAppendGeometry,
92 QQuick3DResourceLoader::qmlGeometriesCount,
93 QQuick3DResourceLoader::qmlGeometryAt,
94 QQuick3DResourceLoader::qmlClearGeometries);
97QQmlListProperty<QQuick3DTexture> QQuick3DResourceLoader::textures()
99 return QQmlListProperty<QQuick3DTexture>(
this,
101 QQuick3DResourceLoader::qmlAppendTexture,
102 QQuick3DResourceLoader::qmlTexturesCount,
103 QQuick3DResourceLoader::qmlTextureAt,
104 QQuick3DResourceLoader::qmlClearTextures);
107void QQuick3DResourceLoader::onGeometryDestroyed(QObject *object)
110 for (
int i = 0; i < m_geometries.size(); ++i) {
111 if (m_geometries[i] == object) {
112 m_geometries.removeAt(i--);
117 markDirty(QQuick3DResourceLoader::GeometriesDirty);
120void QQuick3DResourceLoader::onTextureDestroyed(QObject *object)
123 for (
int i = 0; i < m_textures.size(); ++i) {
124 if (m_textures[i] == object) {
125 m_textures.removeAt(i--);
130 markDirty(QQuick3DResourceLoader::TexturesDirty);
133QSSGRenderGraphObject *QQuick3DResourceLoader::updateSpatialNode(QSSGRenderGraphObject *node)
137 node =
new QSSGRenderResourceLoader();
139 QQuick3DObject::updateSpatialNode(node);
140 int dirtyAttribute = 0;
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)));
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;
154 resourceLoaderNode->textures.push_back(graphObject);
156 dirtyAttribute |= TexturesDirty;
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;
165 resourceLoaderNode->geometries.push_back(graphObject);
167 dirtyAttribute |= GeometriesDirty;
171 m_dirtyAttributes = dirtyAttribute;
172 return resourceLoaderNode;
176void QQuick3DResourceLoader::markAllDirty()
178 m_dirtyAttributes = 0xffffffff;
179 QQuick3DObject::markAllDirty();
182void QQuick3DResourceLoader::itemChange(ItemChange change,
const ItemChangeData &value)
184 if (change == QQuick3DObject::ItemSceneChange)
185 updateSceneManager(value.sceneManager);
188void QQuick3DResourceLoader::qmlAppendGeometry(QQmlListProperty<QQuick3DGeometry> *list, QQuick3DGeometry *geometry)
190 if (geometry ==
nullptr)
192 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
193 self->m_geometries.push_back(geometry);
195 self->markDirty(QQuick3DResourceLoader::GeometriesDirty);
197 if (geometry->parentItem() ==
nullptr) {
200 QQuick3DObject *parentItem = qobject_cast<QQuick3DObject *>(geometry->parent());
202 geometry->setParentItem(parentItem);
204 const auto &sceneManager = QQuick3DObjectPrivate::get(self)->sceneManager;
206 QQuick3DObjectPrivate::get(geometry)->refSceneManager(*sceneManager);
212 connect(geometry, &QQuick3DGeometry::destroyed, self, &QQuick3DResourceLoader::onGeometryDestroyed);
215QQuick3DGeometry *QQuick3DResourceLoader::qmlGeometryAt(QQmlListProperty<QQuick3DGeometry> *list, qsizetype index)
217 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
219 if (index >= self->m_geometries.size()) {
220 qWarning(
"The index exceeds the range of valid geometries.");
224 return self->m_geometries.at(index);
227qsizetype QQuick3DResourceLoader::qmlGeometriesCount(QQmlListProperty<QQuick3DGeometry> *list)
229 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
230 return self->m_geometries.size();
233void QQuick3DResourceLoader::qmlClearGeometries(QQmlListProperty<QQuick3DGeometry> *list)
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 disconnect(geometry, &QQuick3DGeometry::destroyed, self, &QQuick3DResourceLoader::onGeometryDestroyed);
242 self->m_geometries.clear();
243 self->markDirty(QQuick3DResourceLoader::GeometriesDirty);
246void QQuick3DResourceLoader::qmlAppendTexture(QQmlListProperty<QQuick3DTexture> *list, QQuick3DTexture *texture)
248 if (texture ==
nullptr)
250 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
251 self->m_textures.push_back(texture);
253 self->markDirty(QQuick3DResourceLoader::TexturesDirty);
255 if (texture->parentItem() ==
nullptr) {
258 QQuick3DObject *parentItem = qobject_cast<QQuick3DObject *>(texture->parent());
260 texture->setParentItem(parentItem);
262 const auto &sceneManager = QQuick3DObjectPrivate::get(self)->sceneManager;
264 QQuick3DObjectPrivate::get(texture)->refSceneManager(*sceneManager);
269 connect(texture, &QQuick3DTextureData::destroyed, self, &QQuick3DResourceLoader::onTextureDestroyed);
272QQuick3DTexture *QQuick3DResourceLoader::qmlTextureAt(QQmlListProperty<QQuick3DTexture> *list, qsizetype index)
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.");
280 return self->m_textures.at(index);
283qsizetype QQuick3DResourceLoader::qmlTexturesCount(QQmlListProperty<QQuick3DTexture> *list)
285 QQuick3DResourceLoader *self =
static_cast<QQuick3DResourceLoader *>(list->object);
286 return self->m_textures.size();
289void QQuick3DResourceLoader::qmlClearTextures(QQmlListProperty<QQuick3DTexture> *list)
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 disconnect(data, &QQuick3DTextureData::destroyed, self, &QQuick3DResourceLoader::onTextureDestroyed);
297 self->m_textures.clear();
298 self->markDirty(QQuick3DResourceLoader::TexturesDirty);
301void QQuick3DResourceLoader::markDirty(ResourceLoaderDirtyType type)
303 if (!(m_dirtyAttributes & quint32(type))) {
304 m_dirtyAttributes |= quint32(type);
309void QQuick3DResourceLoader::updateSceneManager(QQuick3DSceneManager *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);
319 for (
auto &geometry : m_geometries)
320 QQuick3DObjectPrivate::derefSceneManager(geometry);
321 for (
auto &texture : m_textures)
322 QQuick3DObjectPrivate::derefSceneManager(texture);