diff options
author | Mike Krus <mike.krus@kdab.com> | 2019-10-03 21:43:14 +0100 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2019-10-14 20:37:25 +0200 |
commit | fd85ebb1e24d48ffdff0659810a1830691bba89f (patch) | |
tree | 208bb83880601d4c5836b21a2f01a1f28498b8c4 /src | |
parent | da5a4af50076515abbf04691e8a5dfca5daaca9e (diff) |
Update PickBoundingVolumeJob to use direct sync
Change-Id: I7878294cd44872ccdc17515fbb44a6b2a99239e5
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/render/jobs/pickboundingvolumejob.cpp | 118 | ||||
-rw-r--r-- | src/render/jobs/pickboundingvolumejob_p.h | 3 | ||||
-rw-r--r-- | src/render/picking/objectpicker.cpp | 55 | ||||
-rw-r--r-- | src/render/picking/objectpicker_p.h | 7 | ||||
-rw-r--r-- | src/render/picking/qobjectpicker.cpp | 36 | ||||
-rw-r--r-- | src/render/picking/qobjectpicker.h | 3 | ||||
-rw-r--r-- | src/render/picking/qobjectpicker_p.h | 1 | ||||
-rw-r--r-- | src/render/picking/qpickevent_p.h | 4 |
8 files changed, 115 insertions, 112 deletions
diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index a88e861b6..9d8d3e491 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -41,7 +41,11 @@ #include "qpicktriangleevent.h" #include "qpicklineevent.h" #include "qpickpointevent.h" +#include <Qt3DCore/private/qaspectmanager_p.h> +#include <Qt3DRender/qobjectpicker.h> +#include <Qt3DRender/qviewport.h> #include <Qt3DRender/qgeometryrenderer.h> +#include <Qt3DRender/private/qobjectpicker_p.h> #include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/nodemanagers_p.h> #include <Qt3DRender/private/entity_p.h> @@ -65,6 +69,82 @@ using namespace Qt3DRender::RayCasting; namespace Render { +class PickBoundingVolumeJobPrivate : public Qt3DCore::QAspectJobPrivate +{ +public: + PickBoundingVolumeJobPrivate() = default; + ~PickBoundingVolumeJobPrivate() override = default; + + void postFrame(Qt3DCore::QAspectManager *manager) override; + + enum CustomEventType { + MouseButtonClick = QEvent::User, + }; + + struct EventDetails { + Qt3DCore::QNodeId pickerId; + int sourceEventType; + QPickEventPtr resultingEvent; + Qt3DCore::QNodeId viewportNodeId; + }; + + QVector<EventDetails> dispatches; +}; + + +void PickBoundingVolumeJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) +{ + using namespace Qt3DCore; + QNodeId previousId; + QObjectPicker *node = nullptr; + + for (auto res: qAsConst(dispatches)) { + if (previousId != res.pickerId) { + node = qobject_cast<QObjectPicker *>(manager->lookupNode(res.pickerId)); + previousId = res.pickerId; + } + if (!node) + continue; + + QObjectPickerPrivate *dnode = static_cast<QObjectPickerPrivate *>(QObjectPickerPrivate::get(node)); + + // resolve front end details + QPickEvent *pickEvent = res.resultingEvent.data(); + if (pickEvent) { + QPickEventPrivate *dpickEvent = QPickEventPrivate::get(pickEvent); + dpickEvent->m_viewport = static_cast<QViewport *>(manager->lookupNode(res.viewportNodeId)); + dpickEvent->m_entityPtr = static_cast<QEntity *>(manager->lookupNode(dpickEvent->m_entity)); + } + + // dispatch event + switch (res.sourceEventType) { + case QEvent::MouseButtonPress: + dnode->pressedEvent(pickEvent); + break; + case QEvent::MouseButtonRelease: + dnode->releasedEvent(pickEvent); + break; + case MouseButtonClick: + dnode->clickedEvent(pickEvent); + break; + case QEvent::MouseMove: + dnode->movedEvent(pickEvent); + break; + case QEvent::Enter: + emit node->entered(); + dnode->setContainsMouse(true); + break; + case QEvent::Leave: + dnode->setContainsMouse(false); + emit node->exited(); + break; + default: Q_UNREACHABLE(); + } + } + + dispatches.clear(); +} + namespace { void setEventButtonAndModifiers(const QMouseEvent &event, QPickEvent::Buttons &eventButton, int &eventButtons, int &eventModifiers) @@ -109,10 +189,10 @@ void setEventButtonAndModifiers(const QMouseEvent &event, QPickEvent::Buttons &e } // anonymous PickBoundingVolumeJob::PickBoundingVolumeJob() - : AbstractPickingJob() + : AbstractPickingJob(*new PickBoundingVolumeJobPrivate) , m_pickersDirty(true) { - SET_JOB_RUN_STAT_TYPE(this, JobTypes::PickBoundingVolume, 0); + SET_JOB_RUN_STAT_TYPE(this, JobTypes::PickBoundingVolume, 0) } void PickBoundingVolumeJob::setRoot(Entity *root) @@ -300,6 +380,8 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event, bool allHitsRequested, Qt3DCore::QNodeId viewportNodeId) { + Q_D(PickBoundingVolumeJob); + ObjectPicker *lastCurrentPicker = m_manager->objectPickerManager()->data(m_currentPicker); // If we have hits if (!sphereHits.isEmpty()) { @@ -383,37 +465,43 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event, // Store pressed object handle m_currentPicker = objectPickerHandle; // Send pressed event to m_currentPicker - objectPicker->onPressed(pickEvent, viewportNodeId); + d->dispatches.push_back({objectPicker->peerId(), event.type(), pickEvent, viewportNodeId}); + objectPicker->setPressed(true); break; } case QEvent::MouseButtonRelease: { // Only send the release event if it was pressed - if (objectPicker->isPressed()) - objectPicker->onReleased(pickEvent, viewportNodeId); + if (objectPicker->isPressed()) { + d->dispatches.push_back({objectPicker->peerId(), event.type(), pickEvent, viewportNodeId}); + objectPicker->setPressed(false); + } if (lastCurrentPicker != nullptr && m_currentPicker == objectPickerHandle) { - objectPicker->onClicked(pickEvent, viewportNodeId); + d->dispatches.push_back({objectPicker->peerId(), + PickBoundingVolumeJobPrivate::MouseButtonClick, + pickEvent, viewportNodeId}); m_currentPicker = HObjectPicker(); } break; } #if QT_CONFIG(gestures) case QEvent::Gesture: { - objectPicker->onClicked(pickEvent, viewportNodeId); + d->dispatches.push_back({objectPicker->peerId(), + PickBoundingVolumeJobPrivate::MouseButtonClick, + pickEvent, viewportNodeId}); break; } #endif case QEvent::MouseMove: { - if ((objectPicker->isPressed() || objectPicker->isHoverEnabled()) && objectPicker->isDragEnabled()) { - objectPicker->onMoved(pickEvent, viewportNodeId); - } + if ((objectPicker->isPressed() || objectPicker->isHoverEnabled()) && objectPicker->isDragEnabled()) + d->dispatches.push_back({objectPicker->peerId(), event.type(), pickEvent, viewportNodeId}); Q_FALLTHROUGH(); // fallthrough } case QEvent::HoverMove: { if (!m_hoveredPickers.contains(objectPickerHandle)) { if (objectPicker->isHoverEnabled()) { // Send entered event to objectPicker - objectPicker->onEntered(); + d->dispatches.push_back({objectPicker->peerId(), QEvent::Enter, pickEvent, viewportNodeId}); // and save it in the hoveredPickers m_hoveredPickers.push_back(objectPickerHandle); } @@ -440,7 +528,8 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event, if (lastCurrentPicker != nullptr) { m_currentPicker = HObjectPicker(); QPickEventPtr pickEvent(new QPickEvent); - lastCurrentPicker->onReleased(pickEvent, viewportNodeId); + lastCurrentPicker->setPressed(false); + d->dispatches.push_back({lastCurrentPicker->peerId(), event.type(), pickEvent, viewportNodeId}); } break; } @@ -452,12 +541,15 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event, void PickBoundingVolumeJob::clearPreviouslyHoveredPickers() { + Q_D(PickBoundingVolumeJob); + for (const HObjectPicker &pickHandle : qAsConst(m_hoveredPickersToClear)) { ObjectPicker *pick = m_manager->objectPickerManager()->data(pickHandle); if (pick) - pick->onExited(); + d->dispatches.push_back({pick->peerId(), QEvent::Leave, {}, {}}); m_hoveredPickers.removeAll(pickHandle); } + m_hoveredPickersToClear.clear(); } diff --git a/src/render/jobs/pickboundingvolumejob_p.h b/src/render/jobs/pickboundingvolumejob_p.h index e3d847916..49b11b775 100644 --- a/src/render/jobs/pickboundingvolumejob_p.h +++ b/src/render/jobs/pickboundingvolumejob_p.h @@ -70,6 +70,7 @@ namespace Qt3DRender { class QViewport; namespace Render { +class PickBoundingVolumeJobPrivate; namespace PickingUtils { typedef QVector<RayCasting::QCollisionQueryResult::Hit> HitList; @@ -101,6 +102,8 @@ protected: Qt3DCore::QNodeId viewportNodeId); private: + Q_DECLARE_PRIVATE(PickBoundingVolumeJob) + void clearPreviouslyHoveredPickers(); QList<QPair<QObject*, QMouseEvent>> m_pendingMouseEvents; diff --git a/src/render/picking/objectpicker.cpp b/src/render/picking/objectpicker.cpp index e278d6b6f..84169586e 100644 --- a/src/render/picking/objectpicker.cpp +++ b/src/render/picking/objectpicker.cpp @@ -43,7 +43,6 @@ #include <Qt3DRender/private/qobjectpicker_p.h> #include <Qt3DRender/qattribute.h> #include <Qt3DRender/private/pickboundingvolumejob_p.h> -#include <Qt3DCore/qpropertyupdatedchange.h> QT_BEGIN_NAMESPACE @@ -100,7 +99,6 @@ void ObjectPicker::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstT markDirty(AbstractRenderer::AllDirty); notifyJob(); } - } void ObjectPicker::notifyJob() @@ -124,58 +122,9 @@ bool ObjectPicker::isDragEnabled() const return m_dragEnabled; } -void ObjectPicker::onClicked(QPickEventPtr event, Qt3DCore::QNodeId viewportNodeId) -{ - auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); - e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); - e->setPropertyName("clicked"); - e->setValue(QVariant::fromValue(QObjectPickerEvent { event, viewportNodeId })); - notifyObservers(e); -} - -void ObjectPicker::onMoved(QPickEventPtr event, Qt3DCore::QNodeId viewportNodeId) -{ - auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); - e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); - e->setPropertyName("moved"); - e->setValue(QVariant::fromValue(QObjectPickerEvent { event, viewportNodeId })); - notifyObservers(e); -} - -void ObjectPicker::onPressed(QPickEventPtr event, Qt3DCore::QNodeId viewportNodeId) -{ - auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); - e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); - e->setPropertyName("pressed"); - e->setValue(QVariant::fromValue(QObjectPickerEvent { event, viewportNodeId })); - m_isPressed = true; - notifyObservers(e); -} - -void ObjectPicker::onReleased(QPickEventPtr event, Qt3DCore::QNodeId viewportNodeId) -{ - auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); - e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); - e->setPropertyName("released"); - e->setValue(QVariant::fromValue(QObjectPickerEvent { event, viewportNodeId })); - m_isPressed = false; - notifyObservers(e); -} - -void ObjectPicker::onEntered() -{ - auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); - e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); - e->setPropertyName("entered"); - notifyObservers(e); -} - -void ObjectPicker::onExited() +void ObjectPicker::setPressed(bool pressed) { - auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); - e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); - e->setPropertyName("exited"); - notifyObservers(e); + m_isPressed = pressed; } void ObjectPicker::setPriority(int priority) diff --git a/src/render/picking/objectpicker_p.h b/src/render/picking/objectpicker_p.h index b4f7d073c..49c8de770 100644 --- a/src/render/picking/objectpicker_p.h +++ b/src/render/picking/objectpicker_p.h @@ -74,12 +74,7 @@ public: bool isHoverEnabled() const; bool isDragEnabled() const; - void onClicked(QPickEventPtr event, Qt3DCore::QNodeId viewportNodeId); - void onMoved(QPickEventPtr event, Qt3DCore::QNodeId viewportNodeId); - void onPressed(QPickEventPtr event, Qt3DCore::QNodeId viewportNodeId); - void onReleased(QPickEventPtr event, Qt3DCore::QNodeId viewportNodeId); - void onEntered(); - void onExited(); + void setPressed(bool pressed); // Needed for unit tests void setPriority(int priority); diff --git a/src/render/picking/qobjectpicker.cpp b/src/render/picking/qobjectpicker.cpp index 9537d4982..0c667806c 100644 --- a/src/render/picking/qobjectpicker.cpp +++ b/src/render/picking/qobjectpicker.cpp @@ -352,33 +352,6 @@ int QObjectPicker::priority() const return d->m_priority; } -/*! \internal */ -void QObjectPicker::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) -{ - Q_D(QObjectPicker); - Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change); - if (e->type() == Qt3DCore::PropertyUpdated) { - // TO DO: Complete this part - // to emit the correct signals - const QByteArray propertyName = e->propertyName(); - if (propertyName == QByteArrayLiteral("pressed")) { - d->pressedEvent(d->resolvePickEvent(e)); - } else if (propertyName == QByteArrayLiteral("released")) { - d->releasedEvent(d->resolvePickEvent(e)); - } else if (propertyName == QByteArrayLiteral("clicked")) { - d->clickedEvent(d->resolvePickEvent(e)); - } else if (propertyName == QByteArrayLiteral("moved")) { - d->movedEvent(d->resolvePickEvent(e)); - } else if (propertyName == QByteArrayLiteral("entered")) { - emit entered(); - d->setContainsMouse(true); - } else if (propertyName == QByteArrayLiteral("exited")) { - d->setContainsMouse(false); - emit exited(); - } - } -} - /*! \internal */ @@ -407,15 +380,6 @@ void QObjectPickerPrivate::setContainsMouse(bool containsMouse) } } -QPickEvent *QObjectPickerPrivate::resolvePickEvent(Qt3DCore::QPropertyUpdatedChangePtr e) -{ - QObjectPickerEvent ev = e->value().value<QObjectPickerEvent>(); - QPickEvent *pickEvent = ev.event.data(); - pickEvent->d_func()->m_viewport = static_cast<QViewport *>(scene()->lookupNode(ev.viewportNodeId)); - pickEvent->d_func()->m_entityPtr = static_cast<Qt3DCore::QEntity *>(scene()->lookupNode(pickEvent->d_func()->m_entity)); - return pickEvent; -} - void QObjectPickerPrivate::propagateEvent(QPickEvent *event, EventType type) { if (!m_entities.isEmpty()) { diff --git a/src/render/picking/qobjectpicker.h b/src/render/picking/qobjectpicker.h index 8866c99a9..ee63c9418 100644 --- a/src/render/picking/qobjectpicker.h +++ b/src/render/picking/qobjectpicker.h @@ -90,9 +90,6 @@ Q_SIGNALS: void containsMouseChanged(bool containsMouse); Q_REVISION(13) void priorityChanged(int priority); -protected: - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; - private: Q_DECLARE_PRIVATE(QObjectPicker) Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; diff --git a/src/render/picking/qobjectpicker_p.h b/src/render/picking/qobjectpicker_p.h index fb83912b0..69cee529d 100644 --- a/src/render/picking/qobjectpicker_p.h +++ b/src/render/picking/qobjectpicker_p.h @@ -91,7 +91,6 @@ public: Moved }; - QPickEvent *resolvePickEvent(Qt3DCore::QPropertyUpdatedChangePtr e); void propagateEvent(QPickEvent *event, EventType type); void pressedEvent(QPickEvent *event); diff --git a/src/render/picking/qpickevent_p.h b/src/render/picking/qpickevent_p.h index 4d2f1e2d4..15eeb04b8 100644 --- a/src/render/picking/qpickevent_p.h +++ b/src/render/picking/qpickevent_p.h @@ -37,6 +37,9 @@ ** ****************************************************************************/ +#ifndef QT3DRENDER_QPICKEVENT_P_H +#define QT3DRENDER_QPICKEVENT_P_H + // // W A R N I N G // ------------- @@ -95,3 +98,4 @@ public: QT_END_NAMESPACE +#endif // QT3DRENDER_QPICKEVENT_P_H |