From 9272c77091b58399e05d2843d4e627186f906507 Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:21:12 +0200 Subject: Fix build for -no-feature-commandlineparser Change-Id: Ib84385167b2d71e460de87fbda58d59173385258 Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- tools/tools.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/tools.pro b/tools/tools.pro index 9c384630e..4dbd7496a 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -1,2 +1,2 @@ TEMPLATE = subdirs -!android:SUBDIRS += qgltf +qtConfig(commandlineparser):!android:SUBDIRS += qgltf -- cgit v1.2.3 From a6e9441c0fec1819b80cc69429de83d89680cf0a Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:18:47 +0200 Subject: Fix warnings for -no-feature-library Change-Id: I5a6713fe6081c36fdae9dcb7b7671403f737e4c0 Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- src/input/frontend/qinputdeviceintegrationfactory.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/input/frontend/qinputdeviceintegrationfactory.cpp b/src/input/frontend/qinputdeviceintegrationfactory.cpp index 052f2d2b2..957b33542 100644 --- a/src/input/frontend/qinputdeviceintegrationfactory.cpp +++ b/src/input/frontend/qinputdeviceintegrationfactory.cpp @@ -74,6 +74,7 @@ QStringList QInputDeviceIntegrationFactory::keys(const QString &pluginPath) list.append(loader()->keyMap().values()); return list; #else + Q_UNUSED(pluginPath); return QStringList(); #endif } @@ -88,6 +89,10 @@ QInputDeviceIntegration *QInputDeviceIntegrationFactory::create(const QString &n } if (QInputDeviceIntegration *ret = qLoadPlugin(loader(), name, args)) return ret; +#else + Q_UNUSED(name); + Q_UNUSED(args); + Q_UNUSED(pluginPath); #endif return nullptr; } -- cgit v1.2.3 From c5108cb5300a32ac3dd0c2c1e42dcf1d35c1ac2f Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:27:43 +0200 Subject: Fix build for -no-feature-temporaryfile Change-Id: I9e5bfc7636c10d0f0e39faf18b0b97bfb70f67d3 Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- src/plugins/sceneparsers/sceneparsers.pro | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/sceneparsers/sceneparsers.pro b/src/plugins/sceneparsers/sceneparsers.pro index befe08e41..bba802393 100644 --- a/src/plugins/sceneparsers/sceneparsers.pro +++ b/src/plugins/sceneparsers/sceneparsers.pro @@ -2,4 +2,9 @@ TEMPLATE = subdirs # QNX is not supported, and Linux GCC 4.9 on ARM chokes on the assimp # sources (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66964). config_assimp|!cross_compile: SUBDIRS += assimp -SUBDIRS += gltf gltfexport + +SUBDIRS += gltf + +qtConfig(temporaryfile) { + SUBDIRS += gltfexport +} -- cgit v1.2.3 From 34b3ea85829076b5d668c3940b1d1d7acc4b16d9 Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 13:11:00 +0200 Subject: Fix build without quick module Change-Id: I5a2a5ac0d498e8ab5568d57cd2c16e83d947fe47 Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- src/src.pro | 160 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 84 insertions(+), 76 deletions(-) diff --git a/src/src.pro b/src/src.pro index 86a885e51..46c205849 100644 --- a/src/src.pro +++ b/src/src.pro @@ -23,63 +23,65 @@ src_extras.subdir = $$PWD/extras src_extras.target = src_extras src_extras.depends = src_render src_input src_logic -# Quick3D libs -src_quick3d_core.subdir = $$PWD/quick3d/quick3d -src_quick3d_core.target = sub-quick3d-core -src_quick3d_core.depends = src_core src_input - -src_quick3d_render.subdir = $$PWD/quick3d/quick3drender -src_quick3d_render.target = sub-quick3d-render -src_quick3d_render.depends = src_render src_quick3d_core - -src_quick3d_input.subdir = $$PWD/quick3d/quick3dinput -src_quick3d_input.target = sub-quick3d-input -src_quick3d_input.depends = src_input src_quick3d_core - -src_quick3d_animation.subdir = $$PWD/quick3d/quick3danimation -src_quick3d_animation.target = sub-quick3d-animation -src_quick3d_animation.depends = src_animation src_quick3d_core src_quick3d_render - -src_quick3d_extras.subdir = $$PWD/quick3d/quick3dextras -src_quick3d_extras.target = sub-quick3d-extras -src_quick3d_extras.depends = src_render src_logic src_input src_extras src_quick3d_core - -src_quick3d_scene2d.subdir = $$PWD/quick3d/quick3dscene2d -src_quick3d_scene2d.target = sub-quick3d-scene2d -src_quick3d_scene2d.depends = src_render src_logic src_input src_quick3d_core - -# Quick3D imports -src_quick3d_core_imports.file = $$PWD/quick3d/imports/core/importscore.pro -src_quick3d_core_imports.target = sub-quick3d-imports-core -src_quick3d_core_imports.depends = src_quick3d_core - -src_quick3d_imports_render.file = $$PWD/quick3d/imports/render/importsrender.pro -src_quick3d_imports_render.target = sub-quick3d-imports-render -src_quick3d_imports_render.depends = src_quick3d_render - -src_quick3d_imports_scene3d.file = $$PWD/quick3d/imports/scene3d/importsscene3d.pro -src_quick3d_imports_scene3d.target = sub-quick3d-imports-scene3d -src_quick3d_imports_scene3d.depends = src_quick3d_render src_input - -src_quick3d_imports_input.file = $$PWD/quick3d/imports/input/importsinput.pro -src_quick3d_imports_input.target = sub-quick3d-imports-input -src_quick3d_imports_input.depends = src_input src_quick3d_input - -src_quick3d_imports_logic.file = $$PWD/quick3d/imports/logic/importslogic.pro -src_quick3d_imports_logic.target = sub-quick3d-imports-logic -src_quick3d_imports_logic.depends = src_logic - -src_quick3d_imports_animation.file = $$PWD/quick3d/imports/animation/importsanimation.pro -src_quick3d_imports_animation.target = sub-quick3d-imports-animation -src_quick3d_imports_animation.depends = src_animation src_quick3d_animation - -src_quick3d_imports_extras.file = $$PWD/quick3d/imports/extras/importsextras.pro -src_quick3d_imports_extras.target = sub-quick3d-imports-extras -src_quick3d_imports_extras.depends = src_extras src_quick3d_extras - -src_quick3d_imports_scene2d.file = $$PWD/quick3d/imports/scene2d/importsscene2d.pro -src_quick3d_imports_scene2d.target = sub-quick3d-imports-scene2d -src_quick3d_imports_scene2d.depends = src_quick3d_scene2d +qtHaveModule(quick) { + # Quick3D libs + src_quick3d_core.subdir = $$PWD/quick3d/quick3d + src_quick3d_core.target = sub-quick3d-core + src_quick3d_core.depends = src_core src_input + + src_quick3d_render.subdir = $$PWD/quick3d/quick3drender + src_quick3d_render.target = sub-quick3d-render + src_quick3d_render.depends = src_render src_quick3d_core + + src_quick3d_input.subdir = $$PWD/quick3d/quick3dinput + src_quick3d_input.target = sub-quick3d-input + src_quick3d_input.depends = src_input src_quick3d_core + + src_quick3d_animation.subdir = $$PWD/quick3d/quick3danimation + src_quick3d_animation.target = sub-quick3d-animation + src_quick3d_animation.depends = src_animation src_quick3d_core src_quick3d_render + + src_quick3d_extras.subdir = $$PWD/quick3d/quick3dextras + src_quick3d_extras.target = sub-quick3d-extras + src_quick3d_extras.depends = src_render src_logic src_input src_extras src_quick3d_core + + src_quick3d_scene2d.subdir = $$PWD/quick3d/quick3dscene2d + src_quick3d_scene2d.target = sub-quick3d-scene2d + src_quick3d_scene2d.depends = src_render src_logic src_input src_quick3d_core + + # Quick3D imports + src_quick3d_core_imports.file = $$PWD/quick3d/imports/core/importscore.pro + src_quick3d_core_imports.target = sub-quick3d-imports-core + src_quick3d_core_imports.depends = src_quick3d_core + + src_quick3d_imports_render.file = $$PWD/quick3d/imports/render/importsrender.pro + src_quick3d_imports_render.target = sub-quick3d-imports-render + src_quick3d_imports_render.depends = src_quick3d_render + + src_quick3d_imports_scene3d.file = $$PWD/quick3d/imports/scene3d/importsscene3d.pro + src_quick3d_imports_scene3d.target = sub-quick3d-imports-scene3d + src_quick3d_imports_scene3d.depends = src_quick3d_render src_input + + src_quick3d_imports_input.file = $$PWD/quick3d/imports/input/importsinput.pro + src_quick3d_imports_input.target = sub-quick3d-imports-input + src_quick3d_imports_input.depends = src_input src_quick3d_input + + src_quick3d_imports_logic.file = $$PWD/quick3d/imports/logic/importslogic.pro + src_quick3d_imports_logic.target = sub-quick3d-imports-logic + src_quick3d_imports_logic.depends = src_logic + + src_quick3d_imports_animation.file = $$PWD/quick3d/imports/animation/importsanimation.pro + src_quick3d_imports_animation.target = sub-quick3d-imports-animation + src_quick3d_imports_animation.depends = src_animation src_quick3d_animation + + src_quick3d_imports_extras.file = $$PWD/quick3d/imports/extras/importsextras.pro + src_quick3d_imports_extras.target = sub-quick3d-imports-extras + src_quick3d_imports_extras.depends = src_extras src_quick3d_extras + + src_quick3d_imports_scene2d.file = $$PWD/quick3d/imports/scene2d/importsscene2d.pro + src_quick3d_imports_scene2d.target = sub-quick3d-imports-scene2d + src_quick3d_imports_scene2d.depends = src_quick3d_scene2d +} # Qt3D Scene Parser plugins src_plugins_sceneparsers.file = $$PWD/plugins/sceneparsers/sceneparsers.pro @@ -91,10 +93,12 @@ src_plugins_geometryloaders.file = $$PWD/plugins/geometryloaders/geometryloaders src_plugins_geometryloaders.target = sub-plugins-geometryloaders src_plugins_geometryloaders.depends = src_render src_extras -# Qt3D Render plugins -src_plugins_render.file = $$PWD/plugins/renderplugins/renderplugins.pro -src_plugins_render.target = sub-plugins-render -src_plugins_render.depends = src_render src_extras src_quick3d_render src_quick3d_scene2d +qtHaveModule(quick) { + # Qt3D Render plugins + src_plugins_render.file = $$PWD/plugins/renderplugins/renderplugins.pro + src_plugins_render.target = sub-plugins-render + src_plugins_render.depends = src_render src_extras src_quick3d_render src_quick3d_scene2d +} SUBDIRS += \ src_core \ @@ -103,21 +107,25 @@ SUBDIRS += \ src_input \ src_animation \ src_extras \ - src_quick3d_core \ - src_quick3d_core_imports \ - src_quick3d_render \ - src_quick3d_input \ - src_quick3d_animation \ - src_quick3d_extras \ - src_quick3d_imports_render \ - src_quick3d_imports_scene3d \ - src_quick3d_imports_input \ - src_quick3d_imports_logic \ - src_quick3d_imports_animation \ - src_quick3d_imports_extras \ src_plugins_sceneparsers \ src_plugins_geometryloaders \ - src_plugins_render \ - src_quick3d_scene2d \ - src_quick3d_imports_scene2d \ doc + +qtHaveModule(quick) { + SUBDIRS += \ + src_quick3d_core \ + src_quick3d_core_imports \ + src_quick3d_render \ + src_quick3d_input \ + src_quick3d_animation \ + src_quick3d_extras \ + src_quick3d_imports_render \ + src_quick3d_imports_scene3d \ + src_quick3d_imports_input \ + src_quick3d_imports_logic \ + src_quick3d_imports_animation \ + src_quick3d_imports_extras \ + src_plugins_render \ + src_quick3d_scene2d \ + src_quick3d_imports_scene2d +} -- cgit v1.2.3 From a6164a44f2c9ec0fac50060847ff91dcaa993d4a Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:24:44 +0200 Subject: Fix build for -no-feature-shortcut Change-Id: I1ddd01924fc1d5667be7e0bba2540e24c2272bc3 Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- src/input/frontend/qkeyevent.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/input/frontend/qkeyevent.h b/src/input/frontend/qkeyevent.h index 23fed5545..e028438ce 100644 --- a/src/input/frontend/qkeyevent.h +++ b/src/input/frontend/qkeyevent.h @@ -78,7 +78,9 @@ public: inline bool isAccepted() const { return m_event.isAccepted(); } inline void setAccepted(bool accepted) { m_event.setAccepted(accepted); } inline QEvent::Type type() const { return m_event.type(); } +#if QT_CONFIG(shortcut) Q_INVOKABLE bool matches(QKeySequence::StandardKey key_) const { return m_event.matches(key_); } +#endif private: QT_PREPEND_NAMESPACE(QKeyEvent) m_event; -- cgit v1.2.3 From 7a79da942468621c58251f6daca1a00ca99d970a Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:31:27 +0200 Subject: Fix build for -no-feature-gestures Change-Id: Ib0f0d7f21bf32b09f8dc6d3a4859d037b4e39af7 Reviewed-by: Kevin Ottens Reviewed-by: Tasuku Suzuki Reviewed-by: Sean Harmer --- src/input/frontend/qmouseevent.h | 8 +++++++- src/input/frontend/qmousehandler.cpp | 2 ++ src/render/jobs/pickboundingvolumejob.cpp | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/input/frontend/qmouseevent.h b/src/input/frontend/qmouseevent.h index 043f1023d..de11c84a2 100644 --- a/src/input/frontend/qmouseevent.h +++ b/src/input/frontend/qmouseevent.h @@ -85,7 +85,13 @@ public: inline int x() const { return m_event.x(); } inline int y() const { return m_event.y(); } - inline bool wasHeld() const { return static_cast(m_event.type()) == Qt::TapAndHoldGesture; } + inline bool wasHeld() const { +#if QT_CONFIG(gestures) + return static_cast(m_event.type()) == Qt::TapAndHoldGesture; +#else + return false; +#endif + } Buttons button() const; int buttons() const; Modifiers modifiers() const; diff --git a/src/input/frontend/qmousehandler.cpp b/src/input/frontend/qmousehandler.cpp index 750251be9..fef56810c 100644 --- a/src/input/frontend/qmousehandler.cpp +++ b/src/input/frontend/qmousehandler.cpp @@ -83,9 +83,11 @@ void QMouseHandlerPrivate::mouseEvent(const QMouseEventPtr &event) m_pressAndHoldTimer->stop(); emit q->released(event.data()); break; +#if QT_CONFIG(gestures) case Qt::TapGesture: emit q->clicked(event.data()); break; +#endif case QEvent::MouseButtonDblClick: emit q->doubleClicked(event.data()); break; diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index f6c469912..f9c7a390c 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -371,12 +371,12 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event, } break; } - +#if QT_CONFIG(gestures) case Qt::TapGesture: { objectPicker->onClicked(pickEvent); break; } - +#endif case QEvent::MouseMove: { if ((objectPicker->isPressed() || objectPicker->isHoverEnabled()) && objectPicker->isDragEnabled()) { objectPicker->onMoved(pickEvent); -- cgit v1.2.3 From 9b478e9179522315ea53fe10ec1278a1f77753f8 Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 10:30:24 +0200 Subject: Fix build for -no-feature-wheelevent Change-Id: I72591f43c0e2c4cc6e3e589f8d8e52fbb1041666 Reviewed-by: Kevin Ottens Reviewed-by: Tasuku Suzuki Reviewed-by: Sean Harmer --- src/input/backend/inputhandler.cpp | 20 ++++++++++++++++---- src/input/backend/inputhandler_p.h | 4 ++++ src/input/backend/mousedevice.cpp | 2 ++ src/input/backend/mousedevice_p.h | 2 ++ src/input/backend/mouseeventdispatcherjob.cpp | 11 +++++++++-- src/input/backend/mouseeventdispatcherjob_p.h | 9 +++++++-- src/input/backend/mouseeventfilter.cpp | 2 ++ src/input/backend/mousehandler.cpp | 2 ++ src/input/backend/mousehandler_p.h | 2 ++ src/input/frontend/qmouseevent.cpp | 2 ++ src/input/frontend/qmouseevent.h | 5 +++++ src/input/frontend/qmousehandler.cpp | 2 ++ src/input/frontend/qmousehandler.h | 2 ++ src/quick3d/imports/input/qt3dquick3dinputplugin.cpp | 2 ++ 14 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/input/backend/inputhandler.cpp b/src/input/backend/inputhandler.cpp index 985d67470..525a45b6c 100644 --- a/src/input/backend/inputhandler.cpp +++ b/src/input/backend/inputhandler.cpp @@ -163,6 +163,7 @@ void InputHandler::clearPendingMouseEvents() m_pendingMouseEvents.clear(); } +#if QT_CONFIG(wheelevent) void InputHandler::appendWheelEvent(const QT_PREPEND_NAMESPACE(QWheelEvent) &event) { QMutexLocker lock(&m_mutex); @@ -180,7 +181,7 @@ void InputHandler::clearPendingWheelEvents() QMutexLocker lock(&m_mutex); m_pendingWheelEvents.clear(); } - +#endif void InputHandler::appendKeyboardDevice(HKeyboardDevice device) { @@ -249,15 +250,23 @@ QVector InputHandler::mouseJobs() { QVector jobs; const QList mouseEvents = pendingMouseEvents(); +#if QT_CONFIG(wheelevent) const QList wheelEvents = pendingWheelEvents(); +#endif for (const HMouseDevice cHandle : qAsConst(m_activeMouseDevices)) { MouseDevice *controller = m_mouseDeviceManager->data(cHandle); controller->updateMouseEvents(mouseEvents); +#if QT_CONFIG(wheelevent) controller->updateWheelEvents(wheelEvents); +#endif // Event dispacthing job - if (!mouseEvents.isEmpty() || !wheelEvents.empty()) { + if (!mouseEvents.isEmpty() +#if QT_CONFIG(wheelevent) + || !wheelEvents.empty() +#endif + ) { // Send the events to the mouse handlers that have for sourceDevice controller const QVector activeMouseHandlers = m_mouseInputManager->activeHandles(); for (HMouseHandler mouseHandlerHandle : activeMouseHandlers) { @@ -267,8 +276,11 @@ QVector InputHandler::mouseJobs() if (mouseHandler->mouseDevice() == controller->peerId()) { MouseEventDispatcherJob *job = new MouseEventDispatcherJob(mouseHandler->peerId(), - mouseEvents, - wheelEvents); + mouseEvents +#if QT_CONFIG(wheelevent) + , wheelEvents +#endif + ); job->setInputHandler(this); jobs.append(QAspectJobPtr(job)); } diff --git a/src/input/backend/inputhandler_p.h b/src/input/backend/inputhandler_p.h index e80441f1a..a2a38262d 100644 --- a/src/input/backend/inputhandler_p.h +++ b/src/input/backend/inputhandler_p.h @@ -127,9 +127,11 @@ public: QList pendingMouseEvents(); void clearPendingMouseEvents(); +#if QT_CONFIG(wheelevent) void appendWheelEvent(const QT_PREPEND_NAMESPACE(QWheelEvent) &event); QList pendingWheelEvents(); void clearPendingWheelEvents(); +#endif void appendKeyboardDevice(HKeyboardDevice device); void removeKeyboardDevice(HKeyboardDevice device); @@ -170,7 +172,9 @@ private: QList m_pendingKeyEvents; QList m_pendingMouseEvents; +#if QT_CONFIG(wheelevent) QList m_pendingWheelEvents; +#endif mutable QMutex m_mutex; AxisManager *m_axisManager; diff --git a/src/input/backend/mousedevice.cpp b/src/input/backend/mousedevice.cpp index 1d329252d..128988637 100644 --- a/src/input/backend/mousedevice.cpp +++ b/src/input/backend/mousedevice.cpp @@ -135,6 +135,7 @@ float MouseDevice::sensitivity() const return m_sensitivity; } +#if QT_CONFIG(wheelevent) void MouseDevice::updateWheelEvents(const QList &events) { // Reset axis values before we accumulate new values for this frame @@ -147,6 +148,7 @@ void MouseDevice::updateWheelEvents(const QList &events) { diff --git a/src/input/backend/mousedevice_p.h b/src/input/backend/mousedevice_p.h index 0b95c6183..a085194ff 100644 --- a/src/input/backend/mousedevice_p.h +++ b/src/input/backend/mousedevice_p.h @@ -99,7 +99,9 @@ public: bool isButtonPressed(int buttonIdentifier) const Q_DECL_OVERRIDE; void updateMouseEvents(const QList &events); +#if QT_CONFIG(wheelevent) void updateWheelEvents(const QList &events); +#endif MouseState mouseState() const; QPointF previousPos() const; diff --git a/src/input/backend/mouseeventdispatcherjob.cpp b/src/input/backend/mouseeventdispatcherjob.cpp index 77eb69712..11653d8a8 100644 --- a/src/input/backend/mouseeventdispatcherjob.cpp +++ b/src/input/backend/mouseeventdispatcherjob.cpp @@ -50,13 +50,18 @@ namespace Qt3DInput { namespace Input { MouseEventDispatcherJob::MouseEventDispatcherJob(Qt3DCore::QNodeId input, - const QList &mouseEvents, - const QList &wheelEvents) + const QList &mouseEvents +#if QT_CONFIG(wheelevent) + , const QList &wheelEvents +#endif + ) : QAspectJob() , m_inputHandler(nullptr) , m_mouseInput(input) , m_mouseEvents(mouseEvents) +#if QT_CONFIG(wheelevent) , m_wheelEvents(wheelEvents) +#endif { SET_JOB_RUN_STAT_TYPE(this, JobTypes::MouseEventDispatcher, 0); } @@ -73,8 +78,10 @@ void MouseEventDispatcherJob::run() // Send mouse and wheel events to frontend for (const QT_PREPEND_NAMESPACE(QMouseEvent) &e : m_mouseEvents) input->mouseEvent(QMouseEventPtr(new QMouseEvent(e))); +#if QT_CONFIG(wheelevent) for (const QT_PREPEND_NAMESPACE(QWheelEvent) &e : m_wheelEvents) input->wheelEvent(QWheelEventPtr(new QWheelEvent(e))); +#endif } } diff --git a/src/input/backend/mouseeventdispatcherjob_p.h b/src/input/backend/mouseeventdispatcherjob_p.h index ebf1538e4..366774005 100644 --- a/src/input/backend/mouseeventdispatcherjob_p.h +++ b/src/input/backend/mouseeventdispatcherjob_p.h @@ -66,8 +66,11 @@ class MouseEventDispatcherJob : public Qt3DCore::QAspectJob { public: explicit MouseEventDispatcherJob(Qt3DCore::QNodeId input, - const QList &mouseEvents, - const QList &wheelEvents); + const QList &mouseEvents +#if QT_CONFIG(wheelevent) + , const QList &wheelEvents +#endif + ); void setInputHandler(InputHandler *handler); void run() Q_DECL_FINAL; @@ -75,7 +78,9 @@ private: InputHandler *m_inputHandler; const Qt3DCore::QNodeId m_mouseInput; const QList m_mouseEvents; +#if QT_CONFIG(wheelevent) const QList m_wheelEvents; +#endif }; } // namespace Input diff --git a/src/input/backend/mouseeventfilter.cpp b/src/input/backend/mouseeventfilter.cpp index bc2473a33..618a64b15 100644 --- a/src/input/backend/mouseeventfilter.cpp +++ b/src/input/backend/mouseeventfilter.cpp @@ -80,10 +80,12 @@ bool MouseEventFilter::eventFilter(QObject *obj, QEvent *e) // Creates copy and store event to be processed later on in an InputAspect job m_inputHandler->appendMouseEvent(QMouseEvent(*static_cast(e))); break; +#if QT_CONFIG(wheelevent) case QEvent::Wheel: // Creates copy and store event to be processed later on in an InputAspect job m_inputHandler->appendWheelEvent(QWheelEvent(*static_cast(e))); break; +#endif default: break; } diff --git a/src/input/backend/mousehandler.cpp b/src/input/backend/mousehandler.cpp index a0619aaf2..c492dcf28 100644 --- a/src/input/backend/mousehandler.cpp +++ b/src/input/backend/mousehandler.cpp @@ -91,6 +91,7 @@ void MouseHandler::mouseEvent(const QMouseEventPtr &event) notifyObservers(e); } +#if QT_CONFIG(wheelevent) void MouseHandler::wheelEvent(const QWheelEventPtr &event) { auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); @@ -99,6 +100,7 @@ void MouseHandler::wheelEvent(const QWheelEventPtr &event) e->setValue(QVariant::fromValue(event)); notifyObservers(e); } +#endif void MouseHandler::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) { diff --git a/src/input/backend/mousehandler_p.h b/src/input/backend/mousehandler_p.h index 867764017..ae484d8d6 100644 --- a/src/input/backend/mousehandler_p.h +++ b/src/input/backend/mousehandler_p.h @@ -70,7 +70,9 @@ public: Qt3DCore::QNodeId mouseDevice() const; void setInputHandler(InputHandler *handler); void mouseEvent(const QMouseEventPtr &event); +#if QT_CONFIG(wheelevent) void wheelEvent(const QWheelEventPtr &event); +#endif protected: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; diff --git a/src/input/frontend/qmouseevent.cpp b/src/input/frontend/qmouseevent.cpp index b1574f623..62f7a097e 100644 --- a/src/input/frontend/qmouseevent.cpp +++ b/src/input/frontend/qmouseevent.cpp @@ -455,6 +455,7 @@ QMouseEvent::Modifiers QMouseEvent::modifiers() const * Returns the QEvent::Type of the event. */ +#if QT_CONFIG(wheelevent) /*! * Constructs a new QWheelEvent instance from the QWheelEvent \a e. */ @@ -497,6 +498,7 @@ QWheelEvent::Modifiers QWheelEvent::modifiers() const return QWheelEvent::NoModifier; } } +#endif // QT_CONFIG(wheelevent) } // namespace Qt3DInput diff --git a/src/input/frontend/qmouseevent.h b/src/input/frontend/qmouseevent.h index de11c84a2..63786ac28 100644 --- a/src/input/frontend/qmouseevent.h +++ b/src/input/frontend/qmouseevent.h @@ -106,6 +106,7 @@ private: typedef QSharedPointer QMouseEventPtr; +#if QT_CONFIG(wheelevent) class QT3DINPUTSHARED_EXPORT QWheelEvent : public QObject { Q_OBJECT @@ -154,12 +155,16 @@ private: }; typedef QSharedPointer QWheelEventPtr; +#endif } // namespace Qt3DInput QT_END_NAMESPACE Q_DECLARE_METATYPE(Qt3DInput::QMouseEvent*) // LCOV_EXCL_LINE + +#if QT_CONFIG(wheelevent) Q_DECLARE_METATYPE(Qt3DInput::QWheelEvent*) // LCOV_EXCL_LINE +#endif #endif // QT3DINPUT_QMOUSEEVENT_H diff --git a/src/input/frontend/qmousehandler.cpp b/src/input/frontend/qmousehandler.cpp index fef56810c..419052d8a 100644 --- a/src/input/frontend/qmousehandler.cpp +++ b/src/input/frontend/qmousehandler.cpp @@ -313,9 +313,11 @@ void QMouseHandler::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) if (e->propertyName() == QByteArrayLiteral("mouse")) { QMouseEventPtr ev = e->value().value(); d->mouseEvent(ev); +#if QT_CONFIG(wheelevent) } else if (e->propertyName() == QByteArrayLiteral("wheel")) { QWheelEventPtr ev = e->value().value(); emit wheel(ev.data()); +#endif } } } diff --git a/src/input/frontend/qmousehandler.h b/src/input/frontend/qmousehandler.h index 750ed394d..ef4267c5c 100644 --- a/src/input/frontend/qmousehandler.h +++ b/src/input/frontend/qmousehandler.h @@ -82,7 +82,9 @@ Q_SIGNALS: void pressAndHold(Qt3DInput::QMouseEvent *mouse); void positionChanged(Qt3DInput::QMouseEvent *mouse); +#if QT_CONFIG(wheelevent) void wheel(Qt3DInput::QWheelEvent *wheel); +#endif protected: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE; diff --git a/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp b/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp index 9d83f964f..5719a2b98 100644 --- a/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp +++ b/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp @@ -81,7 +81,9 @@ void Qt3DQuick3DInputPlugin::registerTypes(const char *uri) qmlRegisterType(uri, 2, 0, "InputSettings"); qmlRegisterUncreatableType(uri, 2, 0, "MouseEvent", QStringLiteral("Events cannot be created")); +#if QT_CONFIG(wheelevent) qmlRegisterUncreatableType(uri, 2, 0, "WheelEvent", QStringLiteral("Events cannot be created")); +#endif qmlRegisterType(uri, 2, 0, "MouseHandler"); qmlRegisterType(uri, 2, 0, "MouseDevice"); -- cgit v1.2.3 From 16e3a51154651e2ce08dfce2944bc37ea3165b6b Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Mon, 17 Apr 2017 20:39:21 +0100 Subject: Document the QAbstractClipAnimator class Change-Id: I731946acd392a3c164e71513b431e4d7e2a7034a Reviewed-by: Paul Lemire --- src/animation/frontend/qabstractclipanimator.cpp | 96 ++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/animation/frontend/qabstractclipanimator.cpp b/src/animation/frontend/qabstractclipanimator.cpp index 307f2d2f3..d032e3afe 100644 --- a/src/animation/frontend/qabstractclipanimator.cpp +++ b/src/animation/frontend/qabstractclipanimator.cpp @@ -53,6 +53,57 @@ QAbstractClipAnimatorPrivate::QAbstractClipAnimatorPrivate() { } +/*! + \qmltype AbsractClipAnimator + \instantiates Qt3DAnimation::QAbstractClipAnimator + \inqmlmodule Qt3D.Animation + \since 5.9 + + \brief AbstractClipAnimator is the base class for types providing animation playback + capabilities. + + Subclasses of AbstractClipAnimator can be aggregated by an Entity to + provide animation capabilities. The animator components provide an + interface for controlling the animation (e.g. start, stop). Each animator + type requires some form of animation data such as an AbstractAnimationClip + as well as a ChannelMapper which describes how the channels in the + animation clip should be mapped onto the properties of the objects you wish + to animate. + + The following subclasses are available: + + \list + \li Qt3D.Animation.ClipAnimator + \li Qt3D.Animation.BlendedClipAnimator + \endlist +*/ + +/*! + \class Qt3DAnimation::QAbstractClipAnimator + \inherits Qt3DCore::QComponent + + \inmodule Qt3DAnimation + \since 5.9 + + \brief QAbstractClipAnimator is the base class for types providing animation playback + capabilities. + + Subclasses of QAbstractClipAnimator can be aggregated by a QEntity to + provide animation capabilities. The animator components provide an + interface for controlling the animation (e.g. start, stop). Each animator + type requires some form of animation data such as a QAbstractAnimationClip + as well as a QChannelMapper which describes how the channels in the + animation clip should be mapped onto the properties of the objects you wish + to animate. + + The following subclasses are available: + + \list + \li Qt3DAnimation::QClipAnimator + \li Qt3DAnimation::QBlendedClipAnimator + \endlist +*/ + QAbstractClipAnimator::QAbstractClipAnimator(Qt3DCore::QNode *parent) : Qt3DCore::QComponent(*new QAbstractClipAnimatorPrivate, parent) { @@ -67,18 +118,63 @@ QAbstractClipAnimator::~QAbstractClipAnimator() { } +/*! + \qmlproperty bool running + + This property holds whether the animation is currently running. +*/ + +/*! + \property running + + This property holds whether the animation is currently running. +*/ bool QAbstractClipAnimator::isRunning() const { Q_D(const QAbstractClipAnimator); return d->m_running; } +/*! + \property ChannelMapper channelMapper + + This property holds the ChannelMapper that controls how the channels in + the animation clip map onto the properties of the target objects. +*/ + +/*! + \property channelMapper + + This property holds the QChannelMapper that controls how the channels in + the animation clip map onto the properties of the target objects. +*/ QChannelMapper *QAbstractClipAnimator::channelMapper() const { Q_D(const QAbstractClipAnimator); return d->m_mapper; } +/*! + \qmlproperty int loops + + This property holds the number of times the animation should play. + + By default, loops is 1: the animation will play through once and then stop. + + If set to QAbstractClipAnimator::Infinite, the animation will continuously + repeat until it is explicitly stopped. +*/ + +/*! + \property loops + + This property holds the number of times the animation should play. + + By default, loops is 1: the animation will play through once and then stop. + + If set to QAbstractClipAnimator::Infinite, the animation will continuously + repeat until it is explicitly stopped. +*/ int QAbstractClipAnimator::loopCount() const { Q_D(const QAbstractClipAnimator); -- cgit v1.2.3 From 311261ea1faf6e4a9928d3a97cbca3190703cf04 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Mon, 17 Apr 2017 20:47:03 +0100 Subject: Add imperative slots to control animator running property Change-Id: I6fc8a5860421eb881a1b7d299f771ad88a278027 Reviewed-by: Paul Lemire --- src/animation/frontend/qabstractclipanimator.cpp | 16 ++++++++++++++++ src/animation/frontend/qabstractclipanimator.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/src/animation/frontend/qabstractclipanimator.cpp b/src/animation/frontend/qabstractclipanimator.cpp index d032e3afe..0d215b470 100644 --- a/src/animation/frontend/qabstractclipanimator.cpp +++ b/src/animation/frontend/qabstractclipanimator.cpp @@ -220,6 +220,22 @@ void QAbstractClipAnimator::setLoopCount(int loops) emit loopCountChanged(loops); } +/*! + Starts the animation. +*/ +void QAbstractClipAnimator::start() +{ + setRunning(true); +} + +/*! + Stops the animation. +*/ +void QAbstractClipAnimator::stop() +{ + setRunning(false); +} + } // namespace Qt3DAnimation QT_END_NAMESPACE diff --git a/src/animation/frontend/qabstractclipanimator.h b/src/animation/frontend/qabstractclipanimator.h index 805fcb2b3..bd38fd68b 100644 --- a/src/animation/frontend/qabstractclipanimator.h +++ b/src/animation/frontend/qabstractclipanimator.h @@ -73,6 +73,9 @@ public Q_SLOTS: void setChannelMapper(Qt3DAnimation::QChannelMapper *channelMapper); void setLoopCount(int loops); + void start(); + void stop(); + Q_SIGNALS: void runningChanged(bool running); void channelMapperChanged(Qt3DAnimation::QChannelMapper *channelMapper); -- cgit v1.2.3 From 14c00da0a623a74f01337cb5dd8c7fa506197014 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Wed, 19 Apr 2017 18:43:17 +0100 Subject: Document QClipAnimator Change-Id: Iac75f836033e07c2d525c495e4cf0656a5ab11f5 Reviewed-by: Paul Lemire --- src/animation/frontend/qclipanimator.cpp | 62 ++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/animation/frontend/qclipanimator.cpp b/src/animation/frontend/qclipanimator.cpp index 4dcc4b578..eb6c80aee 100644 --- a/src/animation/frontend/qclipanimator.cpp +++ b/src/animation/frontend/qclipanimator.cpp @@ -52,11 +52,59 @@ QClipAnimatorPrivate::QClipAnimatorPrivate() { } +/*! + \qmltype ClipAnimator + \instantiates Qt3DAnimation::QClipAnimator + \inqmlmodule Qt3D.Animation + \since 5.9 + + \brief ClipAnimator is a component providing simple animation playback capabilities. + + An instance of ClipAnimator can be aggregated by an Entity to add the ability to play back + animation clips and to apply the calculated animation values to properties of QObjects. + + The animation key frame data is provided via the clip property. This can be created + programmatically with AnimationClip or loaded from file with AnimationClipLoader. + + In order to apply the values played back from the channels of data in the animation clip, the + clip animator needs to have a ChannelMapper object assigned to the channelMapper property. + + The properties for controlling the animator are provided by the AbstractClipAnimator base + class. + + \sa AbstractClipAnimator, AbstractAnimationClip, ChannelMapper, BlendedClipAnimator +*/ + +/*! + \class Qt3DAnimation::QClipAnimator + \inherits Qt3DAnimation::QAbstractClipAnimator + + \inmodule Qt3DAnimation + \since 5.9 + + \brief QClipAnimator is a component providing simple animation playback capabilities. + + An instance of QClipAnimator can be aggregated by a QEntity to add the ability to play back + animation clips and to apply the calculated animation values to properties of QObjects. + + The animation key frame data is provided via the clip property. This can be created + programmatically with QAnimationClip or loaded from file with QAnimationClipLoader. + + In order to apply the values played back from the channels of data in the animation clip, the + clip animator needs to have a QChannelMapper object assigned to the channelMapper property. + + The properties for controlling the animator are provided by the QAbstractClipAnimator base + class. + + \sa QAbstractClipAnimator, QAbstractAnimationClip, QChannelMapper, QBlendedClipAnimator +*/ + QClipAnimator::QClipAnimator(Qt3DCore::QNode *parent) : Qt3DAnimation::QAbstractClipAnimator(*new QClipAnimatorPrivate, parent) { } +/*! \internal */ QClipAnimator::QClipAnimator(QClipAnimatorPrivate &dd, Qt3DCore::QNode *parent) : Qt3DAnimation::QAbstractClipAnimator(dd, parent) { @@ -66,6 +114,19 @@ QClipAnimator::~QClipAnimator() { } +/*! + \qmlproperty AbstractAnimationClip clip + + This property holds the animation clip which contains the key frame data to be played back. + The key frame data can be specified in either an AnimationClip or AnimationClipLoader. +*/ + +/*! + \property clip + + This property holds the animation clip which contains the key frame data to be played back. + The key frame data can be specified in either a QAnimationClip or QAnimationClipLoader. +*/ QAbstractAnimationClip *QClipAnimator::clip() const { Q_D(const QClipAnimator); @@ -91,6 +152,7 @@ void QClipAnimator::setClip(QAbstractAnimationClip *clip) emit clipChanged(clip); } +/*! \internal */ Qt3DCore::QNodeCreatedChangeBasePtr QClipAnimator::createNodeCreationChange() const { auto creationChange = Qt3DCore::QNodeCreatedChangePtr::create(this); -- cgit v1.2.3 From 6ccffde7abdfbddf6768293a813a382527ad591b Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Wed, 19 Apr 2017 19:27:58 +0100 Subject: Document QBlendedClipAnimator Change-Id: Ic2505c1f2bfbcf3790f38634cf58b41c219c3525 Reviewed-by: Paul Lemire --- src/animation/frontend/qblendedclipanimator.cpp | 208 +++++++++++++++++++++++- 1 file changed, 199 insertions(+), 9 deletions(-) diff --git a/src/animation/frontend/qblendedclipanimator.cpp b/src/animation/frontend/qblendedclipanimator.cpp index 971f4e1e7..e6b127bf1 100644 --- a/src/animation/frontend/qblendedclipanimator.cpp +++ b/src/animation/frontend/qblendedclipanimator.cpp @@ -55,32 +55,208 @@ QBlendedClipAnimatorPrivate::QBlendedClipAnimatorPrivate() \qmltype BlendedClipAnimator \instantiates Qt3DAnimation::QBlendedClipAnimator \inqmlmodule Qt3D.Animation + \since 5.9 - \brief Performs an animation based on a tree of blend nodes + \brief BlendedClipAnimator is a component providing animation playback capabilities of a tree + of blend nodes. - \note The blend node tree should only be edited when the clip is not - running + An instance of BlendedClipAnimator can be aggregated by an Entity to add the ability to play + back animation clips and to apply the calculated animation values to properties of QObjects. - \since 5.9 + Whereas a ClipAnimator gets its animation data from a single animation clip, + BlendedClipAnimator can blend together multiple clips. The animation data is obtained by + evaluating a so called \e {blend tree}. A blend tree is a hierarchical tree structure where the + leaf nodes are value nodes that encapsulate an animation clip (AbstractAnimationClip); and the + internal nodes represent blending operations that operate on the nodes pointed to by their + operand properties. + + To associate a blend tree with a BlendedClipAnimator, set the animator's blendTree property to + point at the root node of your blend tree: + + \badcode + BlendedClipAnimator { + blendTree: AdditiveClipBlend { + .... + } + } + \endcode + + A blend tree can be constructed from the following node types: + + \note The blend node tree should only be edited when the animator is not running. + + \list + \li Qt3D.Animation.ClipBlendValue + \li Qt3D.Animation.LerpClipBlend + \li Qt3D.Animation.AdditiveClipBlend + \endlist + + Additional node types will be added over time. + + As an example consider the following blend tree: + + \badcode + Clip0---- + | + Lerp Node---- + | | + Clip1---- Additive Node + | + Clip2---- + \endcode + + This can be created and used as follows: + + \badcode + BlendedClipAnimator { + blendTree: AdditiveClipBlend { + baseClip: LerpClipBlend { + startClip: ClipBlendValue { + clip: AnimationClipLoader { source: "walk.json" } + } + + endClip: ClipBlendValue { + clip: AnimationClipLoader { source: "run.json" } + } + } + + additiveClip: ClipBlendValue { + clip: AnimationClipLoader { source: "wave-arm.json" } + } + } + + channelMapper: ChannelMapper {...} + running: true + } + \endcode + + By authoring a set of animation clips and blending between them dynamically at runtime with a + blend tree, we open up a huge set of possible resulting animations. As some simple examples of + the above blend tree, where alpha is the additive factor and beta is the lerp blend factor we + can get a 2D continuum of possible animations: + + \badcode + (alpha = 0, beta = 1) Running, No arm waving --- (alpha = 1, beta = 1) Running, Arm waving + | | + | | + | | + (alpha = 0, beta = 0) Walking, No arm waving --- (alpha = 0, beta = 1) Running, No arm waving + \endcode + + More complex blend trees offer even more flexibility for combining your animation clips. Note + that the values used to control the blend tree (alpha and beta above) are simple properties on + the blend nodes. This means, that these properties themselves can also be controlled by + the animation framework. */ /*! \class Qt3DAnimation::QBlendedClipAnimator + \inherits Qt3DAnimation::QAbstractClipAnimator + \inmodule Qt3DAnimation - \inherits Qt3DCore::QComponent + \since 5.9 - \brief Performs an animation based on a tree of blend nodes + \brief QBlendedClipAnimator is a component providing animation playback capabilities of a tree + of blend nodes. - \note The blend node tree should only be edited when the clip is not - running + An instance of QBlendedClipAnimator can be aggregated by a QEntity to add the ability to play + back animation clips and to apply the calculated animation values to properties of QObjects. + + Whereas a QClipAnimator gets its animation data from a single animation clip, + QBlendedClipAnimator can blend together multiple clips. The animation data is obtained by + evaluating a so called \e {blend tree}. A blend tree is a hierarchical tree structure where the + leaf nodes are value nodes that encapsulate an animation clip (QAbstractAnimationClip); and the + internal nodes represent blending operations that operate on the nodes pointed to by their + operand properties. + + To associate a blend tree with a QBlendedClipAnimator, set the animator's blendTree property to + point at the root node of your blend tree: + + \badcode + auto blendTreeRoot = new QAdditiveClipBlend(); + ... + auto animator = new QBlendedClipAnimator(); + animator->setBlendTree(blendTreeRoot); + \endcode + + A blend tree can be constructed from the following node types: + + \note The blend node tree should only be edited when the animator is not running. + + \list + \li Qt3DAnimation::QClipBlendValue + \li Qt3DAnimation::QLerpClipBlend + \li Qt3DAnimation::QAdditiveClipBlend + \endlist + + Additional node types will be added over time. + + As an example consider the following blend tree: + + \badcode + Clip0---- + | + Lerp Node---- + | | + Clip1---- Additive Node + | + Clip2---- + \endcode + + This can be created and used as follows: + + \code + // Create leaf nodes of blend tree + auto clip0 = new QClipBlendValue( + new QAnimationClipLoader(QUrl::fromLocalFile("walk.json"))); + auto clip1 = new QClipBlendValue( + new QAnimationClipLoader(QUrl::fromLocalFile("run.json"))); + auto clip2 = new QClipBlendValue( + new QAnimationClipLoader(QUrl::fromLocalFile("wave-arm.json"))); + + // Create blend tree inner nodes + auto lerpNode = new QLerpClipBlend(); + lerpNode->setStartClip(clip0); + lerpNode->setEndClip(clip1); + lerpNode->setBlendFactor(0.5f); // Half-walk, half-run + + auto additiveNode = new QAdditiveClipBlend(); + additiveNode->setBaseClip(lerpNode); // Comes from lerp sub-tree + additiveNode->setAdditiveClip(clip2); + additiveNode->setAdditiveFactor(1.0f); // Wave arm fully + + // Run the animator + auto animator = new QBlendedClipAnimator(); + animator->setBlendTree(additiveNode); + animator->setChannelMapper(...); + animator->setRunning(true); + \endcode + + By authoring a set of animation clips and blending between them dynamically at runtime with a + blend tree, we open up a huge set of possible resulting animations. As some simple examples of + the above blend tree, where alpha is the additive factor and beta is the lerp blend factor we + can get a 2D continuum of possible animations: + + \badcode + (alpha = 0, beta = 1) Running, No arm waving --- (alpha = 1, beta = 1) Running, Arm waving + | | + | | + | | + (alpha = 0, beta = 0) Walking, No arm waving --- (alpha = 0, beta = 1) Running, No arm waving + \endcode + + More complex blend trees offer even more flexibility for combining your animation clips. Note + that the values used to control the blend tree (alpha and beta above) are simple properties on + the blend nodes. This means, that these properties themselves can also be controlled by + the animation framework. - \since 5.9 */ QBlendedClipAnimator::QBlendedClipAnimator(Qt3DCore::QNode *parent) : Qt3DAnimation::QAbstractClipAnimator(*new QBlendedClipAnimatorPrivate, parent) { } +/*! \internal */ QBlendedClipAnimator::QBlendedClipAnimator(QBlendedClipAnimatorPrivate &dd, Qt3DCore::QNode *parent) : Qt3DAnimation::QAbstractClipAnimator(dd, parent) { @@ -90,6 +266,19 @@ QBlendedClipAnimator::~QBlendedClipAnimator() { } +/*! + \qmlproperty AbstractClipBlendNode blendTree + + This property holds the root of the animation blend tree that will be evaluated before being + interpolated by the animator. +*/ + +/*! + \property blendTree + + This property holds the root of the animation blend tree that will be evaluated before being + interpolated by the animator. +*/ QAbstractClipBlendNode *QBlendedClipAnimator::blendTree() const { Q_D(const QBlendedClipAnimator); @@ -116,6 +305,7 @@ void QBlendedClipAnimator::setBlendTree(QAbstractClipBlendNode *blendTree) emit blendTreeChanged(blendTree); } +/*! \internal */ Qt3DCore::QNodeCreatedChangeBasePtr QBlendedClipAnimator::createNodeCreationChange() const { auto creationChange = Qt3DCore::QNodeCreatedChangePtr::create(this); -- cgit v1.2.3 From f8862fac6366853d4b204a1e3c9e948ae5ba309b Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Sat, 22 Apr 2017 11:49:20 +0100 Subject: Document QAbstractClipBlendNode Change-Id: I15a95fed8500824e0eb0a5294c4725e6263a247c Reviewed-by: Paul Lemire --- src/animation/frontend/qabstractclipblendnode.cpp | 71 +++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/animation/frontend/qabstractclipblendnode.cpp b/src/animation/frontend/qabstractclipblendnode.cpp index 9cc6f3de6..9860e969f 100644 --- a/src/animation/frontend/qabstractclipblendnode.cpp +++ b/src/animation/frontend/qabstractclipblendnode.cpp @@ -46,11 +46,82 @@ QAbstractClipBlendNodePrivate::QAbstractClipBlendNodePrivate() { } +/*! + \qmltype AbstractClipBlendNode + \instantiates Qt3DAnimation::QAbstractClipBlendNode + \inqmlmodule Qt3D.Animation + \since 5.9 + + \brief AbstractClipBlendNode is the base class for types used to construct animation blend + trees. + + Animation blend trees are used with a BlendedClipAnimator to dynamically blend a set of + animation clips together. The way in which the blending of animation clips is performed is + controlled by the structure of the blend tree and the properties on the nodes it contains. + + The leaf nodes in a blend tree are containers for the input animation clips. These clips can be + baked clips read from file via AnimationClipLoader, or they can be clips that you build within + your application with AnimatitonClip and AnimationClipData. To include a clip in your blend + tree, wrap it in a ClipBlendValue node. + + The interior nodes of a blend tree represent blending operations that will be applied to their + arguments which hold the input clips or even entire sub-trees of other blend tree nodes. + + At present, the Qt 3D Animation module provides the following blend tree node types: + + \list + \li Qt3D.Animation.ClipBlendValue + \li Qt3D.Animation.LerpClipBlend + \li Qt3D.Animation.QAdditiveClipBlend + \endlist + + Additional node types representing other blending operations will be added in the future. + + \sa BlendedClipAnimator +*/ + +/*! + \class Qt3DAnimation::QAbstractClipBlendNode + \inherits Qt3DCore::QNode + + \inmodule Qt3DAnimation + \since 5.9 + + \brief QAbstractClipBlendNode is the base class for types used to construct animation blend + trees. + + Animation blend trees are used with a QBlendedClipAnimator to dynamically blend a set of + animation clips together. The way in which the blending of animation clips is performed is + controlled by the structure of the blend tree and the properties on the nodes it contains. + + The leaf nodes in a blend tree are containers for the input animation clips. These clips can be + baked clips read from file via QAnimationClipLoader, or they can be clips that you build within + your application with QAnimatitonClip and QAnimationClipData. To include a clip in your blend + tree, wrap it in a QClipBlendValue node. + + The interior nodes of a blend tree represent blending operations that will be applied to their + arguments which hold the input clips or even entire sub-trees of other blend tree nodes. + + At present, the Qt 3D Animation module provides the following blend tree node types: + + \list + \li Qt3DAnimation::QClipBlendValue + \li Qt3DAnimation::QLerpClipBlend + \li Qt3DAnimation::QAdditiveClipBlend + \endlist + + Additional node types representing other blending operations will be added in the future. + + \sa QBlendedClipAnimator +*/ + +/*! \internal */ QAbstractClipBlendNode::QAbstractClipBlendNode(Qt3DCore::QNode *parent) : Qt3DCore::QNode(*new QAbstractClipBlendNodePrivate(), parent) { } +/*! \internal */ QAbstractClipBlendNode::QAbstractClipBlendNode(QAbstractClipBlendNodePrivate &dd, Qt3DCore::QNode *parent) : Qt3DCore::QNode(dd, parent) { -- cgit v1.2.3 From cf29e6c74aa8e65480110df65086346485a90803 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Mon, 24 Apr 2017 14:07:37 +0100 Subject: Document QAdditiveClipBlend Change-Id: I8cc48899e31a32f6c1dd9f4f56e3a5fa846bd8f4 Reviewed-by: Paul Lemire --- src/animation/frontend/qadditiveclipblend.cpp | 123 ++++++++++++++++---------- 1 file changed, 74 insertions(+), 49 deletions(-) diff --git a/src/animation/frontend/qadditiveclipblend.cpp b/src/animation/frontend/qadditiveclipblend.cpp index ee207eb42..58ef5e577 100644 --- a/src/animation/frontend/qadditiveclipblend.cpp +++ b/src/animation/frontend/qadditiveclipblend.cpp @@ -48,39 +48,67 @@ namespace Qt3DAnimation { \instantiates Qt3DAnimation::QAdditiveClipBlend \inqmlmodule Qt3D.Animation - \brief Performs an addition of two animation clips based on a - normalized factor - \since 5.9 - AdditiveClipBlend can be useful to create advanced animation effects based on - individual animation clips. For instance, given a player character, additive - blending could be used to combine a walking animation clip with an injured - animation clip based on a blend factor that increases the more the player - gets injured. This would then allow with blend factor == 0 to have a non - injured walking player, with blend factor == 1 a fully injured player, with - blend factor == 0.5 a partially walking and injured player. + \brief Performs an additive blend of two animation clips based on an additive factor. + + QAdditiveClipBlend can be useful to create advanced animation effects based on + individual animation clips. For example, if you: + + \list + \li set the baseClip property to a normal walk cycle animation clip and + \li set the additiveClip property to a shaking head difference clip, + \endlist + + then adjusting the additiveFactor property will control how much of the additiveClip gets added + on to the baseClip. This has he effect that with an additiveFactor of zero, this blend node will + yield the original walk cycle clip. With an additiveFactor of 1, it will yield the walk cycle + including a shaking head animation. + + The blending operation implemented by this class is: + + \badcode + resultClip = baseClip + additiveFactor * additiveClip + \endcode + + There is nothing stopping you from using values for the additiveFacor property outside the 0 to + 1 range, but please be aware that the input animation clips may not be authored in such a way + for this to make sense. \sa BlendedClipAnimator */ /*! \class Qt3DAnimation::QAdditiveClipBlend - \inmodule Qt3DAnimation \inherits Qt3DAnimation::QAbstractClipBlendNode - \brief Performs an addition of two animation clips based on a - normalized factor - + \inmodule Qt3DAnimation \since 5.9 + \brief Performs an additive blend of two animation clips based on an additive factor. + QAdditiveClipBlend can be useful to create advanced animation effects based on - individual animation clips. For instance, given a player character, additive - blending could be used to combine a walking animation clip with an injured - animation clip based on a blend factor that increases the more the player - gets injured. This would then allow with blend factor == 0 to have a non - injured walking player, with blend factor == 1 a fully injured player, with - blend factor == 0.5 a partially walking and injured player. + individual animation clips. For example, if you: + + \list + \li set the baseClip property to a normal walk cycle animation clip and + \li set the additiveClip property to a shaking head difference clip, + \endlist + + then adjusting the additiveFactor property will control how much of the additiveClip gets added + on to the baseClip. This has he effect that with an additiveFactor of zero, this blend node will + yield the original walk cycle clip. With an additiveFactor of 1, it will yield the walk cycle + including a shaking head animation. + + The blending operation implemented by this class is: + + \badcode + resultClip = baseClip + additiveFactor * additiveClip + \endcode + + There is nothing stopping you from using values for the additiveFacor property outside the 0 to + 1 range, but please be aware that the input animation clips may not be authored in such a way + for this to make sense. \sa QBlendedClipAnimator */ @@ -121,13 +149,13 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAdditiveClipBlend::createNodeCreationChange /*! \qmlproperty real AdditiveClipBlend::additiveFactor - Specifies the blending factor between 0 and 1 to control the blending of + Specifies the blending factor, typically between 0 and 1, to control the blending of two animation clips. */ /*! \property QAdditiveClipBlend::additiveFactor - Specifies the blending factor between 0 and 1 to control the blending of + Specifies the blending factor, typically between 0 and 1, to control the blending of two animation clips. */ float QAdditiveClipBlend::additiveFactor() const @@ -136,12 +164,36 @@ float QAdditiveClipBlend::additiveFactor() const return d->m_additiveFactor; } +/*! + \qmlproperty AbstractClipBlendNode baseClip + + This property holds the base animation clip. When the additiveFacgtor is zero the baseClip will + also be the resulting clip of this blend node. +*/ +/*! + \property baseClip + + This property holds the base animation clip. When the additiveFacgtor is zero the baseClip will + also be the resulting clip of this blend node. +*/ QAbstractClipBlendNode *QAdditiveClipBlend::baseClip() const { Q_D(const QAdditiveClipBlend); return d->m_baseClip; } +/*! + \qmlproperty AbstractClipBlendNode additiveClip + + This property holds the additive clip to be blended with the baseClip. The amount of blending + is controlled by the additiveFactor property. +*/ +/*! + \property additiveClip + + This property holds the additive clip to be blended with the baseClip. The amount of blending + is controlled by the additiveFactor property. +*/ QAbstractClipBlendNode *QAdditiveClipBlend::additiveClip() const { Q_D(const QAdditiveClipBlend); @@ -197,33 +249,6 @@ void QAdditiveClipBlend::setAdditiveClip(QAbstractClipBlendNode *additiveClip) emit additiveClipChanged(additiveClip); } -/*! - \qmlproperty list AdditiveClipBlend::clips - - Holds the list of AnimationClip nodes against which the blending is performed. - - \note Only the two first AnimationClip are used, subsequent ones are ignored -*/ - - -/*! - \fn void QAdditiveClipBlend::addClip(QAnimationClip *clip); - Adds a \a clip to the blending node's clips list. - - \note Only the two first AnimationClip are used, subsequent ones are ignored - */ - -/*! - \fn void QAdditiveClipBlend::removeClip(QAnimationClip *clip); - Removes a \a clip from the blending node's clips list. - */ - -/*! - \fn QVector QAdditiveClipBlend::clips() const; - Returns the list of QAnimationClip against which the blending is performed. - */ - - } // Qt3DAnimation QT_END_NAMESPACE -- cgit v1.2.3 From e138c89c5f75e62c873dfe77e1e4c2e39b7b5f6c Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:29:05 +0200 Subject: Fix build for -no-feature-regularexpression Change-Id: Icff3f2bb2886ba4e077fb43f9a406592435f6fff Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- src/plugins/geometryloaders/geometryloaders.pro | 2 +- src/plugins/sceneparsers/sceneparsers.pro | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/geometryloaders/geometryloaders.pro b/src/plugins/geometryloaders/geometryloaders.pro index 8dd99deb5..764c615da 100644 --- a/src/plugins/geometryloaders/geometryloaders.pro +++ b/src/plugins/geometryloaders/geometryloaders.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs -SUBDIRS += default +qtConfig(regularexpression) : SUBDIRS += default SUBDIRS += gltf qtConfig(qt3d-fbxsdk) : SUBDIRS += fbx diff --git a/src/plugins/sceneparsers/sceneparsers.pro b/src/plugins/sceneparsers/sceneparsers.pro index bba802393..7b50f654e 100644 --- a/src/plugins/sceneparsers/sceneparsers.pro +++ b/src/plugins/sceneparsers/sceneparsers.pro @@ -5,6 +5,6 @@ config_assimp|!cross_compile: SUBDIRS += assimp SUBDIRS += gltf -qtConfig(temporaryfile) { +qtConfig(temporaryfile):qtConfig(regularexpression) { SUBDIRS += gltfexport } -- cgit v1.2.3 From 873caffc95b6e279d68851cc0a8ed738980ebd0c Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Thu, 27 Apr 2017 14:03:48 +0100 Subject: Fix -Werror=unused-parameter issue Change-Id: Ibc77241e8d369224eda790b8dcfd900f330bed37 Reviewed-by: Paul Lemire --- src/extras/text/qdistancefieldglyphcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extras/text/qdistancefieldglyphcache.cpp b/src/extras/text/qdistancefieldglyphcache.cpp index aacccc7dc..9c997013e 100644 --- a/src/extras/text/qdistancefieldglyphcache.cpp +++ b/src/extras/text/qdistancefieldglyphcache.cpp @@ -61,7 +61,7 @@ namespace Qt3DExtras { class StoredGlyph { public: StoredGlyph() = default; - StoredGlyph(const StoredGlyph &other) = default; + StoredGlyph(const StoredGlyph &) = default; StoredGlyph(const QRawFont &font, quint32 glyph, bool doubleResolution); int refCount() const { return m_ref; } -- cgit v1.2.3 From 80e4d6db6b5636b839cef7e79b2b8ff528329ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Tue, 18 Apr 2017 10:09:47 +0300 Subject: Modify configure to build with no assimp Add -no-assimp configure to build without assimp. Task-number: QTBUG-60128 Change-Id: I2ca7bb68d3b659e18bd79039beb5cb6623473859 Reviewed-by: Sean Harmer --- src/core/configure.json | 2 +- src/plugins/sceneparsers/sceneparsers.pro | 5 +++-- tools/tools.pro | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/core/configure.json b/src/core/configure.json index 86b31223f..47a726d82 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -4,7 +4,7 @@ "commandline": { "options": { - "assimp": { "type": "enum", "values": [ "qt", "system" ] }, + "assimp": { "type": "enum", "values": [ "qt", "system", "no" ] }, "qt3d-profile-jobs": "boolean", "qt3d-profile-gl": "boolean" } diff --git a/src/plugins/sceneparsers/sceneparsers.pro b/src/plugins/sceneparsers/sceneparsers.pro index 7b50f654e..cb274b472 100644 --- a/src/plugins/sceneparsers/sceneparsers.pro +++ b/src/plugins/sceneparsers/sceneparsers.pro @@ -1,8 +1,9 @@ TEMPLATE = subdirs # QNX is not supported, and Linux GCC 4.9 on ARM chokes on the assimp # sources (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66964). -config_assimp|!cross_compile: SUBDIRS += assimp - +QT_FOR_CONFIG += 3dcore-private +qtConfig(assimp):if(qtConfig(system-assimp)|!cross_compile): \ + SUBDIRS += assimp SUBDIRS += gltf qtConfig(temporaryfile):qtConfig(regularexpression) { diff --git a/tools/tools.pro b/tools/tools.pro index 4dbd7496a..8e973aecb 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -1,2 +1,4 @@ TEMPLATE = subdirs -qtConfig(commandlineparser):!android:SUBDIRS += qgltf +QT_FOR_CONFIG += 3dcore-private +!android:qtConfig(assimp):qtConfig(commandlineparser): \ + SUBDIRS += qgltf -- cgit v1.2.3 From b5800ac037321e161d31ee362688aef179c8d9d2 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Thu, 27 Apr 2017 10:43:29 +0200 Subject: Renderer: fix OnDemand rendering Note: this is a risky change For some reason the renderer assumed that a RenderQueue would never have a size of 0. This prevented the renderer from calling proceedToNextFrame() on the vsync advance service as it somehow felt that it was a case of rendering with a RenderQueue not yet ready. In the case of OnDemand rendering it is perfectly valid to have a RenderQueue of 0 (nothing has changed that requires rendering) but we still need to call proceedToNextFrame() otherwise syncChanges() is never called and we end up never updating the aspects ever again. The renderer was updated to 1) check if a RenderQueue is complete 2) check if the RenderQueue is empty. (a RenderQueue can be complete but empty (OnDemand case)) 3) Proceed to next frame if RenderQueue is complete or RenderQueue is empty. Change-Id: I27ae778831c9b136db1e1a69892f6fde291fd965 Task-number: QTBUG-59696 Task-number: QTBUG-54900 Reviewed-by: Sean Harmer --- src/render/backend/renderer.cpp | 145 +++++++++++----------- src/render/backend/renderer_p.h | 4 +- src/render/backend/renderqueue.cpp | 6 +- src/render/backend/renderqueue_p.h | 4 + tests/auto/render/renderqueue/tst_renderqueue.cpp | 6 + 5 files changed, 89 insertions(+), 76 deletions(-) diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index e40d5d68e..4080a72eb 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -536,17 +536,26 @@ void Renderer::render() void Renderer::doRender() { - bool submissionSucceeded = false; - bool hasCleanedQueueAndProceeded = false; Renderer::ViewSubmissionResultData submissionData; + bool hasCleanedQueueAndProceeded = false; bool preprocessingComplete = false; - - if (isReadyToSubmit()) { - - // Lock the mutex to protect access to m_surface and check if we are still set - // to the running state and that we have a valid surface on which to draw - // TO DO: Is that still needed given the surface changes - QMutexLocker locker(&m_mutex); + bool beganDrawing = false; + const bool canSubmit = isReadyToSubmit(); + + // Lock the mutex to protect access to the renderQueue while we look for its state + QMutexLocker locker(&m_renderQueueMutex); + const bool queueIsComplete = m_renderQueue->isFrameQueueComplete(); + const bool queueIsEmpty = m_renderQueue->targetRenderViewCount() == 0; + + // When using synchronous rendering (QtQuick) + // We are not sure that the frame queue is actually complete + // Since a call to render may not be synched with the completions + // of the RenderViewJobs + // In such a case we return early, waiting for a next call with + // the frame queue complete at this point + + // RenderQueue is complete (but that means it may be of size 0) + if (canSubmit && (queueIsComplete && !queueIsEmpty)) { const QVector renderViews = m_renderQueue->nextFrameQueue(); #ifdef QT3D_JOBS_RUN_STATS @@ -561,8 +570,7 @@ void Renderer::doRender() submissionStatsPart2.jobId.typeAndInstance[1] = 0; submissionStatsPart2.threadId = reinterpret_cast(QThread::currentThreadId()); #endif - - if (canRender() && (submissionSucceeded = renderViews.size() > 0) == true) { + if (canRender()) { // Clear all dirty flags but Compute so that // we still render every frame when a compute shader is used in a scene BackendNodeDirtySet changesToUnset = m_changeSet; @@ -584,7 +592,8 @@ void Renderer::doRender() // Reset state for each draw if we don't have complete control of the context if (!m_ownedContext) m_graphicsContext->setCurrentStateSet(nullptr); - if (m_graphicsContext->beginDrawing(surface)) { + beganDrawing = m_graphicsContext->beginDrawing(surface); + if (beganDrawing) { // 1) Execute commands for buffer uploads, texture updates, shader loading first updateGLResources(); // 2) Update VAO and copy data into commands to allow concurrent submission @@ -595,6 +604,7 @@ void Renderer::doRender() } // 2) Proceed to next frame and start preparing frame n + 1 m_renderQueue->reset(); + locker.unlock(); // Done protecting RenderQueue m_vsyncFrameAdvanceService->proceedToNextFrame(); hasCleanedQueueAndProceeded = true; @@ -638,61 +648,57 @@ void Renderer::doRender() #endif } - // Note: submissionSucceeded is false when - // * we cannot render because a shutdown has been scheduled - // * the renderqueue is incomplete (only when rendering with a Scene3D) - // Otherwise returns true even for cases like - // * No render view - // * No surface set - // * OpenGLContext failed to be set current - // This behavior is important as we need to - // call proceedToNextFrame despite rendering errors that aren't fatal - // Only reset renderQueue and proceed to next frame if the submission - // succeeded or it we are using a render thread and that is wasn't performed + // succeeded or if we are using a render thread and that is wasn't performed // already - // If submissionSucceeded isn't true this implies that something went wrong + // If hasCleanedQueueAndProceeded isn't true this implies that something went wrong // with the rendering and/or the renderqueue is incomplete from some reason // (in the case of scene3d the render jobs may be taking too long ....) - if (m_renderThread || submissionSucceeded) { - - if (!hasCleanedQueueAndProceeded) { - // Reset the m_renderQueue so that we won't try to render - // with a queue used by a previous frame with corrupted content - // if the current queue was correctly submitted - m_renderQueue->reset(); - - // We allow the RenderTickClock service to proceed to the next frame - // In turn this will allow the aspect manager to request a new set of jobs - // to be performed for each aspect - m_vsyncFrameAdvanceService->proceedToNextFrame(); - } + // or alternatively it could be complete but empty (RenderQueue of size 0) + if (!hasCleanedQueueAndProceeded && + (m_renderThread || queueIsComplete || queueIsEmpty)) { + // RenderQueue was full but something bad happened when + // trying to render it and therefore proceedToNextFrame was not called + // Note: in this case the renderQueue mutex is still locked + + // Reset the m_renderQueue so that we won't try to render + // with a queue used by a previous frame with corrupted content + // if the current queue was correctly submitted + m_renderQueue->reset(); + + // We allow the RenderTickClock service to proceed to the next frame + // In turn this will allow the aspect manager to request a new set of jobs + // to be performed for each aspect + m_vsyncFrameAdvanceService->proceedToNextFrame(); + } - // Perform the last swapBuffers calls after the proceedToNextFrame - // as this allows us to gain a bit of time for the preparation of the - // next frame + // Perform the last swapBuffers calls after the proceedToNextFrame + // as this allows us to gain a bit of time for the preparation of the + // next frame + // Finish up with last surface used in the list of RenderViews + if (beganDrawing) { + SurfaceLocker surfaceLock(submissionData.surface); // Finish up with last surface used in the list of RenderViews - if (submissionSucceeded) { - SurfaceLocker surfaceLock(submissionData.surface); - // Finish up with last surface used in the list of RenderViews - m_graphicsContext->endDrawing(submissionData.lastBoundFBOId == m_graphicsContext->defaultFBO() && surfaceLock.isSurfaceValid()); - } + m_graphicsContext->endDrawing(submissionData.lastBoundFBOId == m_graphicsContext->defaultFBO() && surfaceLock.isSurfaceValid()); } } // Called by RenderViewJobs +// When the frameQueue is complete and we are using a renderThread +// we allow the render thread to proceed void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder) { - QMutexLocker locker(&m_mutex); // Prevent out of order execution + QMutexLocker locker(&m_renderQueueMutex); // Prevent out of order execution // We cannot use a lock free primitive here because: // - QVector is not thread safe // - Even if the insert is made correctly, the isFrameComplete call // could be invalid since depending on the order of execution // the counter could be complete but the renderview not yet added to the // buffer depending on whichever order the cpu decides to process this - - if (m_renderQueue->queueRenderView(renderView, submitOrder)) { + const bool isQueueComplete = m_renderQueue->queueRenderView(renderView, submitOrder); + locker.unlock(); // We're done protecting the queue at this point + if (isQueueComplete) { if (m_renderThread && m_running.load()) Q_ASSERT(m_submitRenderViewsSemaphore.available() == 0); m_submitRenderViewsSemaphore.release(1); @@ -731,16 +737,6 @@ bool Renderer::isReadyToSubmit() // something to render // The case of shutdown should have been handled just before Q_ASSERT(m_renderQueue->isFrameQueueComplete()); - } else { - // When using synchronous rendering (QtQuick) - // We are not sure that the frame queue is actually complete - // Since a call to render may not be synched with the completions - // of the RenderViewJobs - // In such a case we return early, waiting for a next call with - // the frame queue complete at this point - QMutexLocker locker(&m_mutex); - if (!m_renderQueue->isFrameQueueComplete()) - return false; } return true; } @@ -1431,22 +1427,25 @@ QVector Renderer::renderBinJobs() renderBinJobs.push_back(m_textureGathererJob); renderBinJobs.push_back(m_shaderGathererJob); - // Traverse the current framegraph. For each leaf node create a - // RenderView and set its configuration then create a job to - // populate the RenderView with a set of RenderCommands that get - // their details from the RenderNodes that are visible to the - // Camera selected by the framegraph configuration - FrameGraphVisitor visitor(m_nodesManager->frameGraphManager()); - const QVector fgLeaves = visitor.traverse(frameGraphRoot()); - - const int fgBranchCount = fgLeaves.size(); - for (int i = 0; i < fgBranchCount; ++i) { - RenderViewBuilder builder(fgLeaves.at(i), i, this); - renderBinJobs.append(builder.buildJobHierachy()); - } + QMutexLocker lock(&m_renderQueueMutex); + if (m_renderQueue->wasReset()) { // Have we rendered yet? (Scene3D case) + // Traverse the current framegraph. For each leaf node create a + // RenderView and set its configuration then create a job to + // populate the RenderView with a set of RenderCommands that get + // their details from the RenderNodes that are visible to the + // Camera selected by the framegraph configuration + FrameGraphVisitor visitor(m_nodesManager->frameGraphManager()); + const QVector fgLeaves = visitor.traverse(frameGraphRoot()); + + const int fgBranchCount = fgLeaves.size(); + for (int i = 0; i < fgBranchCount; ++i) { + RenderViewBuilder builder(fgLeaves.at(i), i, this); + renderBinJobs.append(builder.buildJobHierachy()); + } - // Set target number of RenderViews - m_renderQueue->setTargetRenderViewCount(fgBranchCount); + // Set target number of RenderViews + m_renderQueue->setTargetRenderViewCount(fgBranchCount); + } return renderBinJobs; } diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h index 9df24ef2c..af10108e9 100644 --- a/src/render/backend/renderer_p.h +++ b/src/render/backend/renderer_p.h @@ -259,7 +259,7 @@ public: ViewSubmissionResultData submitRenderViews(const QVector &renderViews); - QMutex* mutex() { return &m_mutex; } + QMutex* mutex() { return &m_renderQueueMutex; } #ifdef QT3D_RENDER_UNIT_TESTS @@ -290,7 +290,7 @@ private: QScopedPointer m_renderThread; QScopedPointer m_vsyncFrameAdvanceService; - QMutex m_mutex; + QMutex m_renderQueueMutex; QSemaphore m_submitRenderViewsSemaphore; QSemaphore m_waitForInitializationToBeCompleted; diff --git a/src/render/backend/renderqueue.cpp b/src/render/backend/renderqueue.cpp index 6ec7da464..2fa1cb7d2 100644 --- a/src/render/backend/renderqueue.cpp +++ b/src/render/backend/renderqueue.cpp @@ -49,6 +49,7 @@ namespace Render { RenderQueue::RenderQueue() : m_noRender(false) + , m_wasReset(true) , m_targetRenderViewCount(0) , m_currentRenderViewCount(0) , m_currentWorkQueue(1) @@ -70,6 +71,7 @@ void RenderQueue::reset() m_targetRenderViewCount = 0; m_currentWorkQueue.clear(); m_noRender = false; + m_wasReset = true; } void RenderQueue::setNoRender() @@ -88,6 +90,7 @@ bool RenderQueue::queueRenderView(RenderView *renderView, uint submissionOrderIn Q_ASSERT(!m_noRender); m_currentWorkQueue[submissionOrderIndex] = renderView; ++m_currentRenderViewCount; + Q_ASSERT(m_currentRenderViewCount <= m_targetRenderViewCount); return isFrameQueueComplete(); } @@ -109,6 +112,7 @@ void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount) Q_ASSERT(!m_noRender); m_targetRenderViewCount = targetRenderViewCount; m_currentWorkQueue.resize(targetRenderViewCount); + m_wasReset = false; } /*! @@ -119,7 +123,7 @@ void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount) bool RenderQueue::isFrameQueueComplete() const { return (m_noRender - || (m_targetRenderViewCount && m_targetRenderViewCount == currentRenderViewCount())); + || (m_targetRenderViewCount > 0 && m_targetRenderViewCount == m_currentRenderViewCount)); } } // namespace Render diff --git a/src/render/backend/renderqueue_p.h b/src/render/backend/renderqueue_p.h index 49316049b..611f5849a 100644 --- a/src/render/backend/renderqueue_p.h +++ b/src/render/backend/renderqueue_p.h @@ -77,9 +77,13 @@ public: void reset(); void setNoRender(); + inline bool isNoRender() const { return m_noRender; } + + inline bool wasReset() const { return m_wasReset; } private: bool m_noRender; + bool m_wasReset; int m_targetRenderViewCount; int m_currentRenderViewCount; QVector m_currentWorkQueue; diff --git a/tests/auto/render/renderqueue/tst_renderqueue.cpp b/tests/auto/render/renderqueue/tst_renderqueue.cpp index 2d25cbe57..163a699c1 100644 --- a/tests/auto/render/renderqueue/tst_renderqueue.cpp +++ b/tests/auto/render/renderqueue/tst_renderqueue.cpp @@ -55,10 +55,14 @@ void tst_RenderQueue::setRenderViewCount() // GIVEN Qt3DRender::Render::RenderQueue renderQueue; + // THEN + QCOMPARE(renderQueue.wasReset(), true); + // WHEN renderQueue.setTargetRenderViewCount(7); // THEN + QCOMPARE(renderQueue.wasReset(), false); QVERIFY(renderQueue.targetRenderViewCount() == 7); QVERIFY(renderQueue.currentRenderViewCount()== 0); } @@ -214,6 +218,7 @@ void tst_RenderQueue::resetQueue() // WHEN renderQueue.setTargetRenderViewCount(5); // THEN + QCOMPARE(renderQueue.wasReset(), false); QVERIFY(renderQueue.currentRenderViewCount() == 0); // WHEN @@ -227,6 +232,7 @@ void tst_RenderQueue::resetQueue() // WHEN renderQueue.reset(); + QCOMPARE(renderQueue.wasReset(), true); // THEN QVERIFY(renderQueue.currentRenderViewCount() == 0); } -- cgit v1.2.3 From d947ef04bc162d9f1816afb6188e8ef0a30c5143 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 21 Mar 2017 12:23:27 +0100 Subject: Doc: correct several link errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qkeyframeanimation.cpp:61: warning: Can't link to 'Qt3D.Render::Transform' levelofdetailloader.qdoc:40: warning: Can't link to 'minimum' levelofdetailloader.qdoc:40: warning: Can't link to 'maximum' qlevelofdetail.cpp:201: warning: Can't link to 'Qt3DRender::QLevelOfDetail::SizeProxyMode' qlevelofdetailswitch.cpp:62: warning: Can't link to 'LevelOfDetailSwitch::currentIndex' Plus a minor language correction Change-Id: I26096ec74880a406ada27fb3d867983845611410 Reviewed-by: Venugopal Shivashankar Reviewed-by: Topi Reiniƶ --- src/animation/frontend/qkeyframeanimation.cpp | 2 +- src/doc/src/levelofdetailloader.qdoc | 2 +- src/render/frontend/qlevelofdetail.cpp | 31 +-------------------------- src/render/frontend/qlevelofdetailswitch.cpp | 8 ++++++- 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/src/animation/frontend/qkeyframeanimation.cpp b/src/animation/frontend/qkeyframeanimation.cpp index 0b17265a6..19069a8ed 100644 --- a/src/animation/frontend/qkeyframeanimation.cpp +++ b/src/animation/frontend/qkeyframeanimation.cpp @@ -68,7 +68,7 @@ namespace Qt3DAnimation { A KeyframeAnimation type implements simple keyframe animation that can be used to animate \l Transform. The keyframes consists of multiple - timed \l {Qt3D.Render::Transform}{Transforms}, which are interpolated and applied + timed \l {Qt3D.Core::Transform}s, which are interpolated and applied to the target Transform. EasingCurve is used between keyframes to control the interpolator. RepeatMode can be set for when the position set to the KeyframeAnimation is less or or greater than the values defined in the keyframe positions. diff --git a/src/doc/src/levelofdetailloader.qdoc b/src/doc/src/levelofdetailloader.qdoc index 65fda072a..6294e4735 100644 --- a/src/doc/src/levelofdetailloader.qdoc +++ b/src/doc/src/levelofdetailloader.qdoc @@ -40,12 +40,12 @@ /*! \qmltype LevelOfDetailLoader \inqmlmodule Qt3D.Render + \inherits Entity \since 5.9 \brief An entity loader that changes depending on distance to camera or screen size A LevelOfDetailLoader will load the entity matching the \l LevelOfDetail::currentIndex. The source is selected from the \l sources property. - The range is specified using the \l {minimum} and the \l{maximum} values. \sa LevelOfDetail */ diff --git a/src/render/frontend/qlevelofdetail.cpp b/src/render/frontend/qlevelofdetail.cpp index df169876e..4d6b07d4b 100644 --- a/src/render/frontend/qlevelofdetail.cpp +++ b/src/render/frontend/qlevelofdetail.cpp @@ -77,7 +77,7 @@ QLevelOfDetailPrivate::QLevelOfDetailPrivate() The currentIndex property can then be used, for example, to enable or disable entities, change material, etc. - The LevelOfDetail component is not shareable between multiple Entity's. + The LevelOfDetail component is not shareable between multiple \l [QML]{Entity}{entities}. \code #include @@ -185,35 +185,6 @@ QLevelOfDetailPrivate::QLevelOfDetailPrivate() * \sa Qt3DRender::QLevelOfDetail::ThresholdType */ - -/*! - * \enum Qt3DRender::QLevelOfDetail::SizeProxyMode - * - * Specifies what is used as a proxy for the entity when computing distance - * or size. - * - * \value LevelOfDetailBoundingSphere use the bounding sphere specified by the center - * and radius properties. - * \value Children LevelOfDetailBoundingSphere use the bounding sphere of the entity the - * component is attached to. - */ - -/*! - * \qmlproperty enumeration LevelOfDetail::SizeProxyMode - * - * Specifies what is used as a proxy for the entity when computing distance - * or size. - * - * \list - * \li LevelOfDetailBoundingSphere use the bounding sphere specified by the center - * and radius properties. - * \li Children LevelOfDetailBoundingSphere use the bounding sphere of the entity the - * component is attached to. - * \endlist - * \sa Qt3DRender::QLevelOfDetail::SizeProxyMode - */ - - /*! * \qmlproperty Camera LevelOfDetail::camera * diff --git a/src/render/frontend/qlevelofdetailswitch.cpp b/src/render/frontend/qlevelofdetailswitch.cpp index a6d2b1530..845fdd5a6 100644 --- a/src/render/frontend/qlevelofdetailswitch.cpp +++ b/src/render/frontend/qlevelofdetailswitch.cpp @@ -69,11 +69,17 @@ namespace Qt3DRender { This component is assigned to an entity. When the entity changes distance relative to the camera, the LevelOfDetailSwitch will disable all the child entities except - the one matching index \l LevelOfDetailSwitch::currentIndex. + the one matching index \l currentIndex. \sa LevelOfDetail */ +/*! + \qmlproperty int LevelOfDetailSwitch::currentIndex + + The index of the presently selected child entity. +*/ + /*! \fn Qt3DRender::QLevelOfDetailSwitch::QLevelOfDetailSwitch(Qt3DCore::QNode *parent) Constructs a new QLevelOfDetailSwitch with the specified \a parent. */ -- cgit v1.2.3