summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2017-08-22 15:35:13 +0100
committerSean Harmer <sean.harmer@kdab.com>2017-08-30 12:59:21 +0000
commit9fc405b68e8dd60ed2cd957d85147017621b85f9 (patch)
treeea78a77e7449f8402d0f5a836f095568ea4cb944
parentdab7c73e04cf850819827c3e4c4e7bea6e1a223c (diff)
Factor out local poses into their own vector
To make it easier and more efficient to send all the local poses for a skeleton between aspects. Change-Id: I68bf374a7d466f606f8979fdbf84cb697a47a8a7 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--src/render/geometry/gltfskeletonloader.cpp2
-rw-r--r--src/render/geometry/skeleton.cpp31
-rw-r--r--src/render/geometry/skeleton_p.h4
-rw-r--r--src/render/geometry/skeletondata.cpp1
-rw-r--r--src/render/geometry/skeletondata_p.h3
-rw-r--r--tests/auto/render/skeleton/tst_skeleton.cpp47
6 files changed, 55 insertions, 33 deletions
diff --git a/src/render/geometry/gltfskeletonloader.cpp b/src/render/geometry/gltfskeletonloader.cpp
index 428f7bc74..76601836a 100644
--- a/src/render/geometry/gltfskeletonloader.cpp
+++ b/src/render/geometry/gltfskeletonloader.cpp
@@ -373,13 +373,13 @@ SkeletonData GLTFSkeletonLoader::createSkeletonFromSkin(Skin *skin) const
jointIndexMap.insert(node, i);
JointInfo joint;
- joint.localPose = node->localTransform;
joint.inverseBindPose = inverseBindMatrix(skin, i);
joint.parentIndex = jointIndexMap.value(&m_nodes[node->parentNodeIndex], -1);
if (joint.parentIndex == -1 && i != 0)
qCDebug(Jobs) << "Cannot find parent joint for joint" << i;
skel.joints.push_back(joint);
+ skel.localPoses.push_back(node->localTransform);
skel.jointNames.push_back(node->name);
}
diff --git a/src/render/geometry/skeleton.cpp b/src/render/geometry/skeleton.cpp
index f1761bc18..f672f867e 100644
--- a/src/render/geometry/skeleton.cpp
+++ b/src/render/geometry/skeleton.cpp
@@ -297,9 +297,10 @@ Qt3DCore::QJoint *Skeleton::createFrontendJoints(const SkeletonData &skeletonDat
const int jointCount = skeletonData.joints.size();
frontendJoints.reserve(jointCount);
for (int i = 0; i < jointCount; ++i) {
- const JointInfo &jointInfo = skeletonData.joints[i];
+ const QMatrix4x4 &inverseBindMatrix = skeletonData.joints[i].inverseBindPose;
const QString &jointName = skeletonData.jointNames[i];
- frontendJoints.push_back(createFrontendJoint(jointName, jointInfo));
+ const Qt3DCore::Sqt &localPose = skeletonData.localPoses[i];
+ frontendJoints.push_back(createFrontendJoint(jointName, localPose, inverseBindMatrix));
}
// Now go through and resolve the parent for each joint
@@ -317,13 +318,15 @@ Qt3DCore::QJoint *Skeleton::createFrontendJoints(const SkeletonData &skeletonDat
return frontendJoints[0];
}
-Qt3DCore::QJoint *Skeleton::createFrontendJoint(const QString &jointName, const JointInfo &jointInfo) const
+Qt3DCore::QJoint *Skeleton::createFrontendJoint(const QString &jointName,
+ const Qt3DCore::Sqt &localPose,
+ const QMatrix4x4 &inverseBindMatrix) const
{
auto joint = QAbstractNodeFactory::createNode<QJoint>("QJoint");
- joint->setTranslation(jointInfo.localPose.translation);
- joint->setRotation(jointInfo.localPose.rotation);
- joint->setScale(jointInfo.localPose.scale);
- joint->setInverseBindMatrix(jointInfo.inverseBindPose);
+ joint->setTranslation(localPose.translation);
+ joint->setRotation(localPose.rotation);
+ joint->setScale(localPose.scale);
+ joint->setInverseBindMatrix(inverseBindMatrix);
joint->setName(jointName);
return joint;
}
@@ -338,6 +341,7 @@ void Skeleton::processJointHierarchy(Qt3DCore::QNodeId jointId,
joint->setOwningSkeleton(m_skeletonHandle);
const JointInfo jointInfo(joint, parentJointIndex);
skeletonData.joints.push_back(jointInfo);
+ skeletonData.localPoses.push_back(joint->localPose());
skeletonData.jointNames.push_back(joint->name());
const int jointIndex = skeletonData.joints.size() - 1;
@@ -353,6 +357,7 @@ void Skeleton::clearData()
{
m_name.clear();
m_skeletonData.joints.clear();
+ m_skeletonData.localPoses.clear();
m_skeletonData.jointNames.clear();
m_skeletonData.jointIndices.clear();
}
@@ -364,19 +369,21 @@ void Skeleton::setLocalPose(HJoint jointHandle, const Qt3DCore::Sqt &localPose)
// and set the local pose
const int jointIndex = m_skeletonData.jointIndices.value(jointHandle, -1);
Q_ASSERT(jointIndex != -1);
- m_skeletonData.joints[jointIndex].localPose = localPose;
+ m_skeletonData.localPoses[jointIndex] = localPose;
}
QVector<QMatrix4x4> Skeleton::calculateSkinningMatrixPalette()
{
+ const QVector<Sqt> &localPoses = m_skeletonData.localPoses;
+ QVector<JointInfo> &joints = m_skeletonData.joints;
for (int i = 0; i < m_skeletonData.joints.size(); ++i) {
// Calculate the global pose of this joint
- JointInfo &joint = m_skeletonData.joints[i];
+ JointInfo &joint = joints[i];
if (joint.parentIndex == -1) {
- joint.globalPose = joint.localPose.toMatrix();
+ joint.globalPose = localPoses[i].toMatrix();
} else {
- JointInfo &parentJoint = m_skeletonData.joints[joint.parentIndex];
- joint.globalPose = parentJoint.globalPose * joint.localPose.toMatrix();
+ JointInfo &parentJoint = joints[joint.parentIndex];
+ joint.globalPose = parentJoint.globalPose * localPoses[i].toMatrix();
}
m_skinningPalette[i] = joint.globalPose * joint.inverseBindPose;
diff --git a/src/render/geometry/skeleton_p.h b/src/render/geometry/skeleton_p.h
index 566304114..e1611d21a 100644
--- a/src/render/geometry/skeleton_p.h
+++ b/src/render/geometry/skeleton_p.h
@@ -123,7 +123,9 @@ private:
void loadSkeletonFromUrl();
void loadSkeletonFromData();
Qt3DCore::QJoint *createFrontendJoints(const SkeletonData &skeletonData) const;
- Qt3DCore::QJoint *createFrontendJoint(const QString &jointName, const JointInfo &jointInfo) const;
+ Qt3DCore::QJoint *createFrontendJoint(const QString &jointName,
+ const Qt3DCore::Sqt &localPose,
+ const QMatrix4x4 &inverseBindMatrix) const;
void processJointHierarchy(Qt3DCore::QNodeId jointId, int parentJointIndex, SkeletonData &skeletonData);
void clearData();
diff --git a/src/render/geometry/skeletondata.cpp b/src/render/geometry/skeletondata.cpp
index 8196856b6..bbb59e82d 100644
--- a/src/render/geometry/skeletondata.cpp
+++ b/src/render/geometry/skeletondata.cpp
@@ -48,6 +48,7 @@ SkeletonData::SkeletonData()
void SkeletonData::reserve(int size)
{
joints.reserve(size);
+ localPoses.reserve(size);
jointNames.reserve(size);
}
diff --git a/src/render/geometry/skeletondata_p.h b/src/render/geometry/skeletondata_p.h
index 8de29d4ac..b30a3c6d4 100644
--- a/src/render/geometry/skeletondata_p.h
+++ b/src/render/geometry/skeletondata_p.h
@@ -71,13 +71,11 @@ struct Q_AUTOTEST_EXPORT JointInfo
explicit JointInfo(Joint *joint, int parentJointIndex)
: inverseBindPose(joint->inverseBindMatrix())
- , localPose(joint->localPose())
, parentIndex(parentJointIndex)
{
}
QMatrix4x4 inverseBindPose;
- Qt3DCore::Sqt localPose;
QMatrix4x4 globalPose;
int parentIndex;
};
@@ -89,6 +87,7 @@ struct Q_AUTOTEST_EXPORT SkeletonData
void reserve(int size);
QVector<JointInfo> joints;
+ QVector<Qt3DCore::Sqt> localPoses;
QVector<QString> jointNames;
QHash<HJoint, int> jointIndices;
};
diff --git a/tests/auto/render/skeleton/tst_skeleton.cpp b/tests/auto/render/skeleton/tst_skeleton.cpp
index 9aafe29b9..499bb7cc7 100644
--- a/tests/auto/render/skeleton/tst_skeleton.cpp
+++ b/tests/auto/render/skeleton/tst_skeleton.cpp
@@ -47,6 +47,7 @@ using namespace Qt3DRender::Render;
Q_DECLARE_METATYPE(Qt3DRender::Render::JointInfo)
Q_DECLARE_METATYPE(Qt3DRender::Render::SkeletonData)
+Q_DECLARE_METATYPE(Qt3DCore::Sqt)
namespace {
@@ -230,19 +231,22 @@ private Q_SLOTS:
void checkCreateFrontendJoint_data()
{
- QTest::addColumn<JointInfo>("jointInfo");
+ QTest::addColumn<QMatrix4x4>("inverseBindMatrix");
+ QTest::addColumn<Qt3DCore::Sqt>("localPose");
QTest::addColumn<QString>("jointName");
QTest::addColumn<QJoint *>("expectedJoint");
- QTest::newRow("default") << JointInfo() << QString() << new QJoint();
+ QMatrix4x4 m;
+ Qt3DCore::Sqt localPose;
+ QTest::newRow("default") << m << localPose << QString() << new QJoint();
const QVector3D t(1.0f, 2.0f, 3.0f);
const QQuaternion r = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 45.0f);
const QVector3D s(1.5f, 2.5f, 3.5f);
- JointInfo jointInfo;
- jointInfo.localPose.scale = s;
- jointInfo.localPose.rotation = r;
- jointInfo.localPose.translation = t;
+ localPose.scale = s;
+ localPose.rotation = r;
+ localPose.translation = t;
+
QString name = QLatin1String("Foo");
QJoint *joint = new QJoint();
@@ -250,13 +254,12 @@ private Q_SLOTS:
joint->setRotation(r);
joint->setScale(s);
joint->setName(name);
- QTest::newRow("localPose") << jointInfo << name << joint;
+ joint->setInverseBindMatrix(m);
+ QTest::newRow("localPose") << m << localPose << name << joint;
- QMatrix4x4 m;
m.rotate(r);
m.scale(QVector3D(1.0f, 1.0f, 1.0f) / s);
m.translate(-t);
- jointInfo.inverseBindPose = m;
name = QLatin1String("Bar");
joint = new QJoint();
@@ -265,19 +268,20 @@ private Q_SLOTS:
joint->setScale(s);
joint->setInverseBindMatrix(m);
joint->setName(name);
- QTest::newRow("inverseBind") << jointInfo << name << joint;
+ QTest::newRow("inverseBind") << m << localPose << name << joint;
}
void checkCreateFrontendJoint()
{
// GIVEN
Skeleton backendSkeleton;
- QFETCH(JointInfo, jointInfo);
+ QFETCH(QMatrix4x4, inverseBindMatrix);
+ QFETCH(Qt3DCore::Sqt, localPose);
QFETCH(QString, jointName);
QFETCH(QJoint *, expectedJoint);
// WHEN
- const QJoint *actualJoint = backendSkeleton.createFrontendJoint(jointName, jointInfo);
+ const QJoint *actualJoint = backendSkeleton.createFrontendJoint(jointName, localPose, inverseBindMatrix);
// THEN
QCOMPARE(actualJoint->scale(), expectedJoint->scale());
@@ -302,13 +306,18 @@ private Q_SLOTS:
JointInfo rootJointInfo;
skeletonData.joints.push_back(rootJointInfo);
skeletonData.jointNames.push_back(QLatin1String("rootJoint"));
+ skeletonData.localPoses.push_back(Qt3DCore::Sqt());
const int childCount = 10;
for (int i = 0; i < childCount; ++i) {
JointInfo childJointInfo;
- const float x = static_cast<float>(i);
- childJointInfo.localPose.translation = QVector3D(x, x, x);
childJointInfo.parentIndex = 0;
skeletonData.joints.push_back(childJointInfo);
+
+ const float x = static_cast<float>(i);
+ Qt3DCore::Sqt localPose;
+ localPose.translation = QVector3D(x, x, x);
+ skeletonData.localPoses.push_back(localPose);
+
skeletonData.jointNames.push_back(QString("Child-%1").arg(i));
}
@@ -326,10 +335,14 @@ private Q_SLOTS:
skeletonData.joints.push_back(rootJointInfo);
for (int i = 0; i < childCount; ++i) {
JointInfo childJointInfo;
- const float x = static_cast<float>(i);
- childJointInfo.localPose.translation = QVector3D(x, x, x);
childJointInfo.parentIndex = i;
skeletonData.joints.push_back(childJointInfo);
+
+ const float x = static_cast<float>(i);
+ Qt3DCore::Sqt localPose;
+ localPose.translation = QVector3D(x, x, x);
+ skeletonData.localPoses.push_back(localPose);
+
skeletonData.jointNames.push_back(QString("Child-%1").arg(i));
}
@@ -367,7 +380,7 @@ private Q_SLOTS:
QCOMPARE(joints.size(), skeletonData.joints.size());
for (int i = 0; i < joints.size(); ++i) {
// Check the translations match
- QCOMPARE(joints[i]->translation(), skeletonData.joints[i].localPose.translation);
+ QCOMPARE(joints[i]->translation(), skeletonData.localPoses[i].translation);
}
// Now we know the order of Joints match. Check the parents match too