summaryrefslogtreecommitdiffstats
path: root/src/render/jobs
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/jobs')
-rw-r--r--src/render/jobs/loadscenejob.cpp3
-rw-r--r--src/render/jobs/pickboundingvolumejob.cpp19
-rw-r--r--src/render/jobs/pickboundingvolumejob_p.h8
-rw-r--r--src/render/jobs/pickboundingvolumeutils.cpp141
-rw-r--r--src/render/jobs/pickboundingvolumeutils_p.h58
5 files changed, 119 insertions, 110 deletions
diff --git a/src/render/jobs/loadscenejob.cpp b/src/render/jobs/loadscenejob.cpp
index 3d6326e93..5be733a4d 100644
--- a/src/render/jobs/loadscenejob.cpp
+++ b/src/render/jobs/loadscenejob.cpp
@@ -47,6 +47,9 @@
#include <Qt3DRender/private/qurlhelper_p.h>
#include <Qt3DRender/qsceneloader.h>
+#include <QFileInfo>
+#include <QMimeDatabase>
+
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp
index f9c7a390c..a1c8dd864 100644
--- a/src/render/jobs/pickboundingvolumejob.cpp
+++ b/src/render/jobs/pickboundingvolumejob.cpp
@@ -39,17 +39,17 @@
#include "pickboundingvolumejob_p.h"
#include "qpicktriangleevent.h"
+#include <Qt3DRender/qgeometryrenderer.h>
#include <Qt3DRender/private/renderer_p.h>
#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/entity_p.h>
#include <Qt3DRender/private/objectpicker_p.h>
#include <Qt3DRender/private/managers_p.h>
#include <Qt3DRender/private/geometryrenderer_p.h>
-
#include <Qt3DRender/private/rendersettings_p.h>
-#include <Qt3DRender/qgeometryrenderer.h>
#include <Qt3DRender/private/job_common_p.h>
#include <Qt3DRender/private/qpickevent_p.h>
+#include <Qt3DRender/private/pickboundingvolumeutils_p.h>
QT_BEGIN_NAMESPACE
@@ -60,8 +60,6 @@ namespace Render {
namespace {
-typedef PickingUtils::AbstractCollisionGathererFunctor::result_type HitList;
-
void setEventButtonAndModifiers(const QMouseEvent &event, QPickEvent::Buttons &eventButton, int &eventButtons, int &eventModifiers)
{
switch (event.button()) {
@@ -223,9 +221,6 @@ bool PickBoundingVolumeJob::runHelper()
// If we have move or hover move events that someone cares about, we try to avoid expensive computations
// by compressing them into a single one
- // Store the reducer function which varies depending on the picking settings set on the renderer
- using ReducerFunction = PickingUtils::CollisionVisitor::HitList (*)(PickingUtils::CollisionVisitor::HitList &results, const PickingUtils::CollisionVisitor::HitList &intermediate);
-
const bool trianglePickingRequested = (m_renderSettings->pickMethod() == QPickingSettings::TrianglePicking);
const bool allHitsRequested = (m_renderSettings->pickResultMode() == QPickingSettings::AllPicks);
const bool frontFaceRequested =
@@ -233,9 +228,6 @@ bool PickBoundingVolumeJob::runHelper()
const bool backFaceRequested =
m_renderSettings->faceOrientationPickingMode() != QPickingSettings::FrontFace;
- // Select the best reduction function based on the settings
- const ReducerFunction reducerOp = allHitsRequested ? PickingUtils::reduceToAllHits : PickingUtils::reduceToFirstHit;
-
// For each mouse event
for (const QMouseEvent &event : mouseEvents) {
m_hoveredPickersToClear = m_hoveredPickers;
@@ -248,7 +240,7 @@ bool PickBoundingVolumeJob::runHelper()
// For each triplet of Viewport / Camera and Area
for (const PickingUtils::ViewportCameraAreaTriplet &vca : vcaTriplets) {
- HitList sphereHits;
+ PickingUtils::HitList sphereHits;
QRay3D ray = rayForViewportAndCamera(vca.area, event.pos(), vca.viewport, vca.cameraId);
PickingUtils::HierarchicalEntityPicker entityPicker(ray);
@@ -259,8 +251,7 @@ bool PickBoundingVolumeJob::runHelper()
gathererFunctor.m_backFaceRequested = backFaceRequested;
gathererFunctor.m_manager = m_manager;
gathererFunctor.m_ray = ray;
- sphereHits = QtConcurrent::blockingMappedReduced<HitList>(entityPicker.entities(),
- gathererFunctor, reducerOp);
+ sphereHits = gathererFunctor.computeHits(entityPicker.entities(), allHitsRequested);
} else {
sphereHits = entityPicker.hits();
PickingUtils::AbstractCollisionGathererFunctor::sortHits(sphereHits);
@@ -300,7 +291,7 @@ void PickBoundingVolumeJob::run()
}
void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event,
- const PickingUtils::CollisionVisitor::HitList &sphereHits,
+ const PickingUtils::HitList &sphereHits,
QPickEvent::Buttons eventButton,
int eventButtons,
int eventModifiers,
diff --git a/src/render/jobs/pickboundingvolumejob_p.h b/src/render/jobs/pickboundingvolumejob_p.h
index 5239c5c6c..f13e4e48b 100644
--- a/src/render/jobs/pickboundingvolumejob_p.h
+++ b/src/render/jobs/pickboundingvolumejob_p.h
@@ -56,7 +56,6 @@
#include <Qt3DRender/private/handle_types_p.h>
#include <Qt3DRender/private/qboundingvolumeprovider_p.h>
#include <Qt3DRender/private/qcollisionqueryresult_p.h>
-#include <Qt3DRender/private/pickboundingvolumeutils_p.h>
#include <Qt3DRender/qpickevent.h>
#include <QMouseEvent>
#include <QKeyEvent>
@@ -76,6 +75,10 @@ class Renderer;
class NodeManagers;
class RenderSettings;
+namespace PickingUtils {
+typedef QVector<RayCasting::QCollisionQueryResult::Hit> HitList;
+}
+
class Q_AUTOTEST_EXPORT PickBoundingVolumeJob : public Qt3DCore::QAspectJob
{
public:
@@ -102,7 +105,8 @@ public:
protected:
void run() Q_DECL_FINAL;
- void dispatchPickEvents(const QMouseEvent &event, const PickingUtils::CollisionVisitor::HitList &sphereHits,
+ void dispatchPickEvents(const QMouseEvent &event,
+ const PickingUtils::HitList &sphereHits,
QPickEvent::Buttons eventButton,
int eventButtons,
int eventModifiers,
diff --git a/src/render/jobs/pickboundingvolumeutils.cpp b/src/render/jobs/pickboundingvolumeutils.cpp
index f08398a5a..a8367dc20 100644
--- a/src/render/jobs/pickboundingvolumeutils.cpp
+++ b/src/render/jobs/pickboundingvolumeutils.cpp
@@ -110,7 +110,8 @@ QVector<ViewportCameraAreaTriplet> ViewportCameraAreaGatherer::gather(FrameGraph
return vcaTriplets;
}
-bool PickingUtils::ViewportCameraAreaGatherer::isUnique(const QVector<ViewportCameraAreaTriplet> &vcaTriplets, const ViewportCameraAreaTriplet &vca) const
+bool ViewportCameraAreaGatherer::isUnique(const QVector<ViewportCameraAreaTriplet> &vcaTriplets,
+ const ViewportCameraAreaTriplet &vca) const
{
for (const ViewportCameraAreaTriplet &triplet : vcaTriplets) {
if (vca.cameraId == triplet.cameraId && vca.viewport == triplet.viewport && vca.area == triplet.area)
@@ -147,7 +148,35 @@ QVector<Entity *> EntityGatherer::entities() const
return m_entities;
}
-void CollisionVisitor::visit(uint andx, const QVector3D &a, uint bndx, const QVector3D &b, uint cndx, const QVector3D &c)
+
+class TriangleCollisionVisitor : public TrianglesVisitor
+{
+public:
+ HitList hits;
+
+ TriangleCollisionVisitor(NodeManagers* manager, const Entity *root, const RayCasting::QRay3D& ray,
+ bool frontFaceRequested, bool backFaceRequested)
+ : TrianglesVisitor(manager), m_root(root), m_ray(ray), m_triangleIndex(0)
+ , m_frontFaceRequested(frontFaceRequested), m_backFaceRequested(backFaceRequested)
+ {
+ }
+
+private:
+ const Entity *m_root;
+ RayCasting::QRay3D m_ray;
+ uint m_triangleIndex;
+ bool m_frontFaceRequested;
+ bool m_backFaceRequested;
+
+ void visit(uint andx, const QVector3D &a,
+ uint bndx, const QVector3D &b,
+ uint cndx, const QVector3D &c) Q_DECL_OVERRIDE;
+ bool intersectsSegmentTriangle(uint andx, const QVector3D &a,
+ uint bndx, const QVector3D &b,
+ uint cndx, const QVector3D &c);
+};
+
+void TriangleCollisionVisitor::visit(uint andx, const QVector3D &a, uint bndx, const QVector3D &b, uint cndx, const QVector3D &c)
{
const QMatrix4x4 &mat = *m_root->worldTransform();
const QVector3D tA = mat * a;
@@ -163,7 +192,7 @@ void CollisionVisitor::visit(uint andx, const QVector3D &a, uint bndx, const QVe
m_triangleIndex++;
}
-bool CollisionVisitor::intersectsSegmentTriangle(uint andx, const QVector3D &a, uint bndx, const QVector3D &b, uint cndx, const QVector3D &c)
+bool TriangleCollisionVisitor::intersectsSegmentTriangle(uint andx, const QVector3D &a, uint bndx, const QVector3D &b, uint cndx, const QVector3D &c)
{
float t = 0.0f;
QVector3D uvw;
@@ -183,6 +212,32 @@ bool CollisionVisitor::intersectsSegmentTriangle(uint andx, const QVector3D &a,
return intersected;
}
+HitList reduceToFirstHit(HitList &result, const HitList &intermediate)
+{
+ if (!intermediate.empty()) {
+ if (result.empty())
+ result.push_back(intermediate.front());
+ float closest = result.front().m_distance;
+ for (const auto &v : intermediate) {
+ if (v.m_distance < closest) {
+ result.push_front(v);
+ closest = v.m_distance;
+ }
+ }
+
+ while (result.size() > 1)
+ result.pop_back();
+ }
+ return result;
+}
+
+HitList reduceToAllHits(HitList &results, const HitList &intermediate)
+{
+ if (!intermediate.empty())
+ results << intermediate;
+ return results;
+}
+
AbstractCollisionGathererFunctor::AbstractCollisionGathererFunctor()
: m_manager(nullptr)
{ }
@@ -190,7 +245,7 @@ AbstractCollisionGathererFunctor::AbstractCollisionGathererFunctor()
AbstractCollisionGathererFunctor::~AbstractCollisionGathererFunctor()
{ }
-AbstractCollisionGathererFunctor::result_type AbstractCollisionGathererFunctor::operator ()(const Entity *entity) const
+HitList AbstractCollisionGathererFunctor::operator ()(const Entity *entity) const
{
HObjectPicker objectPickerHandle = entity->componentHandle<ObjectPicker, 16>();
@@ -205,44 +260,62 @@ AbstractCollisionGathererFunctor::result_type AbstractCollisionGathererFunctor::
ObjectPicker *objectPicker = m_manager->objectPickerManager()->data(objectPickerHandle);
if (objectPicker == nullptr || !objectPicker->isEnabled())
- return result_type(); // don't bother picking entities that don't
- // have an object picker, or if it's disabled
+ return {}; // don't bother picking entities that don't
+ // have an object picker, or if it's disabled
- RayCasting::QRayCastingService rayCasting;
+ return pick(entity);
+}
- return pick(&rayCasting, entity);
+bool AbstractCollisionGathererFunctor::rayHitsEntity(const Entity *entity) const
+{
+ QRayCastingService rayCasting;
+ const QCollisionQueryResult::Hit queryResult = rayCasting.query(m_ray, entity->worldBoundingVolume());
+ return queryResult.m_distance >= 0.f;
}
-void AbstractCollisionGathererFunctor::sortHits(CollisionVisitor::HitList &results)
+void AbstractCollisionGathererFunctor::sortHits(HitList &results)
{
- auto compareHitsDistance = [](const CollisionVisitor::HitList::value_type &a,
- const CollisionVisitor::HitList::value_type &b) {
+ auto compareHitsDistance = [](const HitList::value_type &a,
+ const HitList::value_type &b) {
return a.m_distance < b.m_distance;
};
std::sort(results.begin(), results.end(), compareHitsDistance);
}
-AbstractCollisionGathererFunctor::result_type EntityCollisionGathererFunctor::pick(RayCasting::QAbstractCollisionQueryService *rayCasting, const Entity *entity) const
+HitList EntityCollisionGathererFunctor::computeHits(const QVector<Entity *> &entities, bool allHitsRequested)
{
- result_type result;
+ const auto reducerOp = allHitsRequested ? PickingUtils::reduceToAllHits : PickingUtils::reduceToFirstHit;
+ return QtConcurrent::blockingMappedReduced<HitList>(entities, *this, reducerOp);
+}
- const QCollisionQueryResult::Hit queryResult = rayCasting->query(m_ray, entity->worldBoundingVolume());
+HitList EntityCollisionGathererFunctor::pick(const Entity *entity) const
+{
+ HitList result;
+
+ QRayCastingService rayCasting;
+ const QCollisionQueryResult::Hit queryResult = rayCasting.query(m_ray, entity->worldBoundingVolume());
if (queryResult.m_distance >= 0.f)
result.push_back(queryResult);
return result;
}
-AbstractCollisionGathererFunctor::result_type TriangleCollisionGathererFunctor::pick(RayCasting::QAbstractCollisionQueryService *rayCasting, const Entity *entity) const
+HitList TriangleCollisionGathererFunctor::computeHits(const QVector<Entity *> &entities, bool allHitsRequested)
+{
+ const auto reducerOp = allHitsRequested ? PickingUtils::reduceToAllHits : PickingUtils::reduceToFirstHit;
+ return QtConcurrent::blockingMappedReduced<HitList>(entities, *this, reducerOp);
+}
+
+HitList TriangleCollisionGathererFunctor::pick(const Entity *entity) const
{
- result_type result;
+ HitList result;
GeometryRenderer *gRenderer = entity->renderComponent<GeometryRenderer>();
if (!gRenderer)
return result;
- if (rayHitsEntity(rayCasting, entity)) {
- CollisionVisitor visitor(m_manager, entity, m_ray, m_frontFaceRequested, m_backFaceRequested);
+ if (rayHitsEntity(entity)) {
+ TriangleCollisionVisitor visitor(m_manager, entity, m_ray, m_frontFaceRequested, m_backFaceRequested);
visitor.apply(gRenderer, entity->peerId());
result = visitor.hits;
@@ -252,38 +325,6 @@ AbstractCollisionGathererFunctor::result_type TriangleCollisionGathererFunctor::
return result;
}
-bool TriangleCollisionGathererFunctor::rayHitsEntity(RayCasting::QAbstractCollisionQueryService *rayCasting, const Entity *entity) const
-{
- const QCollisionQueryResult::Hit queryResult = rayCasting->query(m_ray, entity->worldBoundingVolume());
- return queryResult.m_distance >= 0.f;
-}
-
-CollisionVisitor::HitList reduceToFirstHit(CollisionVisitor::HitList &result, const CollisionVisitor::HitList &intermediate)
-{
- if (!intermediate.empty()) {
- if (result.empty())
- result.push_back(intermediate.front());
- float closest = result.front().m_distance;
- for (const auto &v : intermediate) {
- if (v.m_distance < closest) {
- result.push_front(v);
- closest = v.m_distance;
- }
- }
-
- while (result.size() > 1)
- result.pop_back();
- }
- return result;
-}
-
-CollisionVisitor::HitList reduceToAllHits(CollisionVisitor::HitList &results, const CollisionVisitor::HitList &intermediate)
-{
- if (!intermediate.empty())
- results << intermediate;
- return results;
-}
-
HierarchicalEntityPicker::HierarchicalEntityPicker(const QRay3D &ray)
: m_ray(ray)
{
diff --git a/src/render/jobs/pickboundingvolumeutils_p.h b/src/render/jobs/pickboundingvolumeutils_p.h
index 08615c094..eb272ce41 100644
--- a/src/render/jobs/pickboundingvolumeutils_p.h
+++ b/src/render/jobs/pickboundingvolumeutils_p.h
@@ -108,33 +108,7 @@ private:
mutable bool m_needsRefresh;
};
-class Q_AUTOTEST_EXPORT CollisionVisitor : public TrianglesVisitor
-{
-public:
- typedef QVector<RayCasting::QCollisionQueryResult::Hit> HitList;
- HitList hits;
-
- CollisionVisitor(NodeManagers* manager, const Entity *root, const RayCasting::QRay3D& ray,
- bool frontFaceRequested, bool backFaceRequested)
- : TrianglesVisitor(manager), m_root(root), m_ray(ray), m_triangleIndex(0)
- , m_frontFaceRequested(frontFaceRequested), m_backFaceRequested(backFaceRequested)
- {
- }
-
-private:
- const Entity *m_root;
- RayCasting::QRay3D m_ray;
- uint m_triangleIndex;
- bool m_frontFaceRequested;
- bool m_backFaceRequested;
-
- void visit(uint andx, const QVector3D &a,
- uint bndx, const QVector3D &b,
- uint cndx, const QVector3D &c) Q_DECL_OVERRIDE;
- bool intersectsSegmentTriangle(uint andx, const QVector3D &a,
- uint bndx, const QVector3D &b,
- uint cndx, const QVector3D &c);
-};
+typedef QVector<RayCasting::QCollisionQueryResult::Hit> HitList;
class Q_AUTOTEST_EXPORT HierarchicalEntityPicker
{
@@ -142,12 +116,12 @@ public:
explicit HierarchicalEntityPicker(const RayCasting::QRay3D &ray);
bool collectHits(Entity *root);
- inline CollisionVisitor::HitList hits() const { return m_hits; }
+ inline HitList hits() const { return m_hits; }
inline QVector<Entity *> entities() const { return m_entities; }
private:
RayCasting::QRay3D m_ray;
- CollisionVisitor::HitList m_hits;
+ HitList m_hits;
QVector<Entity *> m_entities;
};
@@ -159,17 +133,21 @@ struct Q_AUTOTEST_EXPORT AbstractCollisionGathererFunctor
NodeManagers *m_manager;
RayCasting::QRay3D m_ray;
+ virtual HitList computeHits(const QVector<Entity *> &entities, bool allHitsRequested) = 0;
+
// This define is required to work with QtConcurrent
- typedef CollisionVisitor::HitList result_type;
- result_type operator ()(const Entity *entity) const;
- virtual result_type pick(RayCasting::QAbstractCollisionQueryService *rayCasting, const Entity *entity) const = 0;
+ typedef HitList result_type;
+ HitList operator ()(const Entity *entity) const;
+ virtual HitList pick(const Entity *entity) const = 0;
- static void sortHits(CollisionVisitor::HitList &results);
+ bool rayHitsEntity(const Entity *entity) const;
+ static void sortHits(HitList &results);
};
struct Q_AUTOTEST_EXPORT EntityCollisionGathererFunctor : public AbstractCollisionGathererFunctor
{
- result_type pick(RayCasting::QAbstractCollisionQueryService *rayCasting, const Entity *entity) const Q_DECL_OVERRIDE;
+ HitList computeHits(const QVector<Entity *> &entities, bool allHitsRequested) Q_DECL_OVERRIDE;
+ HitList pick(const Entity *entity) const Q_DECL_OVERRIDE;
};
struct Q_AUTOTEST_EXPORT TriangleCollisionGathererFunctor : public AbstractCollisionGathererFunctor
@@ -177,18 +155,10 @@ struct Q_AUTOTEST_EXPORT TriangleCollisionGathererFunctor : public AbstractColli
bool m_frontFaceRequested;
bool m_backFaceRequested;
- result_type pick(RayCasting::QAbstractCollisionQueryService *rayCasting, const Entity *entity) const Q_DECL_OVERRIDE;
-
- bool rayHitsEntity(RayCasting::QAbstractCollisionQueryService *rayCasting, const Entity *entity) const;
+ HitList computeHits(const QVector<Entity *> &entities, bool allHitsRequested) Q_DECL_OVERRIDE;
+ HitList pick(const Entity *entity) const Q_DECL_OVERRIDE;
};
-Q_AUTOTEST_EXPORT QVector<Entity *> gatherEntities(Entity *entity, QVector<Entity *> entities);
-
-Q_AUTOTEST_EXPORT CollisionVisitor::HitList reduceToFirstHit(CollisionVisitor::HitList &result, const CollisionVisitor::HitList &intermediate);
-
-// Unordered
-Q_AUTOTEST_EXPORT CollisionVisitor::HitList reduceToAllHits(CollisionVisitor::HitList &results, const CollisionVisitor::HitList &intermediate);
-
} // PickingUtils
} // Render