diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2022-08-16 20:36:54 +0300 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2022-08-16 20:36:54 +0300 |
commit | a537b1e4e0b9821850ddf77ef1f2178df8de3d43 (patch) | |
tree | e57a4443bcb94a4d9291aed4665343244d65a9ac /src/render/jobs/pickboundingvolumeutils.cpp | |
parent | e1b9039ca879ab3714a3f67301378f43334e4b1d (diff) | |
parent | ff866ee201ba2ab62d3bdd9f6358612fbcd6128e (diff) |
Merge remote-tracking branch 'origin/tqtc/lts-5.15.6' into tqtc/lts-5.15-opensourcev5.15.6-lts-lgpl
Change-Id: I78ddafff7a563a17c7e9ce31249faf05dc6cda69
Diffstat (limited to 'src/render/jobs/pickboundingvolumeutils.cpp')
-rw-r--r-- | src/render/jobs/pickboundingvolumeutils.cpp | 116 |
1 files changed, 55 insertions, 61 deletions
diff --git a/src/render/jobs/pickboundingvolumeutils.cpp b/src/render/jobs/pickboundingvolumeutils.cpp index 1d22e8645..f4c5cc094 100644 --- a/src/render/jobs/pickboundingvolumeutils.cpp +++ b/src/render/jobs/pickboundingvolumeutils.cpp @@ -52,6 +52,9 @@ #include <Qt3DRender/private/segmentsvisitor_p.h> #include <Qt3DRender/private/pointsvisitor_p.h> #include <Qt3DRender/private/layer_p.h> +#include <Qt3DRender/private/layerfilternode_p.h> +#include <Qt3DRender/private/rendersettings_p.h> +#include <Qt3DRender/private/filterlayerentityjob_p.h> #include <vector> #include <algorithm> @@ -105,6 +108,11 @@ ViewportCameraAreaDetails ViewportCameraAreaGatherer::gatherUpViewportCameraArea // prevent picking in the presence of a NoPicking node return {}; } + case FrameGraphNode::LayerFilter: { + auto fnode = static_cast<const LayerFilterNode *>(node); + vca.layersFilters.push_back(fnode->peerId()); + break; + } default: break; } @@ -139,7 +147,8 @@ bool ViewportCameraAreaGatherer::isUnique(const QVector<ViewportCameraAreaDetail if (vca.cameraId == listItem.cameraId && vca.viewport == listItem.viewport && vca.surface == listItem.surface && - vca.area == listItem.area) + vca.area == listItem.area && + vca.layersFilters == listItem.layersFilters) return false; } return true; @@ -700,16 +709,19 @@ HitList PointCollisionGathererFunctor::pick(const Entity *entity) const HierarchicalEntityPicker::HierarchicalEntityPicker(const QRay3D &ray, bool requireObjectPicker) : m_ray(ray) , m_objectPickersRequired(requireObjectPicker) - , m_filterMode(QAbstractRayCaster::AcceptAnyMatchingLayers) { +} +void HierarchicalEntityPicker::setLayerFilterIds(const Qt3DCore::QNodeIdVector &layerFilterIds) +{ + m_layerFilterIds = layerFilterIds; } -void HierarchicalEntityPicker::setFilterLayers(const Qt3DCore::QNodeIdVector &layerIds, QAbstractRayCaster::FilterMode mode) +void HierarchicalEntityPicker::setLayerIds(const Qt3DCore::QNodeIdVector &layerIds, + QAbstractRayCaster::FilterMode mode) { - m_filterMode = mode; m_layerIds = layerIds; - std::sort(m_layerIds.begin(), m_layerIds.end()); + m_layerFilterMode = mode; } bool HierarchicalEntityPicker::collectHits(NodeManagers *manager, Entity *root) @@ -722,60 +734,37 @@ bool HierarchicalEntityPicker::collectHits(NodeManagers *manager, Entity *root) struct EntityData { Entity* entity; bool hasObjectPicker; - Qt3DCore::QNodeIdVector recursiveLayers; int priority; }; std::vector<EntityData> worklist; - worklist.push_back({root, !root->componentHandle<ObjectPicker>().isNull(), {}, 0}); - - LayerManager *layerManager = manager->layerManager(); + worklist.push_back({root, !root->componentHandle<ObjectPicker>().isNull(), 0}); + + // Record all entities that satisfy layerFiltering. We can then check against + // that to see if a picked Entity also satisfies the layer filtering + + // Note: PickBoundingVolumeJob filters against LayerFilter nodes (FG) whereas + // the RayCastingJob filters only against a set of Layers and a filter Mode + const bool hasLayerFilters = m_layerFilterIds.size() > 0; + const bool hasLayers = m_layerIds.size() > 0; + const bool hasLayerFiltering = hasLayerFilters || hasLayers; + QVector<Entity *> layerFilterEntities; + FilterLayerEntityJob layerFilterJob; + layerFilterJob.setManager(manager); + + if (hasLayerFilters) { + // Note: we expect UpdateEntityLayersJob was called beforehand to handle layer recursivness + // Filtering against LayerFilters (PickBoundingVolumeJob) + if (m_layerFilterIds.size()) { + layerFilterJob.setLayerFilters(m_layerFilterIds); + layerFilterJob.run(); + layerFilterEntities = layerFilterJob.filteredEntities(); + } + } while (!worklist.empty()) { EntityData current = worklist.back(); worklist.pop_back(); - bool accepted = true; - if (m_layerIds.size()) { - // TODO investigate reusing logic from LayerFilter job - Qt3DCore::QNodeIdVector filterLayers = current.recursiveLayers + current.entity->componentsUuid<Layer>(); - - // remove disabled layers - filterLayers.erase(std::remove_if(filterLayers.begin(), filterLayers.end(), - [layerManager](const Qt3DCore::QNodeId layerId) { - Layer *layer = layerManager->lookupResource(layerId); - return !layer || !layer->isEnabled(); - }), filterLayers.end()); - - std::sort(filterLayers.begin(), filterLayers.end()); - - Qt3DCore::QNodeIdVector commonIds; - std::set_intersection(m_layerIds.cbegin(), m_layerIds.cend(), - filterLayers.cbegin(), filterLayers.cend(), - std::back_inserter(commonIds)); - - switch (m_filterMode) { - case QAbstractRayCaster::AcceptAnyMatchingLayers: { - accepted = !commonIds.empty(); - break; - } - case QAbstractRayCaster::AcceptAllMatchingLayers: { - accepted = commonIds == m_layerIds; - break; - } - case QAbstractRayCaster::DiscardAnyMatchingLayers: { - accepted = commonIds.empty(); - break; - } - case QAbstractRayCaster::DiscardAllMatchingLayers: { - accepted = !(commonIds == m_layerIds); - break; - } - default: - Q_UNREACHABLE(); - break; - } - } - // first pick entry sub-scene-graph QCollisionQueryResult::Hit queryResult = rayCasting.query(m_ray, current.entity->worldBoundingVolumeWithChildren()); @@ -784,21 +773,27 @@ bool HierarchicalEntityPicker::collectHits(NodeManagers *manager, Entity *root) // if we get a hit, we check again for this specific entity queryResult = rayCasting.query(m_ray, current.entity->worldBoundingVolume()); - if (accepted && queryResult.m_distance >= 0.f && (current.hasObjectPicker || !m_objectPickersRequired)) { + + // Check Entity is in selected Layers if we have LayerIds or LayerFilterIds + // Note: it's not because a parent doesn't satisfy the layerFiltering that a child might not. + // Therefore we need to keep traversing children in all cases + + // Are we filtering against layerIds (RayCastingJob) + if (hasLayers) { + // QLayerFilter::FilterMode and QAbstractRayCaster::FilterMode are the same + layerFilterJob.filterEntityAgainstLayers(current.entity, m_layerIds, static_cast<QLayerFilter::FilterMode>(m_layerFilterMode)); + layerFilterEntities = layerFilterJob.filteredEntities(); + } + + const bool isInLayers = !hasLayerFiltering || layerFilterEntities.contains(current.entity); + + if (isInLayers && queryResult.m_distance >= 0.f && (current.hasObjectPicker || !m_objectPickersRequired)) { m_entities.push_back(current.entity); m_hits.push_back(queryResult); // Record entry for entity/priority m_entityToPriorityTable.insert(current.entity->peerId(), current.priority); } - Qt3DCore::QNodeIdVector recursiveLayers; - const Qt3DCore::QNodeIdVector entityLayers = current.entity->componentsUuid<Layer>(); - for (const Qt3DCore::QNodeId layerId : entityLayers) { - Layer *layer = layerManager->lookupResource(layerId); - if (layer->recursive()) - recursiveLayers << layerId; - } - // and pick children const auto childrenHandles = current.entity->childrenHandles(); for (const HEntity &handle : childrenHandles) { @@ -806,7 +801,6 @@ bool HierarchicalEntityPicker::collectHits(NodeManagers *manager, Entity *root) if (child) { ObjectPicker *childPicker = child->renderComponent<ObjectPicker>(); worklist.push_back({child, current.hasObjectPicker || childPicker, - current.recursiveLayers + recursiveLayers, (childPicker ? childPicker->priority() : current.priority)}); } } |