diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2018-05-31 13:04:37 +0200 |
---|---|---|
committer | Andy Nichols <andy.nichols@qt.io> | 2018-06-01 07:24:02 +0000 |
commit | c42da985512cbbf013f6a5f9823f83a2a9836c53 (patch) | |
tree | b66ea03038e4e61c3a9299ad766e66ce09572736 | |
parent | 12b6afa18edb5fc25fceacb3305f1e064795f6b1 (diff) |
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 <andy.nichols@qt.io>
-rw-r--r-- | src/runtime/q3dsengine.cpp | 2 | ||||
-rw-r--r-- | src/runtime/q3dsinputmanager.cpp | 82 | ||||
-rw-r--r-- | src/runtime/q3dsinputmanager_p.h | 4 | ||||
-rw-r--r-- | src/runtime/q3dslogging.cpp | 3 | ||||
-rw-r--r-- | src/runtime/q3dslogging_p.h | 1 | ||||
-rw-r--r-- | tests/scenes/behaviors/actionevent.uip | 2 | ||||
-rw-r--r-- | tests/scenes/behaviors/simpleinput.uip | 45 |
7 files changed, 104 insertions, 35 deletions
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<QLoggingCategory &>(lcUipProp()).setEnabled(QtDebugMsg, logValueChanges); + // same for q3ds.input + const_cast<QLoggingCategory &>(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 <QtGui/QMouseEvent> #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 <QtCore/QObject> #include <QtCore/QSize> +#include <QtCore/QQueue> #include <Qt3DRender/QRayCaster> QT_BEGIN_NAMESPACE @@ -100,10 +101,9 @@ private: QPoint pos; InputState inputState; }; - QVector<PickRequest> m_pickRequests; + QQueue<PickRequest> 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<QLoggingCategory &>(lcAnim()).setEnabled(QtDebugMsg, enabled); const_cast<QLoggingCategory &>(lcPerf()).setEnabled(QtDebugMsg, enabled); const_cast<QLoggingCategory &>(lcSlidePlayer()).setEnabled(QtDebugMsg, enabled); + const_cast<QLoggingCategory &>(lcInput()).setEnabled(QtDebugMsg, enabled); const_cast<QLoggingCategory &>(lcProf()).setEnabled(QtDebugMsg, enabled); const_cast<QLoggingCategory &>(lcStudio3D()).setEnabled(QtDebugMsg, enabled); const_cast<QLoggingCategory &>(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 @@ <?xml version="1.0" encoding="UTF-8" ?> -<UIP version="3" > +<UIP version="4" > <Project > <ProjectSettings author="" company="" presentationWidth="1366" presentationHeight="768" maintainAspect="False" > <CustomColors count="16" >#ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff</CustomColors> 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 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<UIP version="4" > + <Project > + <ProjectSettings author="" company="" presentationWidth="800" presentationHeight="480" maintainAspect="False" > + <CustomColors count="16" >#ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff</CustomColors> + </ProjectSettings> + <Graph > + <Scene id="Scene" backgroundcolor="0.929412 0.956863 0.34902" > + <Layer id="Layer" > + <Camera id="Camera" /> + <Light id="Light" /> + <Model id="Cone" > + <Material id="Material_003" /> + </Model> + <Text id="Text2" /> + <Text id="Text3" /> + <Model id="Sphere2" > + <Material id="Default" name="Default" /> + </Model> + </Layer> + </Scene> + </Graph> + <Logic > + <State name="Master Slide" component="#Scene" > + <Add ref="#Layer" /> + <Add ref="#Camera" position="0 -40 -600" rotation="-10 0 -10" /> + <Add ref="#Light" /> + <State id="Scene-Slide1" name="Slide1" playmode="Looping" > + <Add ref="#Cone" name="Cone" rotation="-47.4815 2.69907 11.9215" sourcepath="#Cone" > + <Action id="Cone-Action" eyeball="True" triggerObject="#Cone" event="onPressureDown" targetObject="#Scene" handler="Next Slide" /> + </Add> + <Add ref="#Material_003" diffuse="0.890196 0.341176 0.615686" /> + <Add ref="#Text2" name="Text2" font="TitilliumWeb-Regular" position="-22.6025 107.143 0" textstring="Press for next slide" /> + </State> + <State id="Scene-Slide2" name="Slide2" initialplaystate="Play" playmode="Stop at end" playthroughto="Previous" > + <Add ref="#Text3" name="Text3" font="TitilliumWeb-Regular" position="-0.443962 367.803 0" textstring="Previous slide" /> + <Add ref="#Sphere2" name="Sphere2" position="-16.1459 261.794 0" sourcepath="#Sphere" > + <Action id="Sphere2-Action" eyeball="True" triggerObject="#Sphere2" event="onPressureDown" targetObject="#Scene" handler="Previous Slide" /> + </Add> + <Add ref="#Default" /> + </State> + </State> + </Logic> + </Project> +</UIP> |