diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-11-04 15:37:15 +0100 |
---|---|---|
committer | Andy Nichols <andy.nichols@theqtcompany.com> | 2015-11-16 09:17:52 +0000 |
commit | 726d2deddb80cb73a3de18f1726e3ad9a67ecfc1 (patch) | |
tree | 0b809ac959feeaed242731eb7d119e7bfcd44b10 /src/render/jobs | |
parent | 06e5c80e23e8578517eb47bf2acee9d086fac9ce (diff) |
PickBoundingVolumeJob: few fixes
- properly handle click events
- fix hover events when using multiple viewports
- handle picking on parent Entities that have no geometry
Change-Id: Ie44cc4278a4dacf36f2ad6e4f77aea0eb2977d51
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
Diffstat (limited to 'src/render/jobs')
-rw-r--r-- | src/render/jobs/pickboundingvolumejob.cpp | 47 | ||||
-rw-r--r-- | src/render/jobs/pickboundingvolumejob_p.h | 1 |
2 files changed, 32 insertions, 16 deletions
diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index 02d620b33..2140d5cd3 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -172,18 +172,28 @@ void PickBoundingVolumeJob::run() if (!vcPairs.empty()) { Q_FOREACH (const QMouseEvent &event, m_mouseEvents) { + m_hoveredPickersToClear = m_hoveredPickers; + ObjectPicker *lastCurrentPicker = m_renderer->objectPickerManager()->data(m_currentPicker); Q_FOREACH (const ViewportCameraPair &vc, vcPairs) { const QVector<Qt3DCore::QNodeId> hits = hitsForViewportAndCamera(event.pos(), vc.viewport, vc.cameraId, rayCasting); - ObjectPicker *lastCurrentPicker = m_renderer->objectPickerManager()->data(m_currentPicker); // If we have hits if (!hits.isEmpty()) { Q_FOREACH (const Qt3DCore::QNodeId &entityId, hits) { Entity *entity = m_renderer->renderNodesManager()->lookupResource(entityId); HObjectPicker objectPickerHandle = entity->componentHandle<ObjectPicker, 16>(); + + // If the Entity which actually received the hit doesn't have + // an object picker component, we need to check the parent if it has one ... + while (objectPickerHandle.isNull() && entity != Q_NULLPTR) { + entity = entity->parent(); + if (entity != Q_NULLPTR) + objectPickerHandle = entity->componentHandle<ObjectPicker, 16>(); + } + ObjectPicker *objectPicker = m_renderer->objectPickerManager()->data(objectPickerHandle); if (objectPicker != Q_NULLPTR) { @@ -199,8 +209,10 @@ void PickBoundingVolumeJob::run() case QEvent::MouseButtonRelease: { // Send release event to m_currentPicker - if (lastCurrentPicker != Q_NULLPTR) + if (lastCurrentPicker != Q_NULLPTR) { + lastCurrentPicker->onClicked(); lastCurrentPicker->onReleased(); + } break; } @@ -209,12 +221,9 @@ void PickBoundingVolumeJob::run() break; } + case QEvent::HoverMove: case QEvent::MouseMove: { if (!m_hoveredPickers.contains(objectPickerHandle)) { - // Send exited event to object pickers on which we - // had set the hovered flag - clearPreviouslyHoveredPickers(); - if (objectPicker->hoverEnabled()) { // Send entered event to objectPicker objectPicker->onEntered(); @@ -229,10 +238,14 @@ void PickBoundingVolumeJob::run() break; } } + + // The ObjectPicker was hit -> it is still being hovered + m_hoveredPickersToClear.removeAll(objectPickerHandle); + lastCurrentPicker = m_renderer->objectPickerManager()->data(m_currentPicker); } - // Otherwise + // Otherwise no hits } else { switch (event.type()) { case QEvent::MouseButtonRelease: { @@ -241,18 +254,19 @@ void PickBoundingVolumeJob::run() lastCurrentPicker->onReleased(); break; } - case QEvent::MouseMove: { - // Send exited event to object pickers on which we - // had set the hovered flag - clearPreviouslyHoveredPickers(); - break; - } default: break; } } } } + + // Clear Hovered elements that needs to be cleared + // Send exit event to object pickers on which we + // had set the hovered flag for a previous frame + // and that aren't being hovered any longer + clearPreviouslyHoveredPickers(); + } } @@ -318,19 +332,20 @@ QVector<Qt3DCore::QNodeId> PickBoundingVolumeJob::hitsForViewportAndCamera(const // In GL the y is inverted compared to Qt const QPoint glCorrectPos = s ? QPoint(pos.x(), s->size().height() - pos.y()) : pos; const Qt3DCore::QRay3D ray = intersectionRay(glCorrectPos, viewMatrix, projectionMatrix, viewport); - const Qt3DCore::QQueryHandle rayCastingHandle = rayCasting->query(ray, Qt3DCore::QAbstractCollisionQueryService::FirstHit); + const Qt3DCore::QQueryHandle rayCastingHandle = rayCasting->query(ray, Qt3DCore::QAbstractCollisionQueryService::AllHits); const Qt3DCore::QCollisionQueryResult queryResult = rayCasting->fetchResult(rayCastingHandle); return queryResult.entitiesHit(); } void PickBoundingVolumeJob::clearPreviouslyHoveredPickers() { - Q_FOREACH (const HObjectPicker &pickHandle, m_hoveredPickers) { + Q_FOREACH (const HObjectPicker &pickHandle, m_hoveredPickersToClear) { ObjectPicker *pick = m_renderer->objectPickerManager()->data(pickHandle); if (pick) pick->onExited(); + m_hoveredPickers.removeAll(pickHandle); } - m_hoveredPickers.clear(); + m_hoveredPickersToClear.clear(); } } // namespace Render diff --git a/src/render/jobs/pickboundingvolumejob_p.h b/src/render/jobs/pickboundingvolumejob_p.h index c3b190f67..e52fcccf4 100644 --- a/src/render/jobs/pickboundingvolumejob_p.h +++ b/src/render/jobs/pickboundingvolumejob_p.h @@ -101,6 +101,7 @@ private: void clearPreviouslyHoveredPickers(); HObjectPicker m_currentPicker; QVector<HObjectPicker> m_hoveredPickers; + QVector<HObjectPicker> m_hoveredPickersToClear; }; typedef QSharedPointer<PickBoundingVolumeJob> PickBoundingVolumeJobPtr; |