Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
instancerepeater.cpp
Go to the documentation of this file.
1
// Copyright (C) 2022 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
6
#
include
"instancerepeater_p.h"
7
#
include
<
math
.
h
>
8
#
include
<
QMatrix4x4
>
9
10
QT_BEGIN_NAMESPACE
11
12
/*!
13
\qmltype InstanceModel
14
\inherits Object3D
15
\inqmlmodule QtQuick3D.Helpers
16
\since 6.4
17
\brief Defines a data model based on an instance table.
18
19
The InstanceModel QML type is a data model that provides access to the elements of an \l Instancing table.
20
21
The following roles are available:
22
\table
23
\header
24
\li Role name
25
\li Description
26
\row
27
\li \c modelPosition
28
\li The position of the instance as a \l vector3d
29
\row
30
\li \c modelRotation
31
\li The rotation of the instance as a \l quaternion
32
\row
33
\li \c modelScale
34
\li The scale of the instance as a \l vector3d
35
\row
36
\li \c modelColor
37
\li The \l color of the instance
38
\row
39
\li \c modelData
40
\li The custom data of the instance as a \l vector4d
41
\endtable
42
43
\sa InstanceRepeater
44
*/
45
46
/*!
47
\qmlproperty Instancing InstanceModel::instancingTable
48
49
This property specifies the underlying instance table of the model.
50
*/
51
52
InstanceModel::InstanceModel(QObject *parent)
53
: QAbstractListModel(parent)
54
{
55
}
56
57
QVariant InstanceModel::data(
const
QModelIndex &index,
int
role)
const
58
{
59
if
(!index.isValid())
60
return
QVariant();
61
ensureTable();
62
63
int
idx = index.row();
64
65
if
(idx >= m_count) {
66
qWarning(
"InstanceModel: index out of range"
);
67
return
QVariant();
68
}
69
70
auto
*instanceData =
reinterpret_cast
<
const
QQuick3DInstancing::InstanceTableEntry*>(m_instanceData.data()) + idx;
71
72
switch
(role) {
73
case
ColorRole:
74
return
instanceData->getColor();
75
case
PositionRole:
76
return
instanceData->getPosition();
77
case
RotationRole:
78
return
instanceData->getRotation();
79
case
ScaleRole:
80
return
instanceData->getScale();
81
case
CustomDataRole:
82
return
instanceData->instanceData;
83
}
84
return
QVariant();
85
}
86
87
int
InstanceModel::rowCount(
const
QModelIndex &)
const
88
{
89
ensureTable();
90
return
m_count;
91
}
92
93
void
InstanceModel::setInstancing(QQuick3DInstancing *instancing)
94
{
95
if
(m_instancing == instancing)
96
return
;
97
QObject::disconnect(m_tableConnection);
98
m_instancing = instancing;
99
m_tableConnection = QObject::connect(instancing, &QQuick3DInstancing::instanceTableChanged,
this
, &InstanceModel::reset);
100
emit instancingChanged();
101
}
102
103
const
QQuick3DInstancing::InstanceTableEntry *InstanceModel::instanceData(
int
index)
const
104
{
105
if
(index >= m_count)
106
return
nullptr
;
107
return
reinterpret_cast
<
const
QQuick3DInstancing::InstanceTableEntry*>(m_instanceData.constData()) + index;
108
}
109
110
void
InstanceModel::ensureTable()
const
111
{
112
auto
*that =
const_cast
<InstanceModel*>(
this
);
113
that->m_instanceData = m_instancing->instanceBuffer(&that->m_count);
114
}
115
116
void
InstanceModel::reset()
117
{
118
beginResetModel();
119
m_instanceData.clear();
120
endResetModel();
121
}
122
123
/*!
124
\qmltype InstanceRepeater
125
\inherits Repeater3D
126
\inqmlmodule QtQuick3D.Helpers
127
\since 6.4
128
\brief Instantiates components based on an instance table.
129
130
The InstanceRepeater type is used to create a number of objects based on an
131
\l Instancing table. It is a \l Repeater3D subtype that takes an Instancing table instead
132
of a data model, and automatically applies \c position, \c scale, and \c rotation.
133
134
One use case is to implement \l {View3D::pick}{picking} by creating invisible dummy objects
135
that match the rendered instances. To improve performance, the dummy objects can be created with a
136
simpler geometry than the instanced models.
137
138
For example:
139
\qml
140
InstanceRepeater {
141
instancingTable: myInstanceTable
142
Model {
143
source: "#Cube"
144
pickable: true
145
property int instanceIndex: index // expose the index, so we can identify the instance
146
opacity: 0
147
}
148
}
149
\endqml
150
151
\sa InstanceModel
152
*/
153
154
/*!
155
\qmlproperty Instancing InstanceRepeater::instancingTable
156
157
This property specifies the instance table used by the repeater.
158
*/
159
160
InstanceRepeater::InstanceRepeater(QQuick3DNode *parent)
161
: QQuick3DRepeater(parent)
162
{
163
}
164
165
QQuick3DInstancing *InstanceRepeater::instancing()
const
166
{
167
return
m_model ? m_model->instancing() :
nullptr
;
168
}
169
170
void
InstanceRepeater::setInstancing(QQuick3DInstancing *instancing)
171
{
172
if
(m_model && m_model->instancing() == instancing)
173
return
;
174
if
(!m_model)
175
m_model =
new
InstanceModel(
this
);
176
m_model->setInstancing(instancing);
177
setModel(QVariant::fromValue(m_model));
178
emit instancingChanged();
179
}
180
181
void
InstanceRepeater::initDelegate(
int
index, QQuick3DNode *node)
182
{
183
Q_ASSERT(m_model);
184
auto
*entry = m_model->instanceData(index);
185
Q_ASSERT(entry);
186
node->setPosition(entry->getPosition());
187
node->setScale(entry->getScale());
188
node->setRotation(entry->getRotation());
189
}
190
191
QT_END_NAMESPACE
qtquick3d
src
helpers
instancerepeater.cpp
Generated on
for Qt by
1.18.0