10#include <QtQuick3DRuntimeRender/private/qssgrendergraphobject_p.h>
11#include <QtQuick3DRuntimeRender/private/qssgrenderskin_p.h>
13#include <QtQuick3DUtils/private/qssgutils_p.h>
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
48QQuick3DSkin::QQuick3DSkin(QQuick3DObject *parent)
49 : QQuick3DObject(*(
new QQuick3DObjectPrivate(QQuick3DObjectPrivate::Type::Skin)), parent)
53QQuick3DSkin::~QQuick3DSkin()
55 for (
const auto &conn : m_jointsConnections) {
56 disconnect(conn.first);
57 disconnect(conn.second);
62
63
64
65
66
67
68
69
70
71
72
73QQmlListProperty<QQuick3DNode> QQuick3DSkin::joints()
75 return QQmlListProperty<QQuick3DNode>(
this,
77 QQuick3DSkin::qmlAppendJoint,
78 QQuick3DSkin::qmlJointsCount,
79 QQuick3DSkin::qmlJointAt,
80 QQuick3DSkin::qmlClearJoints);
83#define POS4BONETRANS(x) (sizeof(float) * 16
* (x) * 2
)
84#define POS4BONENORM(x) (sizeof(float) * 16
* ((x) * 2
+ 1
))
86void QQuick3DSkin::qmlAppendJoint(QQmlListProperty<QQuick3DNode> *list, QQuick3DNode *joint)
90 QQuick3DSkin *self =
static_cast<QQuick3DSkin *>(list->object);
91 if (!self->m_jointsConnections.contains(joint)) {
92 self->m_jointsConnections[joint] =
95 joint, &QQuick3DNode::sceneTransformChanged,
96 self, [self, joint]() {
97 self->m_dirtyJoints.insert(joint);
101 joint, &QQuick3DNode::destroyed,
102 self, [self, joint]() {
103 self->m_dirtyJoints.remove(joint);
104 self->m_removedJoints.insert(joint);
110 self->m_joints.push_back(joint);
111 self->m_dirtyJoints.insert(joint);
115QQuick3DNode *QQuick3DSkin::qmlJointAt(QQmlListProperty<QQuick3DNode> *list, qsizetype index)
117 QQuick3DSkin *self =
static_cast<QQuick3DSkin *>(list->object);
118 return self->m_joints.at(index);
121qsizetype QQuick3DSkin::qmlJointsCount(QQmlListProperty<QQuick3DNode> *list)
123 QQuick3DSkin *self =
static_cast<QQuick3DSkin *>(list->object);
124 return self->m_joints.size();
127void QQuick3DSkin::qmlClearJoints(QQmlListProperty<QQuick3DNode> *list)
129 QQuick3DSkin *self =
static_cast<QQuick3DSkin *>(list->object);
130 for (
const auto &conn : self->m_jointsConnections) {
131 disconnect(conn.first);
132 disconnect(conn.second);
134 self->m_jointsConnections.clear();
136 self->m_joints.clear();
137 self->m_boneData.clear();
138 self->m_dirtyJoints.clear();
139 self->m_removedJoints.clear();
145
146
147
148
149
150
151
152
153
154
155QList<QMatrix4x4> QQuick3DSkin::inverseBindPoses()
const
157 return m_inverseBindPoses;
160void QQuick3DSkin::setInverseBindPoses(
const QList<QMatrix4x4> &poses)
162 if (m_inverseBindPoses == poses)
165 m_updatedByNewInverseBindPoses = qMax(poses.size(), m_inverseBindPoses.size());
166 m_inverseBindPoses = poses;
168 emit inverseBindPosesChanged();
172QSSGRenderGraphObject *QQuick3DSkin::updateSpatialNode(QSSGRenderGraphObject *node)
176 node =
new QSSGRenderSkin();
178 QQuick3DObject::updateSpatialNode(node);
179 auto skinNode =
static_cast<QSSGRenderSkin *>(node);
181 if (!m_removedJoints.empty()) {
182 for (
int i = m_joints.size() - 1; i >= 0; --i) {
183 const auto &joint = m_joints.at(i);
184 if (m_removedJoints.contains(joint)) {
185 m_joints.removeAt(i);
187 sizeof(
float) * 16 * 2);
190 m_removedJoints.clear();
193 if (skinNode->boneCount != quint32(m_joints.size())) {
194 skinNode->boneCount = quint32(m_joints.size());
195 const int boneTexWidth = qCeil(qSqrt(skinNode->boneCount * 4 * 2));
196 const int textureSizeInBytes = boneTexWidth * boneTexWidth * 16;
197 m_boneData.resize(textureSizeInBytes);
198 skinNode->setSize(QSize(boneTexWidth, boneTexWidth));
201 if (m_updatedByNewInverseBindPoses > 0 || !m_dirtyJoints.empty()) {
202 for (
int i = 0; i < m_joints.size(); ++i) {
203 const auto &joint = m_joints.at(i);
204 if (i < m_updatedByNewInverseBindPoses || m_dirtyJoints.contains(joint)) {
205 QMatrix4x4 jointGlobal = joint->sceneTransform();
206 if (m_inverseBindPoses.size() > i)
207 jointGlobal *= m_inverseBindPoses.at(i);
209 reinterpret_cast<
const void *>(jointGlobal.constData()),
212 reinterpret_cast<
const void *>(QMatrix4x4(jointGlobal.normalMatrix()).constData()),
216 m_dirtyJoints.clear();
217 m_updatedByNewInverseBindPoses = 0;
220 skinNode->setTextureData(m_boneData);
Combined button and popup list for selecting options.