diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-08-11 11:08:41 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-08-16 13:19:38 +0000 |
commit | a8889da8398c22e5a7f8a0a4ac6bc3c4455ce7b4 (patch) | |
tree | 859793594374cbb7a9face81e5c4b75c68f33a24 /src/render | |
parent | 2302a59c0f8eab97310ff25a7bff545fd56162c4 (diff) |
Update local poses of JointInfos from dirty Joints
These will then get picked up when calculating the skinning matrix
palettes for the armatures.
In the future, this job is a good candidate for being decomposed
into multiple jobs for data parallelism e.g. one job per skeleton.
Change-Id: Ie1e7ddb3baec80f639bf8824482f730967a43afe
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/backend/renderer.cpp | 1 | ||||
-rw-r--r-- | src/render/frontend/qrenderaspect.cpp | 2 | ||||
-rw-r--r-- | src/render/geometry/skeleton.cpp | 22 | ||||
-rw-r--r-- | src/render/geometry/skeleton_p.h | 11 | ||||
-rw-r--r-- | src/render/geometry/skeletondata_p.h | 3 | ||||
-rw-r--r-- | src/render/jobs/updateskinningpalettejob.cpp | 15 | ||||
-rw-r--r-- | src/render/jobs/updateskinningpalettejob_p.h | 4 |
7 files changed, 53 insertions, 5 deletions
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index bf34842d1..3ca1a1675 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -1487,6 +1487,7 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() renderBinJobs.push_back(m_expandBoundingVolumeJob); } + m_updateSkinningPaletteJob->setDirtyJoints(m_nodesManager->jointManager()->dirtyJoints()); renderBinJobs.push_back(m_updateSkinningPaletteJob); renderBinJobs.push_back(m_updateLevelOfDetailJob); renderBinJobs.push_back(m_cleanupJob); diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 756a0e792..2ce6fc685 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -242,7 +242,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType<QGeometry>(QSharedPointer<Render::NodeFunctor<Render::Geometry, Render::GeometryManager> >::create(m_renderer)); q->registerBackendType<QGeometryRenderer>(QSharedPointer<Render::GeometryRendererFunctor>::create(m_renderer, m_nodeManagers->geometryRendererManager())); q->registerBackendType<Qt3DCore::QArmature>(QSharedPointer<Render::NodeFunctor<Render::Armature, Render::ArmatureManager>>::create(m_renderer)); - q->registerBackendType<Qt3DCore::QSkeletonLoader>(QSharedPointer<Render::SkeletonFunctor>::create(m_renderer, m_nodeManagers->skeletonManager())); + q->registerBackendType<Qt3DCore::QSkeletonLoader>(QSharedPointer<Render::SkeletonFunctor>::create(m_renderer, m_nodeManagers->skeletonManager(), m_nodeManagers->jointManager())); q->registerBackendType<Qt3DCore::QJoint>(QSharedPointer<Render::JointFunctor>::create(m_renderer, m_nodeManagers->jointManager(), m_nodeManagers->skeletonManager())); // Textures diff --git a/src/render/geometry/skeleton.cpp b/src/render/geometry/skeleton.cpp index 76d087a24..1839aa056 100644 --- a/src/render/geometry/skeleton.cpp +++ b/src/render/geometry/skeleton.cpp @@ -63,6 +63,8 @@ namespace Render { Skeleton::Skeleton() : BackendNode(Qt3DCore::QBackendNode::ReadWrite) , m_status(Qt3DCore::QSkeletonLoader::NotReady) + , m_skeletonManager(nullptr) + , m_jointManager(nullptr) { } @@ -330,8 +332,10 @@ void Skeleton::processJointHierarchy(Qt3DCore::QNodeId jointId, joint->setOwningSkeleton(m_skeletonHandle); const JointInfo jointInfo(joint, parentJointIndex); skeletonData.joints.push_back(jointInfo); + const int jointIndex = skeletonData.joints.size() - 1; - skeletonData.jointIndices.insert(jointId, jointIndex); + const HJoint jointHandle = m_jointManager->lookupHandle(jointId); + skeletonData.jointIndices.insert(jointHandle, jointIndex); // Recurse to the children for (const auto childJointId : joint->childJointIds()) @@ -345,6 +349,16 @@ void Skeleton::clearData() m_skeletonData.jointIndices.clear(); } +// Called from UpdateSkinningPaletteJob +void Skeleton::setLocalPose(HJoint jointHandle, const Qt3DCore::Sqt &localPose) +{ + // Find the corresponding index into the JointInfo vector + // and set the local pose + const int jointIndex = m_skeletonData.jointIndices.value(jointHandle, -1); + Q_ASSERT(jointIndex != -1); + m_skeletonData.joints[jointIndex].localPose = localPose; +} + QVector<QMatrix4x4> Skeleton::calculateSkinningMatrixPalette() { for (int i = 0; i < m_skeletonData.joints.size(); ++i) { @@ -363,9 +377,12 @@ QVector<QMatrix4x4> Skeleton::calculateSkinningMatrixPalette() } -SkeletonFunctor::SkeletonFunctor(AbstractRenderer *renderer, SkeletonManager *skeletonManager) +SkeletonFunctor::SkeletonFunctor(AbstractRenderer *renderer, + SkeletonManager *skeletonManager, + JointManager *jointManager) : m_renderer(renderer) , m_skeletonManager(skeletonManager) + , m_jointManager(jointManager) { } @@ -374,6 +391,7 @@ Qt3DCore::QBackendNode *SkeletonFunctor::create(const Qt3DCore::QNodeCreatedChan Skeleton *backend = m_skeletonManager->getOrCreateResource(change->subjectId()); backend->setRenderer(m_renderer); backend->setSkeletonManager(m_skeletonManager); + backend->setJointManager(m_jointManager); return backend; } diff --git a/src/render/geometry/skeleton_p.h b/src/render/geometry/skeleton_p.h index fa9b6fc66..2a8ede17e 100644 --- a/src/render/geometry/skeleton_p.h +++ b/src/render/geometry/skeleton_p.h @@ -69,6 +69,7 @@ class QJoint; namespace Qt3DRender { namespace Render { +class JointManager; class SkeletonManager; class Q_AUTOTEST_EXPORT Skeleton : public BackendNode @@ -79,6 +80,9 @@ public: void setSkeletonManager(SkeletonManager *skeletonManager) { m_skeletonManager = skeletonManager; } SkeletonManager *skeletonManager() const { return m_skeletonManager; } + void setJointManager(JointManager *jointManager) { m_jointManager = jointManager; } + JointManager *jointManager() const { return m_jointManager; } + void cleanup(); void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; void setStatus(Qt3DCore::QSkeletonLoader::Status status); @@ -97,6 +101,7 @@ public: // Called from jobs void loadSkeleton(); + void setLocalPose(HJoint jointHandle, const Qt3DCore::Sqt &localPose); QVector<QMatrix4x4> calculateSkinningMatrixPalette(); // Allow unit tests to set the data type @@ -137,6 +142,7 @@ private: QString m_name; SkeletonData m_skeletonData; SkeletonManager *m_skeletonManager; + JointManager *m_jointManager; HSkeleton m_skeletonHandle; // Our own handle to set on joints #if defined(QT_BUILD_INTERNAL) @@ -157,7 +163,9 @@ inline QDebug operator<<(QDebug dbg, const Skeleton &skeleton) class SkeletonFunctor : public Qt3DCore::QBackendNodeMapper { public: - explicit SkeletonFunctor(AbstractRenderer *renderer, SkeletonManager *skeletonManager); + explicit SkeletonFunctor(AbstractRenderer *renderer, + SkeletonManager *skeletonManager, + JointManager *jointManager); Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const final; Qt3DCore::QBackendNode *get(Qt3DCore::QNodeId id) const final; void destroy(Qt3DCore::QNodeId id) const final; @@ -165,6 +173,7 @@ public: private: AbstractRenderer *m_renderer; SkeletonManager *m_skeletonManager; + JointManager *m_jointManager; }; } // namespace Render diff --git a/src/render/geometry/skeletondata_p.h b/src/render/geometry/skeletondata_p.h index 9e98e08fa..8fde853f2 100644 --- a/src/render/geometry/skeletondata_p.h +++ b/src/render/geometry/skeletondata_p.h @@ -54,6 +54,7 @@ #include <QtCore/qvector.h> #include <Qt3DCore/private/sqt_p.h> +#include <Qt3DRender/private/handle_types_p.h> #include <Qt3DRender/private/joint_p.h> QT_BEGIN_NAMESPACE @@ -88,7 +89,7 @@ struct Q_AUTOTEST_EXPORT SkeletonData SkeletonData(); QVector<JointInfo> joints; - QHash<Qt3DCore::QNodeId, int> jointIndices; + QHash<HJoint, int> jointIndices; }; } // namespace Render diff --git a/src/render/jobs/updateskinningpalettejob.cpp b/src/render/jobs/updateskinningpalettejob.cpp index d46de03f7..9cb80c42b 100644 --- a/src/render/jobs/updateskinningpalettejob.cpp +++ b/src/render/jobs/updateskinningpalettejob.cpp @@ -58,6 +58,21 @@ UpdateSkinningPaletteJob::~UpdateSkinningPaletteJob() void UpdateSkinningPaletteJob::run() { + // TODO: Decompose this job across several jobs, say one per skeleton so + // that it can be done in parallel + + // Update the local pose transforms of JointInfo's in Skeletons from + // the set of dirty joints. + for (const auto jointHandle : m_dirtyJoints) { + Joint *joint = m_nodeManagers->jointManager()->data(jointHandle); + Q_ASSERT(joint); + Skeleton *skeleton = m_nodeManagers->skeletonManager()->data(joint->owningSkeleton()); + Q_ASSERT(skeleton); + if (skeleton->isEnabled() && joint->isEnabled()) + skeleton->setLocalPose(jointHandle, joint->localPose()); + } + + // Find all the armature components and update their skinning palettes QVector<HArmature> dirtyArmatures; findDirtyArmatures(m_root, dirtyArmatures); diff --git a/src/render/jobs/updateskinningpalettejob_p.h b/src/render/jobs/updateskinningpalettejob_p.h index 3c5a4648d..9e230f143 100644 --- a/src/render/jobs/updateskinningpalettejob_p.h +++ b/src/render/jobs/updateskinningpalettejob_p.h @@ -70,11 +70,15 @@ public: void setRoot(Entity *root) { m_root = root; } void setManagers(NodeManagers *nodeManagers) { m_nodeManagers = nodeManagers; } + void setDirtyJoints(const QVector<HJoint> dirtyJoints) { m_dirtyJoints = dirtyJoints; } + void clearDirtyJoints() { m_dirtyJoints.clear(); } + protected: void run() override; void findDirtyArmatures(Entity *entity, QVector<HArmature> &armatures) const; NodeManagers *m_nodeManagers; Entity *m_root; + QVector<HJoint> m_dirtyJoints; }; typedef QSharedPointer<UpdateSkinningPaletteJob> UpdateSkinningPaletteJobPtr; |