summaryrefslogtreecommitdiffstats
path: root/src/render
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2017-08-11 11:08:41 +0100
committerSean Harmer <sean.harmer@kdab.com>2017-08-16 13:19:38 +0000
commita8889da8398c22e5a7f8a0a4ac6bc3c4455ce7b4 (patch)
tree859793594374cbb7a9face81e5c4b75c68f33a24 /src/render
parent2302a59c0f8eab97310ff25a7bff545fd56162c4 (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.cpp1
-rw-r--r--src/render/frontend/qrenderaspect.cpp2
-rw-r--r--src/render/geometry/skeleton.cpp22
-rw-r--r--src/render/geometry/skeleton_p.h11
-rw-r--r--src/render/geometry/skeletondata_p.h3
-rw-r--r--src/render/jobs/updateskinningpalettejob.cpp15
-rw-r--r--src/render/jobs/updateskinningpalettejob_p.h4
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;