summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2016-10-25 13:51:37 +0300
committerAntti Määttä <antti.maatta@qt.io>2017-01-27 12:07:01 +0000
commit61a7a44b4f2ea88ee4451dbc0faedbd5efd11558 (patch)
tree535409be8d0deb35b13afa27433db02b642a4bc4
parent1e04bb374fafe4a00d0fd4b8d5a0c5588781f888 (diff)
Update pickboundingvolumejob with event forwarding
Change-Id: I6d14d4ad1bf78bf3e6d6e8b2415137a94d833c9e Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/backend/renderer.cpp7
-rw-r--r--src/render/backend/renderer_p.h2
-rw-r--r--src/render/jobs/pickboundingvolumejob.cpp77
-rw-r--r--src/render/jobs/pickboundingvolumejob_p.h6
-rw-r--r--src/render/picking/pickeventfilter.cpp21
-rw-r--r--src/render/picking/pickeventfilter_p.h7
6 files changed, 107 insertions, 13 deletions
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index 191e70392..c82ae7ec6 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -1576,7 +1576,12 @@ void Renderer::cleanGraphicsResources()
QList<QMouseEvent> Renderer::pendingPickingEvents() const
{
- return m_pickEventFilter->pendingEvents();
+ return m_pickEventFilter->pendingMouseEvents();
+}
+
+QList<QKeyEvent> Renderer::pendingKeyEvents() const
+{
+ return m_pickEventFilter->pendingKeyEvents();
}
const GraphicsApiFilterData *Renderer::contextInfo() const
diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h
index 344565173..690ce8584 100644
--- a/src/render/backend/renderer_p.h
+++ b/src/render/backend/renderer_p.h
@@ -227,8 +227,8 @@ public:
inline RenderStateSet *defaultRenderState() const { return m_defaultRenderStateSet; }
-
QList<QMouseEvent> pendingPickingEvents() const;
+ QList<QKeyEvent> pendingKeyEvents() const;
void addRenderCaptureSendRequest(Qt3DCore::QNodeId nodeId);
const QVector<Qt3DCore::QNodeId> takePendingRenderCaptureSendRequests();
diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp
index 2ce6eb92e..a7df5270f 100644
--- a/src/render/jobs/pickboundingvolumejob.cpp
+++ b/src/render/jobs/pickboundingvolumejob.cpp
@@ -58,6 +58,8 @@ namespace Render {
namespace {
+typedef PickingUtils::AbstractCollisionGathererFunctor::result_type HitList;
+
void setEventButtonAndModifiers(const QMouseEvent &event, QPickEvent::Buttons &eventButton, int &eventButtons, int &eventModifiers)
{
switch (event.button()) {
@@ -118,6 +120,11 @@ void PickBoundingVolumeJob::setMouseEvents(const QList<QMouseEvent> &pendingEven
m_pendingMouseEvents = pendingEvents;
}
+void PickBoundingVolumeJob::setKeyEvents(const QList<QKeyEvent> &pendingEvents)
+{
+ m_pendingKeyEvents = pendingEvents;
+}
+
void PickBoundingVolumeJob::setFrameGraphRoot(FrameGraphNode *frameGraphRoot)
{
m_frameGraphRoot = frameGraphRoot;
@@ -145,9 +152,10 @@ bool PickBoundingVolumeJob::runHelper()
// Move to clear the events so that we don't process them several times
// if run is called several times
const auto mouseEvents = std::move(m_pendingMouseEvents);
+ const auto keyEvents = std::move(m_pendingKeyEvents);
// If we have no events return early
- if (mouseEvents.empty())
+ if (mouseEvents.empty() && keyEvents.empty())
return false;
// bail out early if no picker is enabled
@@ -178,6 +186,23 @@ bool PickBoundingVolumeJob::runHelper()
// that the tree structure has changed
PickingUtils::EntityGatherer entitiesGatherer(m_node);
+ // Forward keyboard events
+ if (keyEvents.size() > 0) {
+ for (Entity *e : entitiesGatherer.entities()) {
+ ObjectPicker *picker = e->renderComponent<ObjectPicker>();
+ if (picker != nullptr) {
+ if (picker->isEventForwardingEnabled()) {
+ EventForward *eventForward
+ = m_manager->eventForwardManager()->lookupResource(picker->eventForward());
+ if (eventForward->focus() && eventForward->forwardKeyboardEvents()) {
+ eventForward->forward(keyEvents);
+ break;
+ }
+ }
+ }
+ }
+ }
+
// 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);
@@ -203,7 +228,6 @@ bool PickBoundingVolumeJob::runHelper()
// For each triplet of Viewport / Camera and Area
for (const PickingUtils::ViewportCameraAreaTriplet &vca : vcaTriplets) {
- typedef PickingUtils::AbstractCollisionGathererFunctor::result_type HitList;
HitList sphereHits;
QRay3D ray = rayForViewportAndCamera(vca.area, event.pos(), vca.viewport, vca.cameraId);
if (trianglePickingRequested) {
@@ -221,7 +245,8 @@ bool PickBoundingVolumeJob::runHelper()
}
// Dispatch events based on hit results
- dispatchPickEvents(event, sphereHits, eventButton, eventButtons, eventModifiers, trianglePickingRequested);
+ dispatchPickEvents(event, sphereHits, eventButton, eventButtons,
+ eventModifiers, trianglePickingRequested, ray);
}
}
@@ -249,7 +274,8 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event,
QPickEvent::Buttons eventButton,
int eventButtons,
int eventModifiers,
- bool trianglePickingRequested)
+ bool trianglePickingRequested,
+ const QRay3D &ray)
{
ObjectPicker *lastCurrentPicker = m_manager->objectPickerManager()->data(m_currentPicker);
// If we have hits
@@ -337,6 +363,49 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event,
default:
break;
}
+ if (objectPicker->isEventForwardingEnabled()) {
+ EventForward *eventForward
+ = m_manager->eventForwardManager()->lookupResource(objectPicker->eventForward());
+ QCollisionQueryResult::Hit triangleHit = hit;
+ bool valid = true;
+ if (eventForward->isEnabled() && eventForward->forwardMouseEvents()) {
+ if (!trianglePickingRequested) {
+ // Triangle picking is not enables so the triangle is not already in the
+ // query results. We need to redo the picking to get the triangle.
+ Qt3DRender::QRayCastingService rayCasting;
+ PickingUtils::TriangleCollisionGathererFunctor gathererFunctor;
+ const bool frontFaceRequested =
+ m_renderSettings->faceOrientationPickingMode() != QPickingSettings::BackFace;
+ const bool backFaceRequested =
+ m_renderSettings->faceOrientationPickingMode() != QPickingSettings::FrontFace;
+ gathererFunctor.m_frontFaceRequested = frontFaceRequested;
+ gathererFunctor.m_backFaceRequested = backFaceRequested;
+ gathererFunctor.m_manager = m_manager;
+ gathererFunctor.m_ray = ray;
+
+ // The bounding method is inaccurate so the triangle picking doesn't
+ // necessarely produce any results
+ HitList hitlist = gathererFunctor.pick(&rayCasting, entity);
+ if (hitlist.size() > 0)
+ triangleHit = hitlist.at(0);
+ else
+ valid = false;
+ }
+ if (valid) {
+ CoordinateReader reader(m_manager);
+ if (reader.setGeometry(entity->renderComponent<GeometryRenderer>(),
+ eventForward->coordinateAttribute())) {
+ QVector4D c0 = reader.getCoordinate(triangleHit.m_vertexIndex[0]);
+ QVector4D c1 = reader.getCoordinate(triangleHit.m_vertexIndex[1]);
+ QVector4D c2 = reader.getCoordinate(triangleHit.m_vertexIndex[2]);
+ QVector4D ci = c2 * triangleHit.m_uvw.x()
+ + c1 * triangleHit.m_uvw.y() + c0 * triangleHit.m_uvw.z();
+ ci.setW(1.0f);
+ eventForward->forward(event, ci);
+ }
+ }
+ }
+ }
}
// The ObjectPicker was hit -> it is still being hovered
diff --git a/src/render/jobs/pickboundingvolumejob_p.h b/src/render/jobs/pickboundingvolumejob_p.h
index 913a5ace0..90a0bdbda 100644
--- a/src/render/jobs/pickboundingvolumejob_p.h
+++ b/src/render/jobs/pickboundingvolumejob_p.h
@@ -59,6 +59,7 @@
#include <Qt3DRender/private/pickboundingvolumeutils_p.h>
#include <Qt3DRender/qpickevent.h>
#include <QMouseEvent>
+#include <QKeyEvent>
#include <QSharedPointer>
QT_BEGIN_NAMESPACE
@@ -85,6 +86,7 @@ public:
void setRoot(Entity *root);
void setMouseEvents(const QList<QMouseEvent> &pendingEvents);
+ void setKeyEvents(const QList<QKeyEvent> &pendingEvents);
void setFrameGraphRoot(FrameGraphNode *frameGraphRoot);
void setRenderSettings(RenderSettings *settings);
void setManagers(NodeManagers *manager);
@@ -104,7 +106,8 @@ protected:
void dispatchPickEvents(const QMouseEvent &event, const PickingUtils::CollisionVisitor::HitList &sphereHits,
QPickEvent::Buttons eventButton,
int eventButtons,
- int eventModifiers, bool trianglePickingRequested);
+ int eventModifiers, bool trianglePickingRequested,
+ const QRay3D &ray);
private:
NodeManagers *m_manager;
@@ -112,6 +115,7 @@ private:
FrameGraphNode *m_frameGraphRoot;
RenderSettings *m_renderSettings;
QList<QMouseEvent> m_pendingMouseEvents;
+ QList<QKeyEvent> m_pendingKeyEvents;
void viewMatrixForCamera(Qt3DCore::QNodeId cameraId,
QMatrix4x4 &viewMatrix,
diff --git a/src/render/picking/pickeventfilter.cpp b/src/render/picking/pickeventfilter.cpp
index a1ae52068..19d3b6b6e 100644
--- a/src/render/picking/pickeventfilter.cpp
+++ b/src/render/picking/pickeventfilter.cpp
@@ -61,11 +61,19 @@ PickEventFilter::~PickEventFilter()
Called from a worker thread in the thread pool so be sure to
mutex protect the data.
*/
-QList<QMouseEvent> PickEventFilter::pendingEvents()
+QList<QMouseEvent> PickEventFilter::pendingMouseEvents()
{
QMutexLocker locker(&m_mutex);
- QList<QMouseEvent> pendingEvents(m_pendingEvents);
- m_pendingEvents.clear();
+ QList<QMouseEvent> pendingEvents(m_pendingMouseEvents);
+ m_pendingMouseEvents.clear();
+ return pendingEvents;
+}
+
+QList<QKeyEvent> PickEventFilter::pendingKeyEvents()
+{
+ QMutexLocker locker(&m_mutex);
+ QList<QKeyEvent> pendingEvents(m_pendingKeyEvents);
+ m_pendingKeyEvents.clear();
return pendingEvents;
}
@@ -82,7 +90,12 @@ bool PickEventFilter::eventFilter(QObject *obj, QEvent *e)
case QEvent::MouseMove:
case QEvent::HoverMove: {
QMutexLocker locker(&m_mutex);
- m_pendingEvents.push_back(QMouseEvent(*static_cast<QMouseEvent *>(e)));
+ m_pendingMouseEvents.push_back(QMouseEvent(*static_cast<QMouseEvent *>(e)));
+ } break;
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease: {
+ QMutexLocker locker(&m_mutex);
+ m_pendingKeyEvents.push_back(QKeyEvent(*static_cast<QKeyEvent *>(e)));
}
default:
break;
diff --git a/src/render/picking/pickeventfilter_p.h b/src/render/picking/pickeventfilter_p.h
index df94a3085..fc4b00ddc 100644
--- a/src/render/picking/pickeventfilter_p.h
+++ b/src/render/picking/pickeventfilter_p.h
@@ -53,6 +53,7 @@
#include <QObject>
#include <QMouseEvent>
+#include <QKeyEvent>
#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
@@ -68,13 +69,15 @@ public:
explicit PickEventFilter(QObject *parent = nullptr);
~PickEventFilter();
- QList<QMouseEvent> pendingEvents();
+ QList<QMouseEvent> pendingMouseEvents();
+ QList<QKeyEvent> pendingKeyEvents();
protected:
bool eventFilter(QObject *obj, QEvent *e) Q_DECL_FINAL;
private:
- QList<QMouseEvent> m_pendingEvents;
+ QList<QMouseEvent> m_pendingMouseEvents;
+ QList<QKeyEvent> m_pendingKeyEvents;
QMutex m_mutex;
};