diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/animation/backend/animationutils.cpp | 49 | ||||
-rw-r--r-- | src/animation/backend/animationutils_p.h | 9 | ||||
-rw-r--r-- | src/animation/backend/skeleton.cpp | 9 | ||||
-rw-r--r-- | src/animation/backend/skeleton_p.h | 17 | ||||
-rw-r--r-- | src/animation/frontend/qanimationaspect.cpp | 1 | ||||
-rw-r--r-- | src/core/transforms/sqt_p.h | 1 |
6 files changed, 85 insertions, 1 deletions
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp index 83a9a8426..a1224f69a 100644 --- a/src/animation/backend/animationutils.cpp +++ b/src/animation/backend/animationutils.cpp @@ -48,6 +48,7 @@ #include <QtGui/qquaternion.h> #include <QtGui/qcolor.h> #include <QtCore/qvariant.h> +#include <QtCore/qvarlengtharray.h> #include <Qt3DAnimation/private/animationlogging_p.h> #include <numeric> @@ -292,13 +293,45 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim bool finalFrame) { QVector<Qt3DCore::QSceneChangePtr> changes; + QVarLengthArray<Skeleton *, 4> dirtySkeletons; + // Iterate over the mappings for (const MappingData &mappingData : mappingDataVec) { if (!mappingData.propertyName) continue; + // Build the new value from the channel/fcurve evaluation results const QVariant v = buildPropertyValue(mappingData, channelResults); - if (v.isValid()) { + if (!v.isValid()) + continue; + + // TODO: Avoid wrapping joint transform components up in a variant, just + // to immediately unwrap them again. Refactor buildPropertyValue() to call + // helper functions that we can call directly here for joints. + if (mappingData.skeleton && mappingData.jointIndex != -1) { + // Remember that this skeleton is dirty. We will ask each dirty skeleton + // to send its set of local poses to observers below. + if (!dirtySkeletons.contains(mappingData.skeleton)) + dirtySkeletons.push_back(mappingData.skeleton); + + switch (mappingData.jointTransformComponent) { + case MappingData::Scale: + mappingData.skeleton->setJointScale(mappingData.jointIndex, v.value<QVector3D>()); + break; + + case MappingData::Rotation: + mappingData.skeleton->setJointRotation(mappingData.jointIndex, v.value<QQuaternion>()); + break; + + case MappingData::Translation: + mappingData.skeleton->setJointTranslation(mappingData.jointIndex, v.value<QVector3D>()); + break; + + default: + Q_UNREACHABLE(); + break; + } + } else { // Construct a property update change, set target, property and delivery options auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(mappingData.targetId); e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); @@ -311,6 +344,8 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim } } + for (const auto skeleton : dirtySkeletons) + skeleton->sendLocalPoses(); // If it's the final frame, notify the frontend that we've stopped if (finalFrame) { @@ -415,6 +450,7 @@ QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &chann // Populate the data we need, easy stuff first MappingData mappingData; mappingData.targetId = mapping->skeletonId(); + mappingData.skeleton = mapping->skeleton(); const int propertyCount = jointProperties.size(); for (int propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex) { @@ -430,6 +466,17 @@ QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &chann mappingData.type = nameAndType.type; mappingData.channelIndices = channelComponentIndices[index]; mappingData.jointIndex = jointIndex; + + // Convert property name for joint transform components to + // an enumerated type so we can avoid the string comparisons + // when sending the change events after evaluation. + if (qstrcmp(mappingData.propertyName, "scale") == 0) + mappingData.jointTransformComponent = MappingData::Scale; + else if (qstrcmp(mappingData.propertyName, "rotation") == 0) + mappingData.jointTransformComponent = MappingData::Rotation; + else if (qstrcmp(mappingData.propertyName, "translation") == 0) + mappingData.jointTransformComponent = MappingData::Translation; + mappingDataVec.push_back(mappingData); } } diff --git a/src/animation/backend/animationutils_p.h b/src/animation/backend/animationutils_p.h index 5d84f54b0..a225e9311 100644 --- a/src/animation/backend/animationutils_p.h +++ b/src/animation/backend/animationutils_p.h @@ -71,8 +71,17 @@ typedef QVector<int> ComponentIndices; struct MappingData { + enum JointTransformComponent { + NoTransformComponent = 0, + Scale, + Rotation, + Translation + }; + Qt3DCore::QNodeId targetId; + Skeleton *skeleton = nullptr; int jointIndex = -1; + JointTransformComponent jointTransformComponent = NoTransformComponent; const char *propertyName; QAnimationCallback *callback; QAnimationCallback::Flags callbackFlags; diff --git a/src/animation/backend/skeleton.cpp b/src/animation/backend/skeleton.cpp index a920e2473..dcfaf55e7 100644 --- a/src/animation/backend/skeleton.cpp +++ b/src/animation/backend/skeleton.cpp @@ -96,6 +96,15 @@ void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) BackendNode::sceneChangeEvent(e); } +void Skeleton::sendLocalPoses() +{ + auto e = QPropertyUpdatedChangePtr::create(peerId()); + e->setDeliveryFlags(Qt3DCore::QSceneChange::BackendNodes); + e->setPropertyName("localPoses"); + e->setValue(QVariant::fromValue(m_jointLocalPoses)); + notifyObservers(e); +} + } // namespace Animation } // namespace Qt3DAnimation diff --git a/src/animation/backend/skeleton_p.h b/src/animation/backend/skeleton_p.h index 19da98261..e26e276d9 100644 --- a/src/animation/backend/skeleton_p.h +++ b/src/animation/backend/skeleton_p.h @@ -66,6 +66,23 @@ public: int jointCount() const { return m_jointLocalPoses.size(); } + void setJointScale(int jointIndex, const QVector3D &scale) + { + m_jointLocalPoses[jointIndex].scale = scale; + } + + void setJointRotation(int jointIndex, const QQuaternion &rotation) + { + m_jointLocalPoses[jointIndex].rotation = rotation; + } + + void setJointTranslation(int jointIndex, const QVector3D &translation) + { + m_jointLocalPoses[jointIndex].translation = translation; + } + + void sendLocalPoses(); + #if defined(QT_BUILD_INTERNAL) void setJointCount(int jointCount) { diff --git a/src/animation/frontend/qanimationaspect.cpp b/src/animation/frontend/qanimationaspect.cpp index 14a0c4f8c..9b23a7b1d 100644 --- a/src/animation/frontend/qanimationaspect.cpp +++ b/src/animation/frontend/qanimationaspect.cpp @@ -95,6 +95,7 @@ QAnimationAspect::QAnimationAspect(QAnimationAspectPrivate &dd, QObject *parent) Q_D(QAnimationAspect); qRegisterMetaType<Qt3DAnimation::QAnimationClipLoader*>(); qRegisterMetaType<Qt3DAnimation::QChannelMapper*>(); + qRegisterMetaType<QVector<Qt3DCore::Sqt>>(); registerBackendType<QAbstractAnimationClip>( QSharedPointer<Animation::NodeFunctor<Animation::AnimationClip, Animation::AnimationClipLoaderManager>>::create(d->m_handler.data(), diff --git a/src/core/transforms/sqt_p.h b/src/core/transforms/sqt_p.h index 262e3a645..5fdefccc8 100644 --- a/src/core/transforms/sqt_p.h +++ b/src/core/transforms/sqt_p.h @@ -101,6 +101,7 @@ struct JointNamesAndLocalPoses QT_END_NAMESPACE +Q_DECLARE_METATYPE(QVector<Qt3DCore::Sqt>) Q_DECLARE_METATYPE(Qt3DCore::JointNamesAndLocalPoses) #endif // QT3DCORE_SQT_P_H |