From c42da985512cbbf013f6a5f9823f83a2a9836c53 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 31 May 2018 13:04:37 +0200 Subject: Fix inputmgr ignoring presses Also adds a new logging category, disabled by default unless Q3DS_DEBUG=1 (or higher) is set. However this now highlights the fact that the raycasting thing just does not return hits half the time. Task-number: QT3DS-1588 Task-number: QT3DS-1785 Change-Id: Ib493510e14d32878168e7094cb0b0b059415e662 Reviewed-by: Andy Nichols --- src/runtime/q3dsengine.cpp | 2 + src/runtime/q3dsinputmanager.cpp | 82 +++++++++++++++++++++------------- src/runtime/q3dsinputmanager_p.h | 4 +- src/runtime/q3dslogging.cpp | 3 ++ src/runtime/q3dslogging_p.h | 1 + tests/scenes/behaviors/actionevent.uip | 2 +- tests/scenes/behaviors/simpleinput.uip | 45 +++++++++++++++++++ 7 files changed, 104 insertions(+), 35 deletions(-) create mode 100644 tests/scenes/behaviors/simpleinput.uip diff --git a/src/runtime/q3dsengine.cpp b/src/runtime/q3dsengine.cpp index b58140b..1a438f0 100644 --- a/src/runtime/q3dsengine.cpp +++ b/src/runtime/q3dsengine.cpp @@ -159,6 +159,8 @@ Q3DSEngine::Q3DSEngine() // Q3DS_DEBUG is set to 1 or higher. const bool logValueChanges = qEnvironmentVariableIntValue("Q3DS_DEBUG") >= 1; const_cast(lcUipProp()).setEnabled(QtDebugMsg, logValueChanges); + // same for q3ds.input + const_cast(lcInput()).setEnabled(QtDebugMsg, logValueChanges); } setViewerSettings(new Q3DSViewerSettings(this)); } diff --git a/src/runtime/q3dsinputmanager.cpp b/src/runtime/q3dsinputmanager.cpp index 315b27c..e2b7bc9 100644 --- a/src/runtime/q3dsinputmanager.cpp +++ b/src/runtime/q3dsinputmanager.cpp @@ -34,6 +34,7 @@ #include #include "q3dsscenemanager_p.h" +#include "q3dslogging_p.h" QT_BEGIN_NAMESPACE @@ -46,33 +47,45 @@ Q3DSInputManager::Q3DSInputManager(Q3DSSceneManager *sceneManager, QObject *pare void Q3DSInputManager::handleMousePressEvent(QMouseEvent *e) { + qCDebug(lcInput) << "mouse press" << e->pos() << "viewport pos" << convertToViewportSpace(e->pos()); m_currentState.mousePressed = true; PickRequest req(convertToViewportSpace(e->pos()), m_currentState); - m_pickRequests.append(req); + m_pickRequests.enqueue(req); } void Q3DSInputManager::handleMouseReleaseEvent(QMouseEvent *e) { + qCDebug(lcInput) << "mouse release" << e->pos() << "viewport pos" << convertToViewportSpace(e->pos()); m_currentState.mousePressed = false; PickRequest req(convertToViewportSpace(e->pos()), m_currentState); - m_pickRequests.append(req); + m_pickRequests.enqueue(req); } void Q3DSInputManager::handleMouseMoveEvent(QMouseEvent *e) { + // no scene events for mouse move at the moment so do nothing +#if 0 if (!m_isHoverEnabled && !m_currentState.mousePressed) return; PickRequest req(convertToViewportSpace(e->pos()), m_currentState); - m_pickRequests.append(req); + m_pickRequests.enqueue(req); +#else + Q_UNUSED(e); +#endif } void Q3DSInputManager::runPicks() { - for (const auto &p : m_pickRequests) - pick(p.pos, p.inputState); + if (m_pickRequests.isEmpty()) + return; - m_pickRequests.clear(); + qCDebug(lcInput, "runPicks (%d in queue)", m_pickRequests.count()); + + while (!m_pickRequests.isEmpty()) { + const PickRequest p = m_pickRequests.dequeue(); + pick(p.pos, p.inputState); + } } void Q3DSInputManager::sendMouseEvent(Q3DSGraphObject *target, @@ -83,15 +96,13 @@ void Q3DSInputManager::sendMouseEvent(Q3DSGraphObject *target, if (!target->attached()) return; - const bool isPress = inputState.mousePressed && !m_lastSentState.mousePressed; - const bool isRelease = !inputState.mousePressed && m_lastSentState.mousePressed; - - if (isPress) + if (inputState.mousePressed) { + qCDebug(lcInput) << " queuing press event on" << target->id(); m_sceneManager->queueEvent(Q3DSGraphObject::Event(target, Q3DSGraphObjectEvents::pressureDownEvent())); - if (isRelease) + } else { + qCDebug(lcInput) << " queuing release event on" << target->id(); m_sceneManager->queueEvent(Q3DSGraphObject::Event(target, Q3DSGraphObjectEvents::pressureUpEvent())); - - m_lastSentState.mousePressed = m_currentState.mousePressed; + } } namespace { @@ -173,25 +184,28 @@ void Q3DSInputManager::castNextRay(Q3DSLayerNode *layer) rayCaster->setOrigin(e.origin); rayCaster->setLength(e.length); - if (!m_connectionMap.value(e.eventId)) { - QMetaObject::Connection connection = connect(rayCaster, &Qt3DRender::QAbstractRayCaster::hitsChanged, rayCaster, - [=](const Qt3DRender::QAbstractRayCaster::Hits &hits) - { - for (auto hit : hits) { - auto node = getNodeForEntity(layer, hit.entity()); - sendMouseEvent(node, hit, e.inputState); - } - disconnect(m_connectionMap.value(e.eventId)); - m_connectionMap.remove(e.eventId); - layerData->rayCasterBusy = false; - if (!layerData->rayCastQueue.isEmpty()) { - // the stupid thing is blocking property notifications so issue the - // next raycast after the emit returns - QMetaObject::invokeMethod(this, "castNextRay", Qt::QueuedConnection, Q_ARG(Q3DSLayerNode*, layer)); - } - }); - m_connectionMap.insert(e.eventId, connection); - } + Q_ASSERT(!m_connectionMap.contains(e.eventId)); + + qCDebug(lcInput) << "setting up async raycast for eventId" << e.eventId << "layer" << layer->id(); + QMetaObject::Connection connection = connect(rayCaster, &Qt3DRender::QAbstractRayCaster::hitsChanged, rayCaster, + [=](const Qt3DRender::QAbstractRayCaster::Hits &hits) + { + qCDebug(lcInput) << "raycast result for eventId" << e.eventId << hits.count() << "hits"; + for (auto hit : hits) { + auto node = getNodeForEntity(layer, hit.entity()); + qCDebug(lcInput) << " hit node is" << node->id(); + sendMouseEvent(node, hit, e.inputState); + } + disconnect(m_connectionMap.value(e.eventId)); + m_connectionMap.remove(e.eventId); + layerData->rayCasterBusy = false; + if (!layerData->rayCastQueue.isEmpty()) { + // the stupid thing is blocking property notifications so issue the + // next raycast after the emit returns + QMetaObject::invokeMethod(this, "castNextRay", Qt::QueuedConnection, Q_ARG(Q3DSLayerNode*, layer)); + } + }); + m_connectionMap.insert(e.eventId, connection); layerData->rayCasterBusy = true; rayCaster->trigger(); @@ -258,9 +272,13 @@ void Q3DSInputManager::pick(const QPoint &point, const InputState &inputState) // OpenGL has inverted Y y = -y; + qCDebug(lcInput) << "raycast for pick" << point << x << y << "on layer" << layer->id() << m_eventId; + // Cast a ray into the layer and get hits castRayIntoLayer(layer, QPointF(x, y), inputState, m_eventId); m_eventId++; + } else { + qCDebug(lcInput) << "pick" << point << "does not intersect with layer" << layer->id(); } } } diff --git a/src/runtime/q3dsinputmanager_p.h b/src/runtime/q3dsinputmanager_p.h index b3b8b26..ad06a9e 100644 --- a/src/runtime/q3dsinputmanager_p.h +++ b/src/runtime/q3dsinputmanager_p.h @@ -44,6 +44,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -100,10 +101,9 @@ private: QPoint pos; InputState inputState; }; - QVector m_pickRequests; + QQueue m_pickRequests; InputState m_currentState; - InputState m_lastSentState; }; QT_END_NAMESPACE diff --git a/src/runtime/q3dslogging.cpp b/src/runtime/q3dslogging.cpp index 2b11ac4..d32eaab 100644 --- a/src/runtime/q3dslogging.cpp +++ b/src/runtime/q3dslogging.cpp @@ -37,6 +37,7 @@ Q3DSV_PRIVATE_EXPORT Q_LOGGING_CATEGORY(lcScene, "q3ds.scene") Q3DSV_PRIVATE_EXPORT Q_LOGGING_CATEGORY(lcAnim, "q3ds.anim") Q3DSV_PRIVATE_EXPORT Q_LOGGING_CATEGORY(lcPerf, "q3ds.perf") Q3DSV_PRIVATE_EXPORT Q_LOGGING_CATEGORY(lcSlidePlayer, "q3ds.slideplayer") +Q3DSV_PRIVATE_EXPORT Q_LOGGING_CATEGORY(lcInput, "q3ds.input") Q3DSV_PRIVATE_EXPORT Q_LOGGING_CATEGORY(lcProf, "q3ds.profileui") Q3DSV_PRIVATE_EXPORT Q_LOGGING_CATEGORY(lcStudio3D, "q3ds.studio3d") Q3DSV_PRIVATE_EXPORT Q_LOGGING_CATEGORY(lc3DSSurface, "q3ds.surface") @@ -52,6 +53,7 @@ QByteArrayList loggingCategoryNames() QByteArrayLiteral("q3ds.scene"), QByteArrayLiteral("q3ds.anim"), QByteArrayLiteral("q3ds.slideplayer"), + QByteArrayLiteral("q3ds.input"), QByteArrayLiteral("q3ds.profileui"), QByteArrayLiteral("q3ds.studio3d"), QByteArrayLiteral("q3ds.surface"), @@ -67,6 +69,7 @@ void setLogging(bool enabled) const_cast(lcAnim()).setEnabled(QtDebugMsg, enabled); const_cast(lcPerf()).setEnabled(QtDebugMsg, enabled); const_cast(lcSlidePlayer()).setEnabled(QtDebugMsg, enabled); + const_cast(lcInput()).setEnabled(QtDebugMsg, enabled); const_cast(lcProf()).setEnabled(QtDebugMsg, enabled); const_cast(lcStudio3D()).setEnabled(QtDebugMsg, enabled); const_cast(lc3DSSurface()).setEnabled(QtDebugMsg, enabled); diff --git a/src/runtime/q3dslogging_p.h b/src/runtime/q3dslogging_p.h index 11197f6..fee7589 100644 --- a/src/runtime/q3dslogging_p.h +++ b/src/runtime/q3dslogging_p.h @@ -53,6 +53,7 @@ Q3DSV_PRIVATE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcScene) Q3DSV_PRIVATE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcAnim) Q3DSV_PRIVATE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcPerf) Q3DSV_PRIVATE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcSlidePlayer) +Q3DSV_PRIVATE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcInput) Q3DSV_PRIVATE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcProf) Q3DSV_PRIVATE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcStudio3D) Q3DSV_PRIVATE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lc3DSSurface) diff --git a/tests/scenes/behaviors/actionevent.uip b/tests/scenes/behaviors/actionevent.uip index 5636ab8..b6f23ed 100644 --- a/tests/scenes/behaviors/actionevent.uip +++ b/tests/scenes/behaviors/actionevent.uip @@ -1,5 +1,5 @@ - + #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff diff --git a/tests/scenes/behaviors/simpleinput.uip b/tests/scenes/behaviors/simpleinput.uip new file mode 100644 index 0000000..beb83a9 --- /dev/null +++ b/tests/scenes/behaviors/simpleinput.uip @@ -0,0 +1,45 @@ + + + + + #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3