diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-08-22 15:35:13 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-08-30 12:59:21 +0000 |
commit | 9fc405b68e8dd60ed2cd957d85147017621b85f9 (patch) | |
tree | ea78a77e7449f8402d0f5a836f095568ea4cb944 | |
parent | dab7c73e04cf850819827c3e4c4e7bea6e1a223c (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.cpp | 2 | ||||
-rw-r--r-- | src/render/geometry/skeleton.cpp | 31 | ||||
-rw-r--r-- | src/render/geometry/skeleton_p.h | 4 | ||||
-rw-r--r-- | src/render/geometry/skeletondata.cpp | 1 | ||||
-rw-r--r-- | src/render/geometry/skeletondata_p.h | 3 | ||||
-rw-r--r-- | tests/auto/render/skeleton/tst_skeleton.cpp | 47 |
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 |