diff options
author | Mike Krus <mike.krus@kdab.com> | 2017-04-08 16:08:24 +0200 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2018-01-26 07:54:14 +0000 |
commit | 7c8410c6dc325902160bb433044800ba02d44d12 (patch) | |
tree | d41961a6d4f6993c85e746154f19c11440ab2cca /src/render/jobs/pickboundingvolumeutils.cpp | |
parent | e680fe041700296be5e6e4a132e2cfc6f54d4e77 (diff) |
Handle multiple surfaces properly for picking
This fixes issues with picking when having multiple viewports and/or
multiple windows.
Now check that the mouse event actually hits inside the viewport extents.
Also track the source of events and check that the surface matches the
source of the event.
Remaining issue is overlapping viewports within the same window
Task-number: QTBUG-59567
Change-Id: I76a4ee2bec7300d893fef6040d89bf81f2109795
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render/jobs/pickboundingvolumeutils.cpp')
-rw-r--r-- | src/render/jobs/pickboundingvolumeutils.cpp | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/src/render/jobs/pickboundingvolumeutils.cpp b/src/render/jobs/pickboundingvolumeutils.cpp index 5c778bf29..5de551cf6 100644 --- a/src/render/jobs/pickboundingvolumeutils.cpp +++ b/src/render/jobs/pickboundingvolumeutils.cpp @@ -68,9 +68,9 @@ void ViewportCameraAreaGatherer::visit(FrameGraphNode *node) m_leaves.push_back(node); } -ViewportCameraAreaTriplet ViewportCameraAreaGatherer::gatherUpViewportCameraAreas(Render::FrameGraphNode *node) const +ViewportCameraAreaDetails ViewportCameraAreaGatherer::gatherUpViewportCameraAreas(Render::FrameGraphNode *node) const { - ViewportCameraAreaTriplet vca; + ViewportCameraAreaDetails vca; vca.viewport = QRectF(0.0f, 0.0f, 1.0f, 1.0f); while (node) { @@ -82,9 +82,12 @@ ViewportCameraAreaTriplet ViewportCameraAreaGatherer::gatherUpViewportCameraArea case FrameGraphNode::Viewport: vca.viewport = computeViewport(vca.viewport, static_cast<const ViewportNode *>(node)); break; - case FrameGraphNode::Surface: - vca.area = static_cast<const RenderSurfaceSelector *>(node)->renderTargetSize(); + case FrameGraphNode::Surface: { + auto selector = static_cast<const RenderSurfaceSelector *>(node); + vca.area = selector->renderTargetSize(); + vca.surface = selector->surface(); break; + } default: break; } @@ -94,28 +97,31 @@ ViewportCameraAreaTriplet ViewportCameraAreaGatherer::gatherUpViewportCameraArea return vca; } -QVector<ViewportCameraAreaTriplet> ViewportCameraAreaGatherer::gather(FrameGraphNode *root) +QVector<ViewportCameraAreaDetails> ViewportCameraAreaGatherer::gather(FrameGraphNode *root) { // Retrieve all leaves visit(root); - QVector<ViewportCameraAreaTriplet> vcaTriplets; + QVector<ViewportCameraAreaDetails> vcaTriplets; vcaTriplets.reserve(m_leaves.count()); // Find all viewport/camera pairs by traversing from leaf to root for (Render::FrameGraphNode *leaf : qAsConst(m_leaves)) { - ViewportCameraAreaTriplet vcaTriplet = gatherUpViewportCameraAreas(leaf); - if (!m_targetCamera.isNull() && vcaTriplet.cameraId != m_targetCamera) + ViewportCameraAreaDetails vcaDetails = gatherUpViewportCameraAreas(leaf); + if (!m_targetCamera.isNull() && vcaDetails.cameraId != m_targetCamera) continue; - if (!vcaTriplet.cameraId.isNull() && isUnique(vcaTriplets, vcaTriplet)) - vcaTriplets.push_back(vcaTriplet); + if (!vcaDetails.cameraId.isNull() && isUnique(vcaTriplets, vcaDetails)) + vcaTriplets.push_back(vcaDetails); } return vcaTriplets; } -bool PickingUtils::ViewportCameraAreaGatherer::isUnique(const QVector<ViewportCameraAreaTriplet> &vcaTriplets, const ViewportCameraAreaTriplet &vca) const +bool PickingUtils::ViewportCameraAreaGatherer::isUnique(const QVector<ViewportCameraAreaDetails> &vcaList, const ViewportCameraAreaDetails &vca) const { - for (const ViewportCameraAreaTriplet &triplet : vcaTriplets) { - if (vca.cameraId == triplet.cameraId && vca.viewport == triplet.viewport && vca.area == triplet.area) + for (const ViewportCameraAreaDetails &listItem : vcaList) { + if (vca.cameraId == listItem.cameraId && + vca.viewport == listItem.viewport && + vca.surface == listItem.surface && + vca.area == listItem.area) return false; } return true; |