diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-09-30 10:47:48 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-09-30 17:04:45 +0100 |
commit | 9c951154256734b36328142e1078382dc2d7ae01 (patch) | |
tree | 60bf432a557511b0a08b2f2dfff8276065e59150 /src | |
parent | 205ba7689c3c6c547543cf4d5d7ec968cce9a7a5 (diff) | |
parent | aee10edf33ccb1faf3179b23b44a2ad48bf4d0f0 (diff) |
Merge branch '5.9' into 5.10
Conflicts:
src/animation/backend/animationutils.cpp
src/animation/backend/animationutils_p.h
src/render/geometry/qmesh.cpp
tests/auto/animation/animation.pro
Change-Id: Ifb57bfb0b12b3ebf9ee177d4ea684134455b4143
Diffstat (limited to 'src')
-rw-r--r-- | src/animation/backend/animationutils.cpp | 78 | ||||
-rw-r--r-- | src/animation/backend/animationutils_p.h | 5 | ||||
-rw-r--r-- | src/animation/backend/channelmapper.cpp | 20 | ||||
-rw-r--r-- | src/animation/backend/channelmapper_p.h | 12 | ||||
-rw-r--r-- | src/animation/backend/clipanimator.cpp | 1 | ||||
-rw-r--r-- | src/animation/backend/clipanimator_p.h | 4 | ||||
-rw-r--r-- | src/animation/backend/clipblendvalue_p.h | 2 | ||||
-rw-r--r-- | src/animation/backend/evaluateclipanimatorjob.cpp | 11 | ||||
-rw-r--r-- | src/animation/backend/findrunningclipanimatorsjob.cpp | 41 | ||||
-rw-r--r-- | src/animation/backend/findrunningclipanimatorsjob_p.h | 10 | ||||
-rw-r--r-- | src/plugins/geometryloaders/default/objgeometryloader.cpp | 2 | ||||
-rw-r--r-- | src/render/frontend/qrendersettings.cpp | 5 | ||||
-rw-r--r-- | src/render/texture/gltexture.cpp | 1 |
13 files changed, 100 insertions, 92 deletions
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp index f421a8025..4e90d3c1d 100644 --- a/src/animation/backend/animationutils.cpp +++ b/src/animation/backend/animationutils.cpp @@ -342,65 +342,6 @@ QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> & return callbacks; } -//TODO: Remove this and use new implementation below for both the unblended -// and blended animation cases. -QVector<MappingData> buildPropertyMappings(Handler *handler, - const AnimationClip *clip, - const ChannelMapper *mapper) -{ - QVector<MappingData> mappingDataVec; - ChannelMappingManager *mappingManager = handler->channelMappingManager(); - const QVector<Channel> &channels = clip->channels(); - - // Iterate over the mappings in the mapper object - const auto mappingIds = mapper->mappingIds(); - for (const Qt3DCore::QNodeId mappingId : mappingIds) { - // Get the mapping object - ChannelMapping *mapping = mappingManager->lookupResource(mappingId); - Q_ASSERT(mapping); - - // Populate the data we need, easy stuff first - MappingData mappingData; - mappingData.targetId = mapping->targetId(); - mappingData.propertyName = mapping->propertyName(); - mappingData.type = mapping->type(); - mappingData.callback = mapping->callback(); - mappingData.callbackFlags = mapping->callbackFlags(); - - if (mappingData.type == static_cast<int>(QVariant::Invalid)) { - qWarning() << "Unknown type for node id =" << mappingData.targetId - << "and property =" << mapping->property() - << "and callback =" << mapping->callback(); - continue; - } - - // Now the tricky part. Mapping the channel indices onto the property type. - // Try to find a ChannelGroup with matching name - const QString channelName = mapping->channelName(); - int channelGroupIndex = 0; - bool foundMatch = false; - for (const Channel &channel : channels) { - if (channel.name == channelName) { - foundMatch = true; - const int channelBaseIndex = clip->channelComponentBaseIndex(channelGroupIndex); - - // Within this group, match channel names with index ordering - mappingData.channelIndices = channelComponentsToIndices(channel, mappingData.type, channelBaseIndex); - - // Store the mapping data - mappingDataVec.push_back(mappingData); - - if (foundMatch) - break; - } - - ++channelGroupIndex; - } - } - - return mappingDataVec; -} - QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &channelMappings, const QVector<ChannelNameAndType> &channelNamesAndTypes, const QVector<ComponentIndices> &channelComponentIndices) @@ -539,6 +480,10 @@ QVector<Qt3DCore::QNodeId> gatherValueNodesToEvaluate(Handler *handler, ClipBlendNodeVisitor::VisitOnlyDependencies); auto func = [&clipIds, nodeManager] (ClipBlendNode *blendNode) { + // Check if this is a value node itself + if (blendNode->blendType() == ClipBlendNode::ValueType) + clipIds.append(blendNode->peerId()); + const auto dependencyIds = blendNode->currentDependencyIds(); for (const auto dependencyId : dependencyIds) { // Look up the blend node and if it's a value type (clip), @@ -565,12 +510,11 @@ ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &ta // Reserve enough storage for all the format indices int indexCount = 0; - for (const auto targetIndexVec : qAsConst(targetIndices)) + for (const auto &targetIndexVec : qAsConst(targetIndices)) indexCount += targetIndexVec.size(); ComponentIndices format; format.resize(indexCount); - // Iterate through the target channels const int channelCount = targetChannels.size(); auto formatIt = format.begin(); @@ -579,18 +523,18 @@ ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &ta const ChannelNameAndType &targetChannel = targetChannels[i]; const int clipChannelIndex = clip->channelIndex(targetChannel.name, targetChannel.jointIndex); - - // TODO: Ensure channel in the clip has enough components to map to the type. - // Requires some improvements to the clip data structure first. - // TODO: I don't think we need the targetIndices, only the number of components - // for each target channel. Check once blend tree is complete. const int componentCount = targetIndices[i].size(); if (clipChannelIndex != -1) { // Found a matching channel in the clip. Get the base channel // component index and populate the format indices for this channel. const int baseIndex = clip->channelComponentBaseIndex(clipChannelIndex); - std::iota(formatIt, formatIt + componentCount, baseIndex); + + // Within this group, match channel names with index ordering + const auto channelIndices = channelComponentsToIndices(clip->channels()[clipChannelIndex], + targetChannel.type, + baseIndex); + std::copy(channelIndices.begin(), channelIndices.end(), formatIt); } else { // No such channel in this clip. We'll use default values when diff --git a/src/animation/backend/animationutils_p.h b/src/animation/backend/animationutils_p.h index 7fcd9ead5..cf21c448d 100644 --- a/src/animation/backend/animationutils_p.h +++ b/src/animation/backend/animationutils_p.h @@ -190,11 +190,6 @@ QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> & const QVector<float> &channelResults); Q_AUTOTEST_EXPORT -QVector<MappingData> buildPropertyMappings(Handler *handler, - const AnimationClip *clip, - const ChannelMapper *mapper); - -Q_AUTOTEST_EXPORT QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping *> &channelMappings, const QVector<ChannelNameAndType> &channelNamesAndTypes, const QVector<ComponentIndices> &channelComponentIndices); diff --git a/src/animation/backend/channelmapper.cpp b/src/animation/backend/channelmapper.cpp index 0e5555096..48a1335fa 100644 --- a/src/animation/backend/channelmapper.cpp +++ b/src/animation/backend/channelmapper.cpp @@ -38,6 +38,7 @@ #include <Qt3DAnimation/qchannelmapper.h> #include <Qt3DAnimation/private/qchannelmapper_p.h> #include <Qt3DAnimation/private/animationlogging_p.h> +#include <Qt3DAnimation/private/managers_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> #include <Qt3DCore/qpropertynodeaddedchange.h> #include <Qt3DCore/qpropertynoderemovedchange.h> @@ -50,6 +51,7 @@ namespace Animation { ChannelMapper::ChannelMapper() : BackendNode(ReadOnly) , m_mappingIds() + , m_isDirty(true) { } @@ -58,12 +60,15 @@ void ChannelMapper::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QChannelMapperData>>(change); const auto &data = typedChange->data; m_mappingIds = data.mappingIds; + m_isDirty = true; } void ChannelMapper::cleanup() { setEnabled(false); m_mappingIds.clear(); + m_mappings.clear(); + m_isDirty = true; } void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) @@ -74,6 +79,7 @@ void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) if (change->propertyName() == QByteArrayLiteral("mappings")) { m_mappingIds.push_back(change->addedNodeId()); setDirty(Handler::ChannelMappingsDirty); + m_isDirty = true; } break; } @@ -83,6 +89,7 @@ void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) if (change->propertyName() == QByteArrayLiteral("mappings")) { m_mappingIds.removeOne(change->removedNodeId()); setDirty(Handler::ChannelMappingsDirty); + m_isDirty = true; } break; } @@ -93,6 +100,19 @@ void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) QBackendNode::sceneChangeEvent(e); } +void ChannelMapper::updateMappings() const +{ + m_mappings.clear(); + m_mappings.reserve(m_mappingIds.size()); + const auto mappingManager = m_handler->channelMappingManager(); + for (const auto &mappingId : m_mappingIds) { + const auto mapping = mappingManager->lookupResource(mappingId); + Q_ASSERT(mapping); + m_mappings.push_back(mapping); + } + m_isDirty = false; +} + } // namespace Animation } // namespace Qt3DAnimation diff --git a/src/animation/backend/channelmapper_p.h b/src/animation/backend/channelmapper_p.h index 710de01ab..8d8f03511 100644 --- a/src/animation/backend/channelmapper_p.h +++ b/src/animation/backend/channelmapper_p.h @@ -74,10 +74,22 @@ public: void setMappingIds(const QVector<Qt3DCore::QNodeId> &mappingIds) { m_mappingIds = mappingIds; } QVector<Qt3DCore::QNodeId> mappingIds() const { return m_mappingIds; } + QVector<ChannelMapping*> mappings() const + { + if (m_isDirty) + updateMappings(); + return m_mappings; + } + private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; + void updateMappings() const; QVector<Qt3DCore::QNodeId> m_mappingIds; + + // Cached data + mutable QVector<ChannelMapping*> m_mappings; + mutable bool m_isDirty; }; } // namespace Animation diff --git a/src/animation/backend/clipanimator.cpp b/src/animation/backend/clipanimator.cpp index 2f4dca63f..568e2dbb0 100644 --- a/src/animation/backend/clipanimator.cpp +++ b/src/animation/backend/clipanimator.cpp @@ -114,6 +114,7 @@ void ClipAnimator::cleanup() m_clockId = Qt3DCore::QNodeId(); m_running = false; m_loops = 1; + m_formatIndices.clear(); } void ClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) diff --git a/src/animation/backend/clipanimator_p.h b/src/animation/backend/clipanimator_p.h index b3389f8da..8a08969ba 100644 --- a/src/animation/backend/clipanimator_p.h +++ b/src/animation/backend/clipanimator_p.h @@ -97,6 +97,9 @@ public: void animationClipMarkedDirty() { setDirty(Handler::ClipAnimatorDirty); } + void setFormatIndices(const ComponentIndices &formatIndices) { m_formatIndices = formatIndices; } + ComponentIndices formatIndices() const { return m_formatIndices; } + private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; @@ -111,6 +114,7 @@ private: QVector<MappingData> m_mappingData; int m_currentLoop; + ComponentIndices m_formatIndices; }; } // namespace Animation diff --git a/src/animation/backend/clipblendvalue_p.h b/src/animation/backend/clipblendvalue_p.h index 6da800f98..5ff8d2b0f 100644 --- a/src/animation/backend/clipblendvalue_p.h +++ b/src/animation/backend/clipblendvalue_p.h @@ -73,7 +73,7 @@ public: inline QVector<Qt3DCore::QNodeId> currentDependencyIds() const Q_DECL_OVERRIDE { - return { m_clipId }; + return {}; } double duration() const Q_DECL_OVERRIDE; diff --git a/src/animation/backend/evaluateclipanimatorjob.cpp b/src/animation/backend/evaluateclipanimatorjob.cpp index 6dab51d63..d9600c375 100644 --- a/src/animation/backend/evaluateclipanimatorjob.cpp +++ b/src/animation/backend/evaluateclipanimatorjob.cpp @@ -70,7 +70,11 @@ void EvaluateClipAnimatorJob::run() // Prepare for evaluation (convert global time to local time ....) const AnimatorEvaluationData animatorEvaluationData = evaluationDataForAnimator(clipAnimator, clock, globalTime); const ClipEvaluationData preEvaluationDataForClip = evaluationDataForClip(clip, animatorEvaluationData); - const ClipResults channelResults = evaluateClipAtLocalTime(clip, preEvaluationDataForClip.localTime); + const ClipResults rawClipResults = evaluateClipAtLocalTime(clip, preEvaluationDataForClip.localTime); + + // Reformat the clip results into the layout used by this animator/blend tree + ComponentIndices format = clipAnimator->formatIndices(); + ClipResults formattedClipResults = formatClipResults(rawClipResults, format); if (preEvaluationDataForClip.isFinalFrame) clipAnimator->setRunning(false); @@ -80,14 +84,15 @@ void EvaluateClipAnimatorJob::run() // Prepare property changes (if finalFrame it also prepares the change for the running property for the frontend) const QVector<Qt3DCore::QSceneChangePtr> changes = preparePropertyChanges(clipAnimator->peerId(), clipAnimator->mappingData(), - channelResults, + formattedClipResults, preEvaluationDataForClip.isFinalFrame); // Send the property changes clipAnimator->sendPropertyChanges(changes); // Trigger callbacks either on this thread or by notifying the gui thread. - const QVector<AnimationCallbackAndValue> callbacks = prepareCallbacks(clipAnimator->mappingData(), channelResults); + const QVector<AnimationCallbackAndValue> callbacks = prepareCallbacks(clipAnimator->mappingData(), + formattedClipResults); clipAnimator->sendCallbacks(callbacks); } diff --git a/src/animation/backend/findrunningclipanimatorsjob.cpp b/src/animation/backend/findrunningclipanimatorsjob.cpp index a8349eb91..41454004d 100644 --- a/src/animation/backend/findrunningclipanimatorsjob.cpp +++ b/src/animation/backend/findrunningclipanimatorsjob.cpp @@ -62,24 +62,39 @@ void FindRunningClipAnimatorsJob::run() Q_ASSERT(m_handler); ClipAnimatorManager *clipAnimatorManager = m_handler->clipAnimatorManager(); - for (const auto clipAnimatorHandle : qAsConst(m_clipAnimatorHandles)) { + for (const auto &clipAnimatorHandle : qAsConst(m_clipAnimatorHandles)) { ClipAnimator *clipAnimator = clipAnimatorManager->data(clipAnimatorHandle); Q_ASSERT(clipAnimator); const bool canRun = clipAnimator->canRun(); m_handler->setClipAnimatorRunning(clipAnimatorHandle, canRun); - // The clip animator needs to know how to map fcurve values through to - // properties on QNodes. Now we know this animator can run, build the mapping - // table. - // TODO: Should be possible to parallelise this with the fcurve evaluation as - // sending the property change events doesn't happen until after evaluation - if (canRun) { - const AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipAnimator->clipId()); - const ChannelMapper *mapper = m_handler->channelMapperManager()->lookupResource(clipAnimator->mapperId()); - Q_ASSERT(clip && mapper); - const QVector<MappingData> mappingData = buildPropertyMappings(m_handler, clip, mapper); - clipAnimator->setMappingData(mappingData); - } + if (!canRun) + continue; + + // The clip animator needs to know how to map fcurve values through to properties on QNodes. + // Now we know this animator can run, build the mapping table. Even though this could be + // done a little simpler in the non-blended case, we follow the same code path as the + // blended clip animator for consistency and ease of maintenance. + const ChannelMapper *mapper = m_handler->channelMapperManager()->lookupResource(clipAnimator->mapperId()); + Q_ASSERT(mapper); + const QVector<ChannelMapping *> channelMappings = mapper->mappings(); + + const QVector<ChannelNameAndType> channelNamesAndTypes + = buildRequiredChannelsAndTypes(m_handler, mapper); + const QVector<ComponentIndices> channelComponentIndices + = assignChannelComponentIndices(channelNamesAndTypes); + + const AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipAnimator->clipId()); + Q_ASSERT(clip); + const ComponentIndices formatIndices = generateClipFormatIndices(channelNamesAndTypes, + channelComponentIndices, + clip); + clipAnimator->setFormatIndices(formatIndices); + + const QVector<MappingData> mappingData = buildPropertyMappings(channelMappings, + channelNamesAndTypes, + channelComponentIndices); + clipAnimator->setMappingData(mappingData); } qCDebug(Jobs) << "Running clip animators =" << m_handler->runningClipAnimators(); diff --git a/src/animation/backend/findrunningclipanimatorsjob_p.h b/src/animation/backend/findrunningclipanimatorsjob_p.h index 023f46303..f8b09939f 100644 --- a/src/animation/backend/findrunningclipanimatorsjob_p.h +++ b/src/animation/backend/findrunningclipanimatorsjob_p.h @@ -52,6 +52,10 @@ #include <Qt3DAnimation/private/handle_types_p.h> #include <QtCore/qvector.h> +#if defined(QT_BUILD_INTERNAL) +class tst_FindRunningClipAnimatorsJob; +#endif + QT_BEGIN_NAMESPACE namespace Qt3DAnimation { @@ -59,7 +63,7 @@ namespace Animation { class Handler; -class FindRunningClipAnimatorsJob : public Qt3DCore::QAspectJob +class Q_AUTOTEST_EXPORT FindRunningClipAnimatorsJob : public Qt3DCore::QAspectJob { public: FindRunningClipAnimatorsJob(); @@ -75,6 +79,10 @@ protected: private: QVector<HClipAnimator> m_clipAnimatorHandles; Handler *m_handler; + +#if defined(QT_BUILD_INTERNAL) + friend class ::tst_FindRunningClipAnimatorsJob; +#endif }; } // namespace Animation diff --git a/src/plugins/geometryloaders/default/objgeometryloader.cpp b/src/plugins/geometryloaders/default/objgeometryloader.cpp index b1fb1f931..7184e2f69 100644 --- a/src/plugins/geometryloaders/default/objgeometryloader.cpp +++ b/src/plugins/geometryloaders/default/objgeometryloader.cpp @@ -144,7 +144,7 @@ bool ObjGeometryLoader::doLoad(QIODevice *ioDev, const QString &subMesh) ++normalsOffset; } } - } else if (!skipping && qstrncmp(tokens.charPtrAt(0), "f ", 2) == 0) { + } else if (!skipping && tokens.size() >= 4 && qstrncmp(tokens.charPtrAt(0), "f ", 2) == 0) { // Process face ++faceCount; diff --git a/src/render/frontend/qrendersettings.cpp b/src/render/frontend/qrendersettings.cpp index 4212897ab..23f88eb10 100644 --- a/src/render/frontend/qrendersettings.cpp +++ b/src/render/frontend/qrendersettings.cpp @@ -217,8 +217,11 @@ void QRenderSettings::setActiveFrameGraph(QFrameGraphNode *activeFrameGraph) if (d->m_activeFrameGraph && activeFrameGraph) { Qt3DRender::QRenderSurfaceSelector *oldSurfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(d->m_activeFrameGraph); Qt3DRender::QRenderSurfaceSelector *newSurfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(activeFrameGraph); - if (oldSurfaceSelector && newSurfaceSelector && oldSurfaceSelector->surface()) + if (oldSurfaceSelector && newSurfaceSelector && oldSurfaceSelector->surface()) { + newSurfaceSelector->setExternalRenderTargetSize(oldSurfaceSelector->externalRenderTargetSize()); + newSurfaceSelector->setSurfacePixelRatio(oldSurfaceSelector->surfacePixelRatio()); newSurfaceSelector->setSurface(oldSurfaceSelector->surface()); + } } if (d->m_activeFrameGraph) diff --git a/src/render/texture/gltexture.cpp b/src/render/texture/gltexture.cpp index 2a35a6f7e..11cc1544f 100644 --- a/src/render/texture/gltexture.cpp +++ b/src/render/texture/gltexture.cpp @@ -208,6 +208,7 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture() // need to (re-)upload texture data? if (needUpload && !texturedDataInvalid) { uploadGLTextureData(); + setDirtyFlag(TextureData, false); } // need to set texture parameters? |