diff options
author | Mike Krus <mike.krus@kdab.com> | 2017-09-11 17:48:12 +0100 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2017-09-12 08:22:57 +0000 |
commit | d88f9796150b8bc3b1506d2bca450c0840bf3807 (patch) | |
tree | ce58d771e1624be72aa2540f841ba1ff6eb74575 /src/render | |
parent | cd467d5ffc6eaaa7da089ab4acc5284cd11d1109 (diff) |
Fix bounding sphere picking
In some cases, the list of pickable objects may contain entities that don’t have an object picker (or not parent has).
Now filter the pick results to only keep entities which either have an object picker or are children of an entity that does.
Added unit test which now passes
Change-Id: I930c3d60cf2d19e845fe6c0de904c53b93ebe8be
Reviewed-by: Kevin Ottens <kevin.ottens@kdab.com>
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/jobs/pickboundingvolumeutils.cpp | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/src/render/jobs/pickboundingvolumeutils.cpp b/src/render/jobs/pickboundingvolumeutils.cpp index f08398a5a..70f0b7f95 100644 --- a/src/render/jobs/pickboundingvolumeutils.cpp +++ b/src/render/jobs/pickboundingvolumeutils.cpp @@ -48,6 +48,8 @@ #include <Qt3DRender/private/sphere_p.h> #include <Qt3DRender/private/entity_p.h> +#include <vector> + QT_BEGIN_NAMESPACE namespace Qt3DRender { @@ -296,27 +298,29 @@ bool HierarchicalEntityPicker::collectHits(Entity *root) m_entities.clear(); QRayCastingService rayCasting; - QVector<Entity *> worklist; - worklist << root; + std::vector<std::pair<Entity *, bool>> worklist; + worklist.push_back({root, !root->componentHandle<ObjectPicker, 16>().isNull()}); while (!worklist.empty()) { - Entity *current = worklist.takeLast(); + auto current = worklist.back(); + worklist.pop_back(); // first pick entry sub-scene-graph QCollisionQueryResult::Hit queryResult = - rayCasting.query(m_ray, current->worldBoundingVolumeWithChildren()); + rayCasting.query(m_ray, current.first->worldBoundingVolumeWithChildren()); if (queryResult.m_distance < 0.f) continue; // if we get a hit, we check again for this specific entity - queryResult = rayCasting.query(m_ray, current->worldBoundingVolume()); - if (queryResult.m_distance >= 0.f) { - m_entities.push_back(current); + queryResult = rayCasting.query(m_ray, current.first->worldBoundingVolume()); + if (queryResult.m_distance >= 0.f && current.second) { + m_entities.push_back(current.first); m_hits.push_back(queryResult); } // and pick children - worklist << current->children(); + for (auto child: current.first->children()) + worklist.push_back({child, current.second || !child->componentHandle<ObjectPicker, 16>().isNull()}); } return !m_hits.empty(); |