summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2015-12-08 12:06:12 +0000
committerMike Krus <mike.krus@kdab.com>2016-01-25 09:03:41 +0000
commit4ad00b344bc79e34f2ba2f8355e65c7948791389 (patch)
tree277ff0f997b962ccb6034728e780cbf77f60c643
parentd798eb52ae1b22fa38d398cdae0012a34cb51922 (diff)
Expose picking details to front end
Intersection (world and local) and distance added to pick event Modified test so that it includes the event Change-Id: I8631d626e5108d2e044374ee3425625f5588c38c Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/quick3d/imports/render/qt3dquick3drenderplugin.cpp2
-rw-r--r--src/render/jobs/pickboundingvolumejob.cpp64
-rw-r--r--src/render/jobs/pickboundingvolumejob_p.h27
-rw-r--r--src/render/picking/objectpicker.cpp10
-rw-r--r--src/render/picking/objectpicker_p.h9
-rw-r--r--src/render/picking/qobjectpicker.cpp12
-rw-r--r--src/render/picking/qobjectpicker.h6
-rw-r--r--src/render/picking/qpickevent.cpp31
-rw-r--r--src/render/picking/qpickevent.h14
-rw-r--r--src/render/raycasting/qabstractcollisionqueryservice.cpp4
-rw-r--r--src/render/raycasting/qabstractcollisionqueryservice_p.h2
-rw-r--r--src/render/raycasting/qcollisionqueryresult.cpp17
-rw-r--r--src/render/raycasting/qcollisionqueryresult_p.h42
-rw-r--r--src/render/raycasting/qraycastingservice.cpp4
-rw-r--r--tests/auto/render/objectpicker/tst_objectpicker.cpp8
-rw-r--r--tests/auto/render/picking/tst_picking.cpp12
-rw-r--r--tests/auto/render/qobjectpicker/tst_qobjectpicker.cpp24
17 files changed, 202 insertions, 86 deletions
diff --git a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
index cc2fe9212..1a0d2f800 100644
--- a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
+++ b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
@@ -103,6 +103,7 @@
#include <Qt3DRender/qconegeometry.h>
#include <Qt3DRender/qcylindergeometry.h>
#include <Qt3DRender/qobjectpicker.h>
+#include <Qt3DRender/qpickevent.h>
#include <Qt3DRender/qboundingvolumespecifier.h>
#include <Qt3DRender/qboundingvolumedebug.h>
#include <Qt3DRender/qfrustumculling.h>
@@ -240,6 +241,7 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri)
// Picking
qmlRegisterType<Qt3DRender::QObjectPicker>(uri, 2, 0, "ObjectPicker");
+ qmlRegisterUncreatableType<Qt3DRender::QPickEvent>(uri, 2, 0, "PickEvent", QStringLiteral("Events cannot be created"));
// Meshes
qmlRegisterType<Qt3DRender::QMesh>(uri, 2, 0, "Mesh");
diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp
index b0d0ab865..c592b348f 100644
--- a/src/render/jobs/pickboundingvolumejob.cpp
+++ b/src/render/jobs/pickboundingvolumejob.cpp
@@ -35,6 +35,7 @@
****************************************************************************/
#include "pickboundingvolumejob_p.h"
+#include "qpickevent.h"
#include <Qt3DRender/private/renderer_p.h>
#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/framegraphnode_p.h>
@@ -260,19 +261,19 @@ void PickBoundingVolumeJob::run()
m_hoveredPickersToClear = m_hoveredPickers;
ObjectPicker *lastCurrentPicker = m_manager->objectPickerManager()->data(m_currentPicker);
Q_FOREACH (const ViewportCameraPair &vc, vcPairs) {
- QVector<Qt3DCore::QNodeId> sphereHits = sphereHitsForViewportAndCamera(event.pos(),
- vc.viewport,
- vc.cameraId,
- rayCasting,
- &sphereGatherer);
+ QVector<QCollisionQueryResult::Hit> sphereHits = sphereHitsForViewportAndCamera(event.pos(),
+ vc.viewport,
+ vc.cameraId,
+ rayCasting,
+ &sphereGatherer);
#if 0
- Q_FOREACH (const Qt3DCore::QNodeId sphereEntityId, sphereHits) {
+ Q_FOREACH (const Qt3DCore::QCollisionQueryResult::Hit sphereHit, sphereHits) {
if (triangleHitsForViewportAndCamera(event.pos(),
vc.viewport,
vc.cameraId,
- sphereEntityId,
+ sphereHit.m_entityId,
rayCasting).isEmpty())
- sphereHits.removeAll(sphereEntityId);
+ sphereHits.removeAll(sphereHit);
}
#endif
@@ -286,8 +287,8 @@ void PickBoundingVolumeJob::run()
// We want to gather hits against triangles
// build a triangle based bounding volume
- Q_FOREACH (const Qt3DCore::QNodeId &entityId, sphereHits) {
- Entity *entity = m_manager->renderNodesManager()->lookupResource(entityId);
+ Q_FOREACH (const QCollisionQueryResult::Hit &hit, sphereHits) {
+ Entity *entity = m_manager->renderNodesManager()->lookupResource(hit.m_entityId);
HObjectPicker objectPickerHandle = entity->componentHandle<ObjectPicker, 16>();
// If the Entity which actually received the hit doesn't have
@@ -302,26 +303,31 @@ void PickBoundingVolumeJob::run()
if (objectPicker != Q_NULLPTR) {
// Send the corresponding event
+ QVector3D localIntersection = hit.m_intersection;
+ if (entity && entity->worldTransform())
+ localIntersection = hit.m_intersection * entity->worldTransform()->inverted();
+ QPickEventPtr pickEvent(new QPickEvent(hit.m_intersection, localIntersection, hit.m_distance));
+
switch (event.type()) {
case QEvent::MouseButtonPress: {
// Store pressed object handle
m_currentPicker = objectPickerHandle;
// Send pressed event to m_currentPicker
- objectPicker->onPressed();
+ objectPicker->onPressed(pickEvent);
}
break;
case QEvent::MouseButtonRelease: {
// Send release event to m_currentPicker
if (lastCurrentPicker != Q_NULLPTR) {
- lastCurrentPicker->onClicked();
- lastCurrentPicker->onReleased();
+ lastCurrentPicker->onClicked(pickEvent);
+ lastCurrentPicker->onReleased(pickEvent);
}
break;
}
case Qt::TapGesture: {
- objectPicker->onClicked();
+ objectPicker->onClicked(pickEvent);
break;
}
@@ -354,8 +360,10 @@ void PickBoundingVolumeJob::run()
switch (event.type()) {
case QEvent::MouseButtonRelease: {
// Send release event to m_currentPicker
- if (lastCurrentPicker != Q_NULLPTR)
- lastCurrentPicker->onReleased();
+ if (lastCurrentPicker != Q_NULLPTR) {
+ QPickEventPtr pickEvent(new QPickEvent);
+ lastCurrentPicker->onReleased(pickEvent);
+ }
break;
}
default:
@@ -409,11 +417,11 @@ QRect PickBoundingVolumeJob::windowViewport(const QRectF &relativeViewport) cons
}
-QVector<Qt3DCore::QNodeId> PickBoundingVolumeJob::sphereHitsForViewportAndCamera(const QPoint &pos,
- const QRectF &relativeViewport,
- const Qt3DCore::QNodeId &cameraId,
- QAbstractCollisionQueryService *rayCasting,
- QBoundingVolumeProvider *volumeProvider) const
+QVector<QCollisionQueryResult::Hit> PickBoundingVolumeJob::sphereHitsForViewportAndCamera(const QPoint &pos,
+ const QRectF &relativeViewport,
+ const Qt3DCore::QNodeId &cameraId,
+ QAbstractCollisionQueryService *rayCasting,
+ QBoundingVolumeProvider *volumeProvider) const
{
QMatrix4x4 viewMatrix;
QMatrix4x4 projectionMatrix;
@@ -428,14 +436,14 @@ QVector<Qt3DCore::QNodeId> PickBoundingVolumeJob::sphereHitsForViewportAndCamera
const Qt3DCore::QRay3D ray = intersectionRay(glCorrectPos, viewMatrix, projectionMatrix, viewport);
const QQueryHandle rayCastingHandle = rayCasting->query(ray, QAbstractCollisionQueryService::AllHits, volumeProvider);
const QCollisionQueryResult queryResult = rayCasting->fetchResult(rayCastingHandle);
- return queryResult.entitiesHit();
+ return queryResult.hits();
}
-QVector<Qt3DCore::QNodeId> PickBoundingVolumeJob::triangleHitsForViewportAndCamera(const QPoint &pos,
- const QRectF &relativeViewport,
- const Qt3DCore::QNodeId &cameraId,
- const Qt3DCore::QNodeId &entityId,
- QAbstractCollisionQueryService *rayCasting) const
+QVector<QCollisionQueryResult::Hit> PickBoundingVolumeJob::triangleHitsForViewportAndCamera(const QPoint &pos,
+ const QRectF &relativeViewport,
+ const Qt3DCore::QNodeId &cameraId,
+ const Qt3DCore::QNodeId &entityId,
+ QAbstractCollisionQueryService *rayCasting) const
{
QMatrix4x4 viewMatrix;
QMatrix4x4 projectionMatrix;
@@ -457,7 +465,7 @@ QVector<Qt3DCore::QNodeId> PickBoundingVolumeJob::triangleHitsForViewportAndCame
QAbstractCollisionQueryService::AllHits,
&boundingVolumeProvider);
const QCollisionQueryResult queryResult = rayCasting->fetchResult(rayCastingHandle);
- return queryResult.entitiesHit();
+ return queryResult.hits();
}
void PickBoundingVolumeJob::clearPreviouslyHoveredPickers()
diff --git a/src/render/jobs/pickboundingvolumejob_p.h b/src/render/jobs/pickboundingvolumejob_p.h
index 11a7a1596..37f5bcc41 100644
--- a/src/render/jobs/pickboundingvolumejob_p.h
+++ b/src/render/jobs/pickboundingvolumejob_p.h
@@ -49,11 +49,12 @@
//
#include <Qt3DCore/qaspectjob.h>
-#include <Qt3DRender/private/qboundingvolumeprovider_p.h>
-#include <Qt3DRender/private/handle_types_p.h>
#include <Qt3DCore/qray3d.h>
-#include <QSharedPointer>
+#include <Qt3DRender/private/handle_types_p.h>
+#include <Qt3DRender/private/qboundingvolumeprovider_p.h>
+#include <Qt3DRender/private/qcollisionqueryresult_p.h>
#include <QMouseEvent>
+#include <QSharedPointer>
QT_BEGIN_NAMESPACE
@@ -95,16 +96,16 @@ private:
QMatrix4x4 &viewMatrix,
QMatrix4x4 &projectionMatrix) const;
QRect windowViewport(const QRectF &relativeViewport) const;
- QVector<Qt3DCore::QNodeId> sphereHitsForViewportAndCamera(const QPoint &pos,
- const QRectF &relativeViewport,
- const Qt3DCore::QNodeId &cameraId,
- Qt3DRender::QAbstractCollisionQueryService *rayCasting,
- Qt3DRender::QBoundingVolumeProvider *volumeProvider) const;
- QVector<Qt3DCore::QNodeId> triangleHitsForViewportAndCamera(const QPoint &pos,
- const QRectF &relativeViewport,
- const Qt3DCore::QNodeId &cameraId,
- const Qt3DCore::QNodeId &entityId,
- Qt3DRender::QAbstractCollisionQueryService *rayCasting) const;
+ QVector<QCollisionQueryResult::Hit> sphereHitsForViewportAndCamera(const QPoint &pos,
+ const QRectF &relativeViewport,
+ const Qt3DCore::QNodeId &cameraId,
+ QAbstractCollisionQueryService *rayCasting,
+ QBoundingVolumeProvider *volumeProvider) const;
+ QVector<QCollisionQueryResult::Hit> triangleHitsForViewportAndCamera(const QPoint &pos,
+ const QRectF &relativeViewport,
+ const Qt3DCore::QNodeId &cameraId,
+ const Qt3DCore::QNodeId &entityId,
+ QAbstractCollisionQueryService *rayCasting) const;
void clearPreviouslyHoveredPickers();
HObjectPicker m_currentPicker;
QVector<HObjectPicker> m_hoveredPickers;
diff --git a/src/render/picking/objectpicker.cpp b/src/render/picking/objectpicker.cpp
index c2f8a354f..c6f278117 100644
--- a/src/render/picking/objectpicker.cpp
+++ b/src/render/picking/objectpicker.cpp
@@ -35,6 +35,7 @@
****************************************************************************/
#include "objectpicker_p.h"
+#include "qpickevent.h"
#include <Qt3DRender/qobjectpicker.h>
#include <Qt3DRender/qattribute.h>
#include <Qt3DCore/qscenepropertychange.h>
@@ -105,27 +106,30 @@ bool ObjectPicker::hoverEnabled() const
return m_hoverEnabled;
}
-void ObjectPicker::onClicked()
+void ObjectPicker::onClicked(QPickEventPtr event)
{
Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, peerUuid()));
e->setPropertyName("clicked");
e->setTargetNode(peerUuid());
+ e->setValue(QVariant::fromValue(event));
notifyObservers(e);
}
-void ObjectPicker::onPressed()
+void ObjectPicker::onPressed(QPickEventPtr event)
{
Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, peerUuid()));
e->setPropertyName("pressed");
e->setTargetNode(peerUuid());
+ e->setValue(QVariant::fromValue(event));
notifyObservers(e);
}
-void ObjectPicker::onReleased()
+void ObjectPicker::onReleased(QPickEventPtr event)
{
Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, peerUuid()));
e->setPropertyName("released");
e->setTargetNode(peerUuid());
+ e->setValue(QVariant::fromValue(event));
notifyObservers(e);
}
diff --git a/src/render/picking/objectpicker_p.h b/src/render/picking/objectpicker_p.h
index 545c7ff95..3477f0e74 100644
--- a/src/render/picking/objectpicker_p.h
+++ b/src/render/picking/objectpicker_p.h
@@ -54,6 +54,9 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
+class QPickEvent;
+typedef QSharedPointer<QPickEvent> QPickEventPtr;
+
namespace Render {
class Q_AUTOTEST_EXPORT ObjectPicker : public Qt3DCore::QBackendNode
@@ -70,9 +73,9 @@ public:
void makeDirty();
bool hoverEnabled() const;
- void onClicked();
- void onPressed();
- void onReleased();
+ void onClicked(QPickEventPtr event);
+ void onPressed(QPickEventPtr event);
+ void onReleased(QPickEventPtr event);
void onEntered();
void onExited();
diff --git a/src/render/picking/qobjectpicker.cpp b/src/render/picking/qobjectpicker.cpp
index 96b3bb9f6..2db315dd6 100644
--- a/src/render/picking/qobjectpicker.cpp
+++ b/src/render/picking/qobjectpicker.cpp
@@ -175,14 +175,14 @@ void QObjectPicker::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
// to emit the correct signals
const QByteArray propertyName = e->propertyName();
if (propertyName == QByteArrayLiteral("pressed")) {
- QPickEvent e;
- d->pressedEvent(&e);
+ QPickEventPtr ev = e->value().value<QPickEventPtr>();
+ d->pressedEvent(ev.data());
} else if (propertyName == QByteArrayLiteral("released")) {
- QPickEvent e;
- d->releasedEvent(&e);
+ QPickEventPtr ev = e->value().value<QPickEventPtr>();
+ d->releasedEvent(ev.data());
} else if (propertyName == QByteArrayLiteral("clicked")) {
- QPickEvent e;
- d->clickedEvent(&e);
+ QPickEventPtr ev = e->value().value<QPickEventPtr>();
+ d->clickedEvent(ev.data());
} else if (propertyName == QByteArrayLiteral("entered")) {
emit entered();
setContainsMouse(true);
diff --git a/src/render/picking/qobjectpicker.h b/src/render/picking/qobjectpicker.h
index b64fb2694..cf8e3e6ff 100644
--- a/src/render/picking/qobjectpicker.h
+++ b/src/render/picking/qobjectpicker.h
@@ -68,9 +68,9 @@ public Q_SLOTS:
void setHoverEnabled(bool hoverEnabled);
Q_SIGNALS:
- void pressed(Qt3DRender::QPickEvent *event);
- void released(Qt3DRender::QPickEvent *event);
- void clicked(Qt3DRender::QPickEvent *event);
+ void pressed(Qt3DRender::QPickEvent *pick);
+ void released(Qt3DRender::QPickEvent *pick);
+ void clicked(Qt3DRender::QPickEvent *pick);
void entered();
void exited();
void hoverEnabledChanged(bool hoverEnabled);
diff --git a/src/render/picking/qpickevent.cpp b/src/render/picking/qpickevent.cpp
index e90bc24c0..420bab16f 100644
--- a/src/render/picking/qpickevent.cpp
+++ b/src/render/picking/qpickevent.cpp
@@ -47,10 +47,14 @@ public:
QPickEventPrivate()
: QObjectPrivate()
, m_accepted(true)
+ , m_distance(-1.f)
{
}
bool m_accepted;
+ QVector3D m_worldIntersection;
+ QVector3D m_localIntersection;
+ float m_distance;
};
QPickEvent::QPickEvent()
@@ -58,6 +62,15 @@ QPickEvent::QPickEvent()
{
}
+QPickEvent::QPickEvent(const QVector3D &intersection, const QVector3D &localIntersection, float distance)
+ : QObject(*new QPickEventPrivate())
+{
+ Q_D(QPickEvent);
+ d->m_distance = distance;
+ d->m_worldIntersection = intersection;
+ d->m_localIntersection = localIntersection;
+}
+
QPickEvent::~QPickEvent()
{
}
@@ -77,6 +90,24 @@ void QPickEvent::setAccepted(bool accepted)
}
}
+float QPickEvent::distance() const
+{
+ Q_D(const QPickEvent);
+ return d->m_distance;
+}
+
+const QVector3D &QPickEvent::worldIntersection() const
+{
+ Q_D(const QPickEvent);
+ return d->m_worldIntersection;
+}
+
+const QVector3D &QPickEvent::localIntersection() const
+{
+ Q_D(const QPickEvent);
+ return d->m_localIntersection;
+}
+
} // Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/picking/qpickevent.h b/src/render/picking/qpickevent.h
index 793377ad8..4734a912d 100644
--- a/src/render/picking/qpickevent.h
+++ b/src/render/picking/qpickevent.h
@@ -38,6 +38,7 @@
#define QT3DRENDER_QPICKEVENT_H
#include <QObject>
+#include <QVector3D>
#include <Qt3DRender/qt3drender_global.h>
QT_BEGIN_NAMESPACE
@@ -46,12 +47,19 @@ namespace Qt3DRender {
class QPickEventPrivate;
+class QPickEvent;
+typedef QSharedPointer<QPickEvent> QPickEventPtr;
+
class QT3DRENDERSHARED_EXPORT QPickEvent : public QObject
{
Q_OBJECT
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted NOTIFY acceptedChanged)
+ Q_PROPERTY(float distance READ distance CONSTANT)
+ Q_PROPERTY(QVector3D localIntersection READ localIntersection CONSTANT)
+ Q_PROPERTY(QVector3D worldIntersection READ worldIntersection CONSTANT)
public:
QPickEvent();
+ QPickEvent(const QVector3D& worldIntersection, const QVector3D& localIntersection, float distance);
~QPickEvent();
bool isAccepted() const;
@@ -59,6 +67,10 @@ public:
public Q_SLOTS:
void setAccepted(bool accepted);
+ float distance() const;
+ const QVector3D &worldIntersection() const;
+ const QVector3D &localIntersection() const;
+
Q_SIGNALS:
void acceptedChanged(bool accepted);
@@ -70,4 +82,6 @@ private:
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(Qt3DRender::QPickEvent*)
+
#endif // QT3DRENDER_QPICKEVENT_H
diff --git a/src/render/raycasting/qabstractcollisionqueryservice.cpp b/src/render/raycasting/qabstractcollisionqueryservice.cpp
index e28b3a7ea..8f756b2ce 100644
--- a/src/render/raycasting/qabstractcollisionqueryservice.cpp
+++ b/src/render/raycasting/qabstractcollisionqueryservice.cpp
@@ -57,9 +57,9 @@ void QAbstractCollisionQueryService::setResultHandle(QCollisionQueryResult &resu
result.d_func()->setHandle(handle);
}
-void QAbstractCollisionQueryService::addEntityHit(QCollisionQueryResult &result, const Qt3DCore::QNodeId &entity)
+void QAbstractCollisionQueryService::addEntityHit(QCollisionQueryResult &result, const Qt3DCore::QNodeId &entity, const QVector3D& intersection, float distance)
{
- result.d_func()->addEntityHit(entity);
+ result.d_func()->addEntityHit(entity, intersection, distance);
}
} // Qt3DRender
diff --git a/src/render/raycasting/qabstractcollisionqueryservice_p.h b/src/render/raycasting/qabstractcollisionqueryservice_p.h
index 8a6042bf7..051946d5e 100644
--- a/src/render/raycasting/qabstractcollisionqueryservice_p.h
+++ b/src/render/raycasting/qabstractcollisionqueryservice_p.h
@@ -92,7 +92,7 @@ protected:
QAbstractCollisionQueryService(QAbstractCollisionQueryServicePrivate &dd);
void setResultHandle(QCollisionQueryResult &result, const QQueryHandle &handle);
- void addEntityHit(QCollisionQueryResult &result, const Qt3DCore::QNodeId &entity);
+ void addEntityHit(QCollisionQueryResult &result, const Qt3DCore::QNodeId &entity, const QVector3D &intersection, float distance);
private:
Q_DECLARE_PRIVATE(QAbstractCollisionQueryService)
diff --git a/src/render/raycasting/qcollisionqueryresult.cpp b/src/render/raycasting/qcollisionqueryresult.cpp
index cf2ea0a9a..e4dc24ebd 100644
--- a/src/render/raycasting/qcollisionqueryresult.cpp
+++ b/src/render/raycasting/qcollisionqueryresult.cpp
@@ -48,13 +48,13 @@ QCollisionQueryResultPrivate::QCollisionQueryResultPrivate()
QCollisionQueryResultPrivate::QCollisionQueryResultPrivate(const QCollisionQueryResultPrivate &copy)
: QSharedData(copy)
, m_handle(copy.m_handle)
- , m_entitiesHit(copy.m_entitiesHit)
+ , m_hits(copy.m_hits)
{
}
-void QCollisionQueryResultPrivate::addEntityHit(const Qt3DCore::QNodeId &entity)
+void QCollisionQueryResultPrivate::addEntityHit(const Qt3DCore::QNodeId &entity, const QVector3D& intersection, float distance)
{
- m_entitiesHit.append(entity);
+ m_hits.append(QCollisionQueryResult::Hit(entity, intersection, distance));
}
void QCollisionQueryResultPrivate::setHandle(const QQueryHandle &handle)
@@ -82,10 +82,19 @@ QCollisionQueryResult &QCollisionQueryResult::operator=(const QCollisionQueryRes
return *this;
}
+QVector<QCollisionQueryResult::Hit> QCollisionQueryResult::hits() const
+{
+ Q_D(const QCollisionQueryResult);
+ return d->m_hits;
+}
+
QVector<Qt3DCore::QNodeId> QCollisionQueryResult::entitiesHit() const
{
Q_D(const QCollisionQueryResult);
- return d->m_entitiesHit;
+ QVector<Qt3DCore::QNodeId> result;
+ Q_FOREACH (const Hit& hit, d->m_hits)
+ result << hit.m_entityId;
+ return result;
}
/*!
diff --git a/src/render/raycasting/qcollisionqueryresult_p.h b/src/render/raycasting/qcollisionqueryresult_p.h
index c4eb164ff..21035e6a8 100644
--- a/src/render/raycasting/qcollisionqueryresult_p.h
+++ b/src/render/raycasting/qcollisionqueryresult_p.h
@@ -51,6 +51,7 @@
#include <Qt3DRender/qt3drender_global.h>
#include <Qt3DCore/qnodeid.h>
#include <QVector>
+#include <QVector3D>
#include <QSharedData>
QT_BEGIN_NAMESPACE
@@ -58,23 +59,19 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
typedef int QQueryHandle;
-
-class QCollisionQueryResultPrivate : public QSharedData
-{
-public:
- explicit QCollisionQueryResultPrivate();
- explicit QCollisionQueryResultPrivate(const QCollisionQueryResultPrivate &copy);
-
- void setHandle(const QQueryHandle &handle);
- void addEntityHit(const Qt3DCore::QNodeId &entity);
-
- QQueryHandle m_handle;
- QVector<Qt3DCore::QNodeId> m_entitiesHit;
-};
+class QCollisionQueryResultPrivate;
class QT3DRENDERSHARED_EXPORT QCollisionQueryResult
{
public:
+ struct Hit {
+ Hit() : m_distance(-1.f) { }
+ Hit(const Qt3DCore::QNodeId &entity, const QVector3D &intersection, float distance) : m_entityId(entity), m_intersection(intersection), m_distance(distance) { }
+ Qt3DCore::QNodeId m_entityId;
+ QVector3D m_intersection;
+ float m_distance;
+ };
+
QCollisionQueryResult();
QCollisionQueryResult(const QCollisionQueryResult &);
~QCollisionQueryResult();
@@ -94,6 +91,7 @@ public:
}
QQueryHandle handle() const;
+ QVector<Hit> hits() const;
QVector<Qt3DCore::QNodeId> entitiesHit() const;
private:
@@ -110,6 +108,24 @@ private:
}
};
+class QCollisionQueryResultPrivate : public QSharedData
+{
+public:
+ explicit QCollisionQueryResultPrivate();
+ explicit QCollisionQueryResultPrivate(const QCollisionQueryResultPrivate &copy);
+
+ void setHandle(const QQueryHandle &handle);
+ void addEntityHit(const Qt3DCore::QNodeId &entity, const QVector3D& intersection, float distance);
+
+ QQueryHandle m_handle;
+ QVector<QCollisionQueryResult::Hit> m_hits;
+};
+
+inline bool operator==(const QCollisionQueryResult::Hit& left, const QCollisionQueryResult::Hit& right)
+{
+ return left.m_entityId == right.m_entityId;
+}
+
} // Qt3DRender
Q_DECLARE_SHARED(Qt3DRender::QCollisionQueryResult)
diff --git a/src/render/raycasting/qraycastingservice.cpp b/src/render/raycasting/qraycastingservice.cpp
index 8e897ec14..0b183f087 100644
--- a/src/render/raycasting/qraycastingservice.cpp
+++ b/src/render/raycasting/qraycastingservice.cpp
@@ -130,12 +130,12 @@ QCollisionQueryResult QRayCastingServicePrivate::collides(const Qt3DCore::QRay3D
if (mode == QAbstractCollisionQueryService::FirstHit) {
Hit firstHit = QtConcurrent::blockingMappedReduced<Hit>(volumes, gathererFunctor, reduceToFirstHit);
if (firstHit.intersects)
- q->addEntityHit(result, firstHit.id);
+ q->addEntityHit(result, firstHit.id, firstHit.intersection, firstHit.distance);
} else {
QVector<Hit> hits = QtConcurrent::blockingMappedReduced<QVector<Hit> >(volumes, gathererFunctor, reduceToAllHits);
std::sort(hits.begin(), hits.end(), compareHitsDistance);
Q_FOREACH (const Hit &hit, hits)
- q->addEntityHit(result, hit.id);
+ q->addEntityHit(result, hit.id, hit.intersection, hit.distance);
}
return result;
diff --git a/tests/auto/render/objectpicker/tst_objectpicker.cpp b/tests/auto/render/objectpicker/tst_objectpicker.cpp
index ce0314ef8..4aa770237 100644
--- a/tests/auto/render/objectpicker/tst_objectpicker.cpp
+++ b/tests/auto/render/objectpicker/tst_objectpicker.cpp
@@ -36,6 +36,7 @@
#include <QtTest/QTest>
#include <Qt3DRender/private/objectpicker_p.h>
+#include <Qt3DRender/qpickevent.h>
#include <Qt3DRender/qobjectpicker.h>
#include <Qt3DCore/private/qbackendnode_p.h>
#include <Qt3DCore/qscenepropertychange.h>
@@ -113,10 +114,11 @@ private Q_SLOTS:
TestArbiter arbiter;
Qt3DRender::Render::ObjectPicker objectPicker;
Qt3DCore::QBackendNodePrivate::get(&objectPicker)->setArbiter(&arbiter);
+ Qt3DRender::QPickEventPtr event(new Qt3DRender::QPickEvent);
QVERIFY(!objectPicker.isDirty());
// WHEN
- objectPicker.onPressed();
+ objectPicker.onPressed(event);
// THEN
QCOMPARE(arbiter.events.count(), 1);
@@ -126,7 +128,7 @@ private Q_SLOTS:
arbiter.events.clear();
// WHEN
- objectPicker.onReleased();
+ objectPicker.onReleased(event);
// THEN
QCOMPARE(arbiter.events.count(), 1);
@@ -136,7 +138,7 @@ private Q_SLOTS:
arbiter.events.clear();
// WHEN
- objectPicker.onClicked();
+ objectPicker.onClicked(event);
// THEN
QCOMPARE(arbiter.events.count(), 1);
diff --git a/tests/auto/render/picking/tst_picking.cpp b/tests/auto/render/picking/tst_picking.cpp
index 93ff2b506..cdaa5e810 100644
--- a/tests/auto/render/picking/tst_picking.cpp
+++ b/tests/auto/render/picking/tst_picking.cpp
@@ -149,8 +149,12 @@ private Q_SLOTS:
PickableEntity child11(QVector3D(), 5.0f, &child1);
// WHEN
+ Qt3DRender::QPickEventPtr event(new Qt3DRender::QPickEvent());
+ QVariant v;
+ v.setValue<Qt3DRender::QPickEventPtr>(event);
Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, child11.id()));
e->setPropertyName("pressed");
+ e->setValue(v);
child11.picker->sceneChangeEvent(e);
// THEN
@@ -193,8 +197,12 @@ private Q_SLOTS:
PickableEntity child11(QVector3D(), 5.0f, &child1);
// WHEN
+ Qt3DRender::QPickEventPtr event(new Qt3DRender::QPickEvent());
+ QVariant v;
+ v.setValue<Qt3DRender::QPickEventPtr>(event);
Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, child11.id()));
e->setPropertyName("pressed");
+ e->setValue(v);
child11.picker->sceneChangeEvent(e);
e->setPropertyName("released");
child11.picker->sceneChangeEvent(e);
@@ -233,8 +241,12 @@ private Q_SLOTS:
PickableEntity child11(QVector3D(), 5.0f, &child1);
// WHEN
+ Qt3DRender::QPickEventPtr event(new Qt3DRender::QPickEvent());
+ QVariant v;
+ v.setValue<Qt3DRender::QPickEventPtr>(event);
Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, child11.id()));
e->setPropertyName("clicked");
+ e->setValue(v);
child11.picker->sceneChangeEvent(e);
// THEN
diff --git a/tests/auto/render/qobjectpicker/tst_qobjectpicker.cpp b/tests/auto/render/qobjectpicker/tst_qobjectpicker.cpp
index a5d98d1f9..6f64b8e40 100644
--- a/tests/auto/render/qobjectpicker/tst_qobjectpicker.cpp
+++ b/tests/auto/render/qobjectpicker/tst_qobjectpicker.cpp
@@ -132,26 +132,32 @@ private Q_SLOTS:
{
QTest::addColumn<QByteArray>("signalPrototype");
QTest::addColumn<QByteArray>("propertyName");
+ QTest::addColumn<bool>("requiresEvent");
QTest::newRow("clicked")
<< QByteArray(SIGNAL(clicked(Qt3DRender::QPickEvent *)))
- << QByteArrayLiteral("clicked");
+ << QByteArrayLiteral("clicked")
+ << true;
QTest::newRow("pressed")
<< QByteArray(SIGNAL(pressed(Qt3DRender::QPickEvent *)))
- << QByteArrayLiteral("pressed");
+ << QByteArrayLiteral("pressed")
+ << true;
QTest::newRow("released")
<< QByteArray(SIGNAL(released(Qt3DRender::QPickEvent *)))
- << QByteArrayLiteral("released");
+ << QByteArrayLiteral("released")
+ << true;
QTest::newRow("entered")
<< QByteArray(SIGNAL(entered()))
- << QByteArrayLiteral("entered");
+ << QByteArrayLiteral("entered")
+ << false;
QTest::newRow("exited")
<< QByteArray(SIGNAL(exited()))
- << QByteArrayLiteral("exited");
+ << QByteArrayLiteral("exited")
+ << false;
}
void checkBackendUpdates()
@@ -159,13 +165,21 @@ private Q_SLOTS:
// GIVEN
QFETCH(QByteArray, signalPrototype);
QFETCH(QByteArray, propertyName);
+ QFETCH(bool, requiresEvent);
QScopedPointer<MyObjectPicker> objectPicker(new MyObjectPicker());
QSignalSpy spy(objectPicker.data(), signalPrototype.constData());
+ Qt3DRender::QPickEventPtr event(new Qt3DRender::QPickEvent());
// WHEN
// Create Backend Change and distribute it to frontend node
Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, objectPicker->id()));
e->setPropertyName(propertyName.constData());
+ if (requiresEvent)
+ {
+ QVariant v;
+ v.setValue<Qt3DRender::QPickEventPtr>(event);
+ e->setValue(v);
+ }
objectPicker->sceneChangeEvent(e);
// THEN