diff options
Diffstat (limited to 'src/runtime')
-rw-r--r-- | src/runtime/q3dsscenemanager.cpp | 54 | ||||
-rw-r--r-- | src/runtime/q3dsscenemanager_p.h | 6 | ||||
-rw-r--r-- | src/runtime/q3dsslideplayer.cpp | 92 | ||||
-rw-r--r-- | src/runtime/q3dsslideplayer_p.h | 3 | ||||
-rw-r--r-- | src/runtime/q3dsuippresentation.cpp | 1 | ||||
-rw-r--r-- | src/runtime/q3dsuippresentation_p.h | 7 |
6 files changed, 89 insertions, 74 deletions
diff --git a/src/runtime/q3dsscenemanager.cpp b/src/runtime/q3dsscenemanager.cpp index 5e113a2..c39f720 100644 --- a/src/runtime/q3dsscenemanager.cpp +++ b/src/runtime/q3dsscenemanager.cpp @@ -524,29 +524,31 @@ void Q3DSSceneManager::updateSizes(const QSize &size, qreal dpr, const QRect &vi }); } -void Q3DSSceneManager::setCurrentSlide(Q3DSSlide *newSlide, bool fromSlidePlayer) +void Q3DSSceneManager::setCurrentSlide(Q3DSSlide *newSlide, bool flush) { + // NOTE: m_currentSlide is update from the slide player... if (m_currentSlide == newSlide) return; - // TODO: Workaround to keep the slide test working... - if (!fromSlidePlayer) { - const int index = m_slidePlayer->slideDeck()->indexOfSlide(newSlide); - m_slidePlayer->slideDeck()->setCurrentSlide(index); - return; + const int index = m_slidePlayer->slideDeck()->indexOfSlide(newSlide); + Q_ASSERT(index != -1); + m_slidePlayer->slideDeck()->setCurrentSlide(index); + if (flush || m_slidePlayer->state() != Q3DSSlidePlayer::PlayerState::Playing) { + m_slidePlayer->setSlideTime(newSlide, 0.0f); + updateSubTree(m_scene); } - - qCDebug(lcScene, "Setting new current slide %s", newSlide->id().constData()); - m_currentSlide = newSlide; } -void Q3DSSceneManager::setComponentCurrentSlide(Q3DSComponentNode *component, Q3DSSlide *newSlide) +void Q3DSSceneManager::setComponentCurrentSlide(Q3DSSlide *newSlide, bool flush) { - Q3DSSlideAttached *data = component->masterSlide()->attached<Q3DSSlideAttached>(); + Q3DSSlideAttached *data = newSlide->attached<Q3DSSlideAttached>(); const int index = data->slidePlayer->slideDeck()->indexOfSlide(newSlide); Q_ASSERT(index != -1); data->slidePlayer->slideDeck()->setCurrentSlide(index); - qCDebug(lcScene, "Setting new current slide %s for component %s", newSlide->id().constData(), component->id().constData()); + if (flush || data->slidePlayer->state() != Q3DSSlidePlayer::PlayerState::Playing) { + data->slidePlayer->setSlideTime(newSlide, 0.0f); + updateSubTree(m_scene); + } } void Q3DSSceneManager::setLayerCaching(bool enabled) @@ -637,7 +639,7 @@ Q3DSSceneManager::Scene Q3DSSceneManager::buildScene(Q3DSUipPresentation *presen m_scene = m_presentation->scene(); m_masterSlide = m_presentation->masterSlide(); m_currentSlide = nullptr; - m_pendingNodeVisibility.clear(); + m_pendingObjectVisibility.clear(); m_pendingSubPresLayers.clear(); m_pendingSubPresImages.clear(); m_subPresentations.clear(); @@ -1923,7 +1925,7 @@ Q3DSCameraNode *Q3DSSceneManager::findFirstCamera(Q3DSLayerNode *layer3DS) if (obj->type() == Q3DSGraphObject::Camera) { Q3DSCameraNode *cam = static_cast<Q3DSCameraNode *>(obj); // ### should use globalVisibility (which is only set in buildLayerCamera first...) - const bool active = cam->flags().testFlag(Q3DSNode::Active);; + const bool active = (cam->attached() && cam->attached()->visibilityTag == Q3DSGraphObjectAttached::Visible); if (active) { // Check if camera is on the current slide Q3DSComponentNode *component = cam->attached() ? cam->attached()->component : nullptr; @@ -3188,7 +3190,7 @@ void Q3DSSceneManager::buildLayerQuadEntity(Q3DSLayerNode *layer3DS, Qt3DCore::Q Qt3DCore::QEntity *layerQuadEntity = new Qt3DCore::QEntity(parentEntity); layerQuadEntity->setObjectName(QObject::tr("compositor for %1").arg(QString::fromUtf8(layer3DS->id()))); data->compositorEntity = layerQuadEntity; - if (!layer3DS->flags().testFlag(Q3DSNode::Active)) + if (layer3DS->attached()->visibilityTag == Q3DSGraphObjectAttached::Hidden) layerQuadEntity->setEnabled(false); // QPlaneMesh works here because the compositor shader is provided by @@ -5522,7 +5524,7 @@ void Q3DSSceneManager::updateEffectStatus(Q3DSLayerNode *layer3DS) for (int i = 0; i < count; ++i) { Q3DSEffectInstance *eff3DS = layerData->effectData.effects[i]; Q3DSEffectAttached *effData = static_cast<Q3DSEffectAttached *>(eff3DS->attached()); - if (eff3DS->active()) { + if (effData->visibilityTag == Q3DSGraphObjectAttached::Visible) { ++activeEffectCount; if (activeEffectCount == 1) firstActiveIndex = i; @@ -5559,7 +5561,7 @@ void Q3DSSceneManager::updateEffectStatus(Q3DSLayerNode *layer3DS) Qt3DRender::QAbstractTexture *prevOutput = nullptr; for (int i = 0; i < count; ++i) { Q3DSEffectInstance *eff3DS = layerData->effectData.effects[i]; - if (eff3DS->active()) { + if (eff3DS->attached()->visibilityTag == Q3DSGraphObjectAttached::Visible) { Q3DSSceneManager::EffectActivationFlags flags = 0; if (i == firstActiveIndex) flags |= Q3DSSceneManager::EffIsFirst; @@ -6701,9 +6703,15 @@ void Q3DSSceneManager::updateSubTree(Q3DSGraphObject *obj) } } - for (auto it = m_pendingNodeVisibility.constBegin(); it != m_pendingNodeVisibility.constEnd(); ++it) - setNodeVisibility(it.key(), it.value()); - m_pendingNodeVisibility.clear(); + for (auto it = m_pendingObjectVisibility.constBegin(); it != m_pendingObjectVisibility.constEnd(); ++it) { + if (it.key()->isNode() && it.key()->type() != Q3DSGraphObject::Layer && it.key()->type() != Q3DSGraphObject::Camera) { + setNodeVisibility(static_cast<Q3DSNode *>(it.key()), it.value()); + } else { + // NOTE: Special handling for e.g., Camera, layers and effects. + it.key()->attached()->visibilityTag = (it.value() ? Q3DSGraphObjectAttached::Visible : Q3DSGraphObjectAttached::Hidden); + } + } + m_pendingObjectVisibility.clear(); } static Q3DSComponentNode *findNextComponentParent(Q3DSComponentNode *component) @@ -7084,7 +7092,7 @@ void Q3DSSceneManager::updateNodeFromChangeFlags(Q3DSNode *node, Qt3DCore::QTran // Drop whatever is queued since that was based on now-invalid // input. (important when entering slides, where eyball property // changes get processed after an initial visit of all objects) - m_pendingNodeVisibility.remove(node); + m_pendingObjectVisibility.remove(node); const bool active = node->flags().testFlag(Q3DSNode::Active); setNodeVisibility(node, active); @@ -7112,9 +7120,11 @@ void Q3DSSceneManager::setNodeVisibility(Q3DSNode *node, bool visible) return; if (!visible) { + data->visibilityTag = Q3DSGraphObjectAttached::Hidden; data->entity->removeComponent(layerData->opaqueTag); data->entity->removeComponent(layerData->transparentTag); } else { + data->visibilityTag = Q3DSGraphObjectAttached::Visible; if (node->type() != Q3DSGraphObject::Text) data->entity->addComponent(layerData->opaqueTag); data->entity->addComponent(layerData->transparentTag); @@ -7298,7 +7308,7 @@ void Q3DSSceneManager::changeSlideByName(Q3DSGraphObject *sceneOrComponent, cons if (targetSlide) { if (component) { if (m_currentSlide->objects().contains(component) || m_masterSlide->objects().contains(component)) - setComponentCurrentSlide(component, targetSlide); + setComponentCurrentSlide(targetSlide); else component->setCurrentSlide(targetSlide); } else { diff --git a/src/runtime/q3dsscenemanager_p.h b/src/runtime/q3dsscenemanager_p.h index fe6cf45..d563be2 100644 --- a/src/runtime/q3dsscenemanager_p.h +++ b/src/runtime/q3dsscenemanager_p.h @@ -666,8 +666,8 @@ public: Q3DSSlide *currentSlide() const { return m_currentSlide; } Q3DSSlide *masterSlide() const { return m_masterSlide; } - void setCurrentSlide(Q3DSSlide *slide, bool fromSlidePlayer = false); - void setComponentCurrentSlide(Q3DSComponentNode *component, Q3DSSlide *newSlide); + void setCurrentSlide(Q3DSSlide *slide, bool flush = false); + void setComponentCurrentSlide(Q3DSSlide *newSlide, bool flush = false); void setLayerCaching(bool enabled); @@ -869,7 +869,7 @@ private: Q3DSTextRenderer *m_textRenderer; QSet<Q3DSGraphObject *> m_subTreeWithDirtyLights; QSet<Q3DSDefaultMaterial *> m_pendingDefMatRebuild; - QHash<Q3DSNode *, bool> m_pendingNodeVisibility; + QHash<Q3DSGraphObject *, bool> m_pendingObjectVisibility; Qt3DRender::QLayer *m_fsQuadTag = nullptr; QStack<Q3DSComponentNode *> m_componentNodeStack; QSet<Q3DSLayerNode *> m_pendingSubPresLayers; diff --git a/src/runtime/q3dsslideplayer.cpp b/src/runtime/q3dsslideplayer.cpp index 48b3ef1..9e4b142 100644 --- a/src/runtime/q3dsslideplayer.cpp +++ b/src/runtime/q3dsslideplayer.cpp @@ -695,10 +695,8 @@ void Q3DSSlidePlayer::handleCurrentSlideChanged(Q3DSSlide *slide, }); }; if (previousSlide && slideDidChange) { - if (parentChanged) { + if (parentChanged) cleanUpComponentPlayers(static_cast<Q3DSSlide *>(previousSlide->parent())); - setSlideTime(static_cast<Q3DSSlide *>(previousSlide->parent()), -1.0f); - } setSlideTime(previousSlide, -1.0f); cleanUpComponentPlayers(previousSlide); Q3DSSlideAttached *data = previousSlide->attached<Q3DSSlideAttached>(); @@ -714,10 +712,8 @@ void Q3DSSlidePlayer::handleCurrentSlideChanged(Q3DSSlide *slide, if (slide && slideDidChange && isSlideVisible(slide)) { processPropertyChanges(slide); attatchPositionCallback(slide); - m_animationManager->updateAnimations(slide, (m_mode == PlayerMode::Editor)); - if (parentChanged) - setSlideTime(static_cast<Q3DSSlide *>(slide->parent()), 0.0f); setSlideTime(slide, 0.0f); + m_animationManager->updateAnimations(slide, (m_mode == PlayerMode::Editor)); Q3DSGraphObject *eventTarget = m_sceneManager->m_scene; if (m_type != PlayerType::Slide) @@ -745,7 +741,7 @@ void Q3DSSlidePlayer::handleCurrentSlideChanged(Q3DSSlide *slide, // A bit crude, but whatever if (m_type == PlayerType::Slide) - m_sceneManager->setCurrentSlide(slide, true); + m_sceneManager->m_currentSlide = slide; else m_component->setCurrentSlide(slide); @@ -791,6 +787,9 @@ static bool objectHasVisibilityTag(Q3DSGraphObject *object) if (!entity) return false; + if (object->type() == Q3DSGraphObject::Camera || object->type() == Q3DSGraphObject::Layer || object->type() == Q3DSGraphObject::Effect) + return (object->attached()->visibilityTag == Q3DSGraphObjectAttached::Visible); + auto layerAttached = static_cast<Q3DSLayerAttached *>(object->isNode() ? object->attached<Q3DSNodeAttached>()->layer3DS->attached() : object->attached<Q3DSEffectAttached>()->layer3DS->attached()); if (entity->components().contains(layerAttached->opaqueTag) || entity->components().contains(layerAttached->transparentTag)) @@ -806,28 +805,37 @@ void Q3DSSlidePlayer::setSlideTime(Q3DSSlide *slide, float time, bool parentVisi // slide changes const bool forceUpdate = parentVisible && (qFuzzyCompare(time, 0.0f) || qFuzzyCompare(time, -1.0f)); - for (Q3DSGraphObject *obj : slide->objects()) { - if (obj->state() != Q3DSGraphObject::Enabled) - continue; + const auto updateObjects = [=](Q3DSSlide *s) { + if (!s) + return; - const bool isEffect = (obj->type() == Q3DSGraphObject::Effect); - if ((!obj->isNode() && !isEffect) || obj->type() == Q3DSGraphObject::Camera || obj->type() == Q3DSGraphObject::Layer) - continue; + for (Q3DSGraphObject *obj : s->objects()) { + if (obj->state() != Q3DSGraphObject::Enabled) + continue; - Q3DSNode *node = obj->isNode() ? static_cast<Q3DSNode *>(obj) : nullptr; - if (node && !node->attached()) - continue; + const bool isEffect = (obj->type() == Q3DSGraphObject::Effect); + if ((!obj->isNode() && !isEffect)) + continue; - const bool nodeActive = (node && node->flags().testFlag(Q3DSNode::Active) && node->attached<Q3DSNodeAttached>()->globalVisibility); - const bool effectActive = isEffect && static_cast<Q3DSEffectInstance *>(obj)->active(); + const bool isRealNode = (obj->isNode() && obj->type() != Q3DSGraphObject::Layer && obj->type() != Q3DSGraphObject::Camera); + Q3DSNode *node = isRealNode ? static_cast<Q3DSNode *>(obj) : nullptr; + if (node && !node->attached()) + continue; - const bool shouldBeVisible = parentVisible - && time >= obj->startTime() && time <= obj->endTime() - && (nodeActive || effectActive); + const bool nodeActive = (node && node->flags().testFlag(Q3DSNode::Active) && node->attached<Q3DSNodeAttached>()->globalVisibility); + const bool otherActive = !node && (obj->attached()->visibilityTag == Q3DSGraphObjectAttached::Visible); - if (forceUpdate || shouldBeVisible != objectHasVisibilityTag(obj)) - updateObjectVisibility(obj, shouldBeVisible); - } + const bool shouldBeVisible = parentVisible + && time >= obj->startTime() && time <= obj->endTime() + && (nodeActive || otherActive); + + if (forceUpdate || shouldBeVisible != objectHasVisibilityTag(obj)) + updateObjectVisibility(obj, shouldBeVisible); + } + }; + + updateObjects(static_cast<Q3DSSlide *>(slide->parent())); + updateObjects(slide); // This method is called for all slides, but we only want to update the // position for the associated slide player once @@ -863,26 +871,16 @@ void Q3DSSlidePlayer::sendPositionChanged(Q3DSSlide *slide, float pos) void Q3DSSlidePlayer::updateObjectVisibility(Q3DSGraphObject *obj, bool shouldBeVisible) { Q_ASSERT(obj->isNode() || obj->type() == Q3DSGraphObject::Effect); - if (obj->isNode()) { - Q3DSNode *node = static_cast<Q3DSNode *>(obj); - auto foundIt = m_sceneManager->m_pendingNodeVisibility.find(node); - const bool insertValue = (foundIt == m_sceneManager->m_pendingNodeVisibility.end()); - const bool updateValue = (!insertValue && foundIt.value() != shouldBeVisible); - - if (insertValue || updateValue) { - qCDebug(lcSlidePlayer, "Scheduling node \"%s\" to be %s", obj->id().constData(), shouldBeVisible ? "shown" : "hidden"); - if (updateValue) - *foundIt = shouldBeVisible; - else if (insertValue) - m_sceneManager->m_pendingNodeVisibility.insert(node, shouldBeVisible); - } - } else { - Q3DSEffectInstance *effect = static_cast<Q3DSEffectInstance *>(obj); - if (effect->active() != shouldBeVisible) { - qCDebug(lcSlidePlayer, "Scheduling effect \"%s\" to be %s", obj->id().constData(), shouldBeVisible ? "shown" : "hidden"); - obj->applyPropertyChanges(Q3DSPropertyChangeList({Q3DSPropertyChange::fromVariant(QLatin1String("eyeball"), QVariant::fromValue(shouldBeVisible))})); - obj->notifyPropertyChanges(Q3DSPropertyChangeList({Q3DSPropertyChange::fromVariant(QLatin1String("eyeball"), QVariant::fromValue(shouldBeVisible))})); - } + auto foundIt = m_sceneManager->m_pendingObjectVisibility.find(obj); + const bool insertValue = (foundIt == m_sceneManager->m_pendingObjectVisibility.end()); + const bool updateValue = (!insertValue && foundIt.value() != shouldBeVisible); + + if (insertValue || updateValue) { + qCDebug(lcSlidePlayer, "Scheduling object \"%s\" to be %s", obj->id().constData(), shouldBeVisible ? "shown" : "hidden"); + if (updateValue) + *foundIt = shouldBeVisible; + else if (insertValue) + m_sceneManager->m_pendingObjectVisibility.insert(obj, shouldBeVisible); } } @@ -940,7 +938,7 @@ void Q3DSSlidePlayer::processPropertyChanges(Q3DSSlide *currentSlide) if (currentSlide->parent()) { Q3DSSlide *parent = static_cast<Q3DSSlide *>(currentSlide->parent()); const auto &objects = parent->objects(); - std::find_if(objects.constBegin(), objects.constEnd(), [this](Q3DSGraphObject *object){ + std::find_if(objects.constBegin(), objects.constEnd(), [](Q3DSGraphObject *object){ if (object->state() != Q3DSGraphObject::Enabled) return false; @@ -961,10 +959,10 @@ void Q3DSSlidePlayer::processPropertyChanges(Q3DSSlide *currentSlide) // Filter out properties that we needs to be marked dirty, i.e., eyeball changes. const auto &propertyChanges = currentSlide->propertyChanges(); for (auto it = propertyChanges.cbegin(); it != propertyChanges.cend(); ++it) { + it.key()->applyPropertyChanges(*it.value()); std::find_if((*it)->cbegin(), (*it)->cend(), [it](const Q3DSPropertyChange &propChange) { - it.key()->applyPropertyChanges(*it.value()); if (propChange.name() == QLatin1String("eyeball")) - it.key()->notifyPropertyChanges(*it.value()); + it.key()->notifyPropertyChanges(Q3DSPropertyChangeList({propChange})); return false; }); diff --git a/src/runtime/q3dsslideplayer_p.h b/src/runtime/q3dsslideplayer_p.h index 2b0fdbc..1a7e29d 100644 --- a/src/runtime/q3dsslideplayer_p.h +++ b/src/runtime/q3dsslideplayer_p.h @@ -136,13 +136,13 @@ private: void setInternalState(PlayerState state); void onDurationChanged(float duration); void onSlideFinished(Q3DSSlide *slide); + void setSlideTime(Q3DSSlide *slide, float time, bool parentVisible = true); void handleCurrentSlideChanged(Q3DSSlide *slide, Q3DSSlide *previousSlide, bool forceUpdate = false); // TODO: Move out to a "slide manager"? - void setSlideTime(Q3DSSlide *slide, float time, bool parentVisible = true); void sendPositionChanged(Q3DSSlide *slide, float pos); void updateObjectVisibility(Q3DSGraphObject *obj, bool visible); bool isSlideVisible(Q3DSSlide *slide); @@ -166,6 +166,7 @@ private: // This class handles animation callback from animationmanager and calls setSlideTime friend class Q3DSSlidePositionCallback; + friend class Q3DSSceneManager; }; class Q3DSV_PRIVATE_EXPORT Q3DSSlideDeck diff --git a/src/runtime/q3dsuippresentation.cpp b/src/runtime/q3dsuippresentation.cpp index f6ee5f2..b4a7aab 100644 --- a/src/runtime/q3dsuippresentation.cpp +++ b/src/runtime/q3dsuippresentation.cpp @@ -3387,7 +3387,6 @@ void Q3DSComponentNode::setCurrentSlide(Q3DSSlide *slide) if (m_currentSlide == slide) return; - qCDebug(lcUip, "Setting new current slide %s", slide->id().constData()); m_currentSlide = slide; } diff --git a/src/runtime/q3dsuippresentation_p.h b/src/runtime/q3dsuippresentation_p.h index 8ed44f7..abffb8a 100644 --- a/src/runtime/q3dsuippresentation_p.h +++ b/src/runtime/q3dsuippresentation_p.h @@ -184,6 +184,12 @@ public: Qt3DCore::QEntity *entity = nullptr; Q3DSComponentNode *component = nullptr; + enum VisibilityTag + { + Visible, + Hidden + }; + enum FrameDirtyFlag { GroupDirty = 0x01, LightDirty = 0x02, @@ -204,6 +210,7 @@ public: }; Q_DECLARE_FLAGS(FrameDirtyFlags, FrameDirtyFlag) + VisibilityTag visibilityTag = Visible; FrameDirtyFlags frameDirty; int frameChangeFlags = 0; }; |