1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qssgscenedesc_p.h"
5
6QT_BEGIN_NAMESPACE
7
8bool QSSGSceneDesc::PropertyCall::set(QQuick3DObject &, const char *, const void *) { return false; }
9bool QSSGSceneDesc::PropertyCall::get(const QQuick3DObject &, const void *[]) const { return false; }
10
11static inline quint16 getNextNodeId(QSSGSceneDesc::Scene &scene)
12{
13 /* root node uses the default value 0 */
14 return ++scene.nodeId;
15}
16
17void QSSGSceneDesc::addNode(QSSGSceneDesc::Node &parent, QSSGSceneDesc::Node &node)
18{
19 Q_ASSERT(parent.scene);
20 node.scene = parent.scene;
21 node.id = getNextNodeId(scene&: *parent.scene);
22
23 if (QSSGRenderGraphObject::isResource(type: node.runtimeType) || node.nodeType == Node::Type::Mesh || node.nodeType == Node::Type::Skeleton)
24 node.scene->resources.push_back(t: &node);
25 else // Here goes nothing: kick all the resources out of the tree...
26 parent.children.push_back(t: &node);
27}
28
29void QSSGSceneDesc::addNode(QSSGSceneDesc::Scene &scene, QSSGSceneDesc::Node &node)
30{
31 if (scene.root) {
32 addNode(parent&: *scene.root, node);
33 } else {
34 Q_ASSERT(node.id == 0);
35 node.scene = &scene;
36 scene.root = &node;
37 }
38}
39
40void QSSGSceneDesc::Scene::reset()
41{
42 id.clear();
43 nodeId = 0;
44 root = nullptr;
45 resources.clear();
46 meshStorage.clear();
47}
48
49void QSSGSceneDesc::Scene::cleanup()
50{
51 id.clear();
52 nodeId = 0;
53
54 root->cleanupChildren();
55 delete root;
56 root = nullptr;
57
58 qDeleteAll(c: resources);
59 resources.clear();
60
61 for (auto *anim: animations) {
62 for (auto *ch: anim->channels) {
63 qDeleteAll(c: ch->keys);
64 ch->keys.clear();
65 delete ch;
66 }
67 delete anim;
68 }
69 animations.clear();
70}
71
72QMetaType QSSGSceneDesc::listViewMetaType()
73{
74 return QMetaType::fromType<QSSGSceneDesc::ListView *>();
75}
76
77void QSSGSceneDesc::destructValue(QVariant &value)
78{
79 if (!value.isValid())
80 return;
81
82 if (value.metaType() == QMetaType::fromType<QSSGSceneDesc::NodeList *>())
83 delete value.value<NodeList *>();
84 else if (value.metaType() == QMetaType::fromType<QSSGSceneDesc::ListView *>())
85 delete value.value<ListView *>();
86 // Non-pointer types are destructed by ~QVariant
87 else if ((value.metaType().flags() & QMetaType::TypeFlag::IsPointer)
88 // Mesh node will be deleted when cleaning up resources.
89 && (value.metaType() != QMetaType::fromType<QSSGSceneDesc::Mesh *>())
90 // Referencing nodes will not be deleted here.
91 // They should be deleted in the node hierarchy or resources.
92 && (value.metaType().id() != qMetaTypeId<QSSGSceneDesc::Node *>())) {
93 qWarning() << value.metaType().name() << " was not destroyed correctly.";
94 }
95}
96
97void QSSGSceneDesc::destructNode(Node &node)
98{
99 for (auto *prop : node.properties)
100 delete prop;
101 // Not necessary to clear the list as long as we only call this from the destructor
102}
103
104QSSGSceneDesc::Node::~Node() { destructNode(node&: *this); }
105
106void QSSGSceneDesc::Node::cleanupChildren()
107{
108 auto firstIt = children.begin();
109 auto lastIt = children.end();
110 for (auto it = firstIt; it != lastIt; ++it) {
111 Node *node = *it;
112 node->cleanupChildren();
113 delete node;
114 }
115}
116
117QSSGSceneDesc::Property *QSSGSceneDesc::setProperty(Node &node, const char *name, QVariant &&value)
118{
119 Q_ASSERT(node.scene);
120 QSSGSceneDesc::Property *prop = new QSSGSceneDesc::Property;
121 prop->name = name;
122 prop->call = nullptr;
123 prop->value = value;
124 node.properties.push_back(t: prop);
125 return prop;
126}
127
128QSSGSceneDesc::Model::Model() : Node(Node::Type::Model, Node::RuntimeType::Model) {}
129
130QSSGSceneDesc::Camera::Camera(RuntimeType rt) : Node(Node::Type::Camera, rt) {}
131
132QSSGSceneDesc::Light::Light(RuntimeType rt) : Node(Node::Type::Light, rt) {}
133
134QSSGSceneDesc::Skin::Skin() : Node(Node::Type::Skin, Node::RuntimeType::Skin) {}
135
136QSSGSceneDesc::Skeleton::Skeleton() : Node(Node::Type::Skeleton, Node::RuntimeType::Skeleton) {}
137
138QSSGSceneDesc::Joint::Joint() : Node(Node::Type::Joint, Node::RuntimeType::Joint) {}
139
140QSSGSceneDesc::MorphTarget::MorphTarget() : Node(Node::Type::MorphTarget, Node::RuntimeType::MorphTarget) {}
141
142QSSGSceneDesc::Material::Material(RuntimeType rt) : Node(Node::Type::Material, rt) {}
143
144QSSGSceneDesc::Texture::Texture(RuntimeType rt, const QByteArray &name)
145 : Node(name, Node::Type::Texture, rt)
146{
147}
148
149QSSGSceneDesc::TextureData::TextureData(const QByteArray &textureData, QSize size, const QByteArray &format, quint8 flags, QByteArray name)
150 : Node(name, Node::Type::Texture, RuntimeType::TextureData)
151 , data(textureData)
152 , sz(size)
153 , fmt(format)
154 , flgs(flags)
155{}
156
157QSSGSceneDesc::Mesh::Mesh(QByteArray name, qsizetype index)
158 : Node(name, Node::Type::Mesh, RuntimeType::Node)
159 , idx(index)
160{}
161
162QT_END_NAMESPACE
163

source code of qtquick3d/src/assetutils/qssgscenedesc.cpp