1 | // Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "updateskinningpalettejob_p.h" |
5 | #include <Qt3DRender/private/nodemanagers_p.h> |
6 | #include <Qt3DRender/private/managers_p.h> |
7 | #include <Qt3DRender/private/handle_types_p.h> |
8 | #include <Qt3DRender/private/job_common_p.h> |
9 | |
10 | QT_BEGIN_NAMESPACE |
11 | |
12 | namespace Qt3DRender { |
13 | namespace Render { |
14 | |
15 | UpdateSkinningPaletteJob::UpdateSkinningPaletteJob() |
16 | : Qt3DCore::QAspectJob() |
17 | , m_nodeManagers(nullptr) |
18 | , m_root() |
19 | { |
20 | SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateSkinningPalette, 0) |
21 | } |
22 | |
23 | UpdateSkinningPaletteJob::~UpdateSkinningPaletteJob() |
24 | { |
25 | } |
26 | |
27 | void UpdateSkinningPaletteJob::run() |
28 | { |
29 | auto armatureManager = m_nodeManagers->armatureManager(); |
30 | if (armatureManager->count() == 0) |
31 | return; |
32 | |
33 | // TODO: Decompose this job across several jobs, say one per skeleton so |
34 | // that it can be done in parallel |
35 | |
36 | // Update the local pose transforms of JointInfo's in Skeletons from |
37 | // the set of dirty joints. |
38 | for (const auto &jointHandle : std::as_const(t&: m_dirtyJoints)) { |
39 | Joint *joint = m_nodeManagers->jointManager()->data(handle: jointHandle); |
40 | Q_ASSERT(joint); |
41 | Skeleton *skeleton = m_nodeManagers->skeletonManager()->data(handle: joint->owningSkeleton()); |
42 | Q_ASSERT(skeleton); |
43 | if (skeleton->isEnabled() && joint->isEnabled()) |
44 | skeleton->setLocalPose(jointHandle, localPose: joint->localPose()); |
45 | } |
46 | |
47 | // Find all the armature components and update their skinning palettes |
48 | QList<HArmature> dirtyArmatures; |
49 | m_root->traverse(operation: [&dirtyArmatures](Entity *entity) { |
50 | const auto armatureHandle = entity->componentHandle<Armature>(); |
51 | if (!armatureHandle.isNull() && !dirtyArmatures.contains(t: armatureHandle)) |
52 | dirtyArmatures.push_back(t: armatureHandle); |
53 | }); |
54 | |
55 | // Update the skeleton for each dirty armature |
56 | auto skeletonManager = m_nodeManagers->skeletonManager(); |
57 | for (const auto &armatureHandle : std::as_const(t&: dirtyArmatures)) { |
58 | auto armature = armatureManager->data(handle: armatureHandle); |
59 | Q_ASSERT(armature); |
60 | |
61 | auto skeletonId = armature->skeletonId(); |
62 | auto skeleton = skeletonManager->lookupResource(id: skeletonId); |
63 | Q_ASSERT(skeleton); |
64 | |
65 | const QVector<QMatrix4x4> &skinningPalette = skeleton->calculateSkinningMatrixPalette(); |
66 | armature->skinningPaletteUniform().setData(skinningPalette); |
67 | } |
68 | } |
69 | |
70 | } // namespace Render |
71 | } // namespace Qt3DRender |
72 | |
73 | QT_END_NAMESPACE |
74 |