summaryrefslogtreecommitdiffstats
path: root/src/render
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2017-09-11 17:48:12 +0100
committerMike Krus <mike.krus@kdab.com>2017-09-12 08:22:57 +0000
commitd88f9796150b8bc3b1506d2bca450c0840bf3807 (patch)
treece58d771e1624be72aa2540f841ba1ff6eb74575 /src/render
parentcd467d5ffc6eaaa7da089ab4acc5284cd11d1109 (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.cpp20
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();