diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2018-05-11 13:36:12 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2018-05-11 13:36:22 +0200 |
commit | 78ab305d5ca59a158232a8b47070ef35ae803033 (patch) | |
tree | bf27f4ddd237347e934459663707632416610167 | |
parent | c292e052d6e5fa7c77c911109bf996b0d322ccb3 (diff) | |
parent | 3ab289edd2fc70d30686a499437a7013027d4e6c (diff) |
Merge remote-tracking branch 'origin/2.0'
Change-Id: Iba12208020aa39fe3c46b5b8c65c916f4fe454d7
54 files changed, 698 insertions, 189 deletions
diff --git a/examples/3dstudioruntime2/simpleoffscreen/simpleoffscreen.pro b/examples/3dstudioruntime2/simpleoffscreen/simpleoffscreen.pro index e4751db..e57ee63 100644 --- a/examples/3dstudioruntime2/simpleoffscreen/simpleoffscreen.pro +++ b/examples/3dstudioruntime2/simpleoffscreen/simpleoffscreen.pro @@ -1,5 +1,5 @@ TEMPLATE = app - +CONFIG += console QT += 3dstudioruntime2 SOURCES += \ diff --git a/src/3rdparty/imgui/qt_attribution.json b/src/3rdparty/imgui/qt_attribution.json index 93cbd89..d3b4381 100644 --- a/src/3rdparty/imgui/qt_attribution.json +++ b/src/3rdparty/imgui/qt_attribution.json @@ -2,7 +2,7 @@ { "Id": "imgui", "Name": "Dear ImGui", - "QDocModule": "qt3dstudio", + "QDocModule": "Qt3DStudioRuntime2", "Description": "Dear ImGui", "QtUsage": "Bloat-free GUI library for in-scene visualization of profiling and debugging data", diff --git a/src/doc/Qt3DStudioRuntime2.qdocconf b/src/doc/Qt3DStudioRuntime2.qdocconf new file mode 100644 index 0000000..6f5f526 --- /dev/null +++ b/src/doc/Qt3DStudioRuntime2.qdocconf @@ -0,0 +1,2 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) +include(qt3d-runtime-project.qdocconf) diff --git a/src/doc/doc.pro b/src/doc/doc.pro new file mode 100644 index 0000000..eba9ea3 --- /dev/null +++ b/src/doc/doc.pro @@ -0,0 +1,8 @@ +TEMPLATE = aux + +build_online_docs: \ + QMAKE_DOCS = $$PWD/online/Qt3DStudioRuntime2.qdocconf +else: \ + QMAKE_DOCS = $$PWD/Qt3DStudioRuntime2.qdocconf + +OTHER_FILES += $$PWD/src/*.qdoc diff --git a/src/doc/online/Qt3DStudioRuntime2.qdocconf b/src/doc/online/Qt3DStudioRuntime2.qdocconf new file mode 100644 index 0000000..4602372 --- /dev/null +++ b/src/doc/online/Qt3DStudioRuntime2.qdocconf @@ -0,0 +1,2 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults-online-commercial.qdocconf) +include(../qt3d-runtime-project.qdocconf) diff --git a/src/doc/qt3d-runtime-project.qdocconf b/src/doc/qt3d-runtime-project.qdocconf new file mode 100644 index 0000000..1c69bf4 --- /dev/null +++ b/src/doc/qt3d-runtime-project.qdocconf @@ -0,0 +1,55 @@ +project = Qt3DStudioRuntime2 +description = Qt 3D Studio Runtime Reference Manual +version = $QT_VERSION + +sourcedirs += ./src +imagedirs += ./src/images + +sourcedirs += ../runtime/api +headerdirs += ../runtime/api + +sourcedirs += ../imports/studio3d +headerdirs += ../imports/studio3d + +depends = qtcore qtgui qtwidgets qtqml qtquick qtdoc qt3dcore qt3drender qt3dlogic qt3danimation + +qhp.projects = 3dstudioruntime2 + +qhp.3dstudioruntime2.file = Qt3DStudioRuntime2.qhp +qhp.3dstudioruntime2.namespace = io.qt.qt3dstudioruntime2.$QT_VERSION_TAG +qhp.3dstudioruntime2.virtualFolder = Qt3DStudioRuntime2 +qhp.3dstudioruntime2.indexTitle = Qt 3D Studio Runtime +qhp.3dstudioruntime2.indexRoot = + +qhp.3dstudioruntime2.filterAttributes = Qt3DStudioRuntime2 $QT_VERSION +qhp.3dstudioruntime2.customFilters.Qt.name = Qt3DStudioRuntime2 $QT_VERSION +qhp.3dstudioruntime2.customFilters.Qt.filterAttributes = Qt3DStudioRuntime2 $QT_VERSION + +qhp.3dstudioruntime2.subprojects = manual qmltypes classes + +qhp.3dstudioruntime2.subprojects.manual.title = Qt 3D Studio Runtime +qhp.3dstudioruntime2.subprojects.manual.indexTitle = Qt 3D Studio Runtime TOC +qhp.3dstudioruntime2.subprojects.manual.type = manual + +qhp.3dstudioruntime2.subprojects.qmltypes.title = QML Types +qhp.3dstudioruntime2.subprojects.qmltypes.indexTitle = Qt 3D Studio Runtime QML Types +qhp.3dstudioruntime2.subprojects.qmltypes.selectors = qmltype +qhp.3dstudioruntime2.subprojects.qmltypes.sortPages = true + +qhp.3dstudioruntime2.subprojects.classes.title = C++ Classes +qhp.3dstudioruntime2.subprojects.classes.indexTitle = Qt 3D Studio Runtime C++ Classes +qhp.3dstudioruntime2.subprojects.classes.selectors = class fake:headerfile +qhp.3dstudioruntime2.subprojects.classes.sortPages = true + +# Add an .html file with sidebar content, used in the online style +HTML.stylesheets += style/qt5-sidebar.html + +navigation.homepage = Qt 3D Studio Runtime +navigation.cppclassespage = Qt 3D Studio Runtime C++ Classes +navigation.qmltypespage = Qt 3D Studio Runtime QML Types +buildversion = "Qt 3D Studio Runtime $QT_VER Manual" + +examplesinstallpath = 3dstudioruntime2 +exampledirs += ../../examples/3dstudioruntime2 + +Cpp.ignoretokens += Q3DSV_EXPORT diff --git a/src/doc/src/copyright.qdoc b/src/doc/src/copyright.qdoc new file mode 100644 index 0000000..01275f1 --- /dev/null +++ b/src/doc/src/copyright.qdoc @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page copyright-notices.html +\title Copyright Notices +\section1 Third-party Licenses + +The following table lists parts (modules) of Qt 3D Studio Runtime that +incorporate code licensed under third-party open-source licenses: + +\annotatedlist attributions-Qt3DStudioRuntime2 +*/ diff --git a/src/doc/src/embedded.qdoc b/src/doc/src/embedded.qdoc new file mode 100644 index 0000000..f665582 --- /dev/null +++ b/src/doc/src/embedded.qdoc @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qt3d-runtime-embedded.html + \title Using the Runtime on Embedded Devices + + embedded stuff (eglfs etc.) +*/ diff --git a/src/doc/src/examples.qdoc b/src/doc/src/examples.qdoc new file mode 100644 index 0000000..86cab63 --- /dev/null +++ b/src/doc/src/examples.qdoc @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \title Examples + \ingroup examples + \page qt3d-runtime-examples.html + \noautolist + + Included in Qt 3D Studio Runtime you will find a set of examples. These are + located in the \c {examples} folder in the installation folder. +*/ diff --git a/src/doc/src/gettingstarted.qdoc b/src/doc/src/gettingstarted.qdoc new file mode 100644 index 0000000..2f5ae37 --- /dev/null +++ b/src/doc/src/gettingstarted.qdoc @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qt3d-runtime-gettingstarted.html + \title Getting Started + + Basic blah blah +*/ diff --git a/src/doc/src/index.qdoc b/src/doc/src/index.qdoc new file mode 100644 index 0000000..a2c5282 --- /dev/null +++ b/src/doc/src/index.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\keyword Qt 3D Studio Runtime +\title Qt 3D Studio Runtime Index +\page index.html + +\section1 Table of Contents + +\list + \li \l {Getting Started} + \li \l {Qt 3D Studio Runtime C++ Classes} + \li \l {Qt 3D Studio Runtime QML Types} + \li \l {Using the Runtime on Android/iOS Devices} + \li \l {Using the Runtime on Embedded Devices} + \li \l {Examples} + \li \l {Copyright Notices} +\endlist + +blah blah blah + +*/ diff --git a/src/doc/src/mobile.qdoc b/src/doc/src/mobile.qdoc new file mode 100644 index 0000000..1787b63 --- /dev/null +++ b/src/doc/src/mobile.qdoc @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qt3d-runtime-mobile.html + \title Using the Runtime on Android/iOS Devices + + mobile stuff +*/ diff --git a/src/doc/src/module.qdoc b/src/doc/src/module.qdoc new file mode 100644 index 0000000..d37417f --- /dev/null +++ b/src/doc/src/module.qdoc @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qt3d-runtime-cpp.html + \title Qt 3D Studio Runtime C++ Classes + \keyword C++ API + \ingroup modules + + \brief Qt 3D Studio provides a number of C++ classes to view and control the presentation. + + To include the definitions of the module's classes, use the following directive: + + \badcode + #include <Qt3DStudioRuntime2> + \endcode + + To link against the module, add this line to your \l qmake \c .pro file: + + \badcode + QT += 3dstudioruntime2 + \endcode + + \section1 Classes + + \generatelist {classesbymodule 3dstudioruntime2} +*/ + +/*! + \page qt3d-runtime-qml.html + \title Qt 3D Studio Runtime QML Types + \keyword QML API + \ingroup qmlmodules + \noautolist + + \brief QML Types for the Qt 3D Studio Runtime module. + + Qt 3D Studio provides a number of QML types to view and control the + presentation. These types can be imported into your application using the + following import statement in your .qml file: + + \badcode + import QtStudio3D 2.0 + \endcode + + \section1 QML Types + + \generatelist {qmltypesbymodule QtStudio3D} +*/ diff --git a/src/doc/style/qt5-sidebar.html b/src/doc/style/qt5-sidebar.html new file mode 100644 index 0000000..89b8c0d --- /dev/null +++ b/src/doc/style/qt5-sidebar.html @@ -0,0 +1,13 @@ +<div class="sectionlist normallist"> + <div class="heading"> + <a name="reference"></a> + <h2 id="reference">Qt 3D Studio Runtime</h2> + </div> + <div class="indexboxcont indexboxbar"> + <ul> + <li><a href="getting-started.html">Getting Started</a></li> + <li><a href="qt3dstudio-studio.html">Studio</a></li> + <li><a href="qtstudio3d-qml-examples.html">Examples</a></li> + <li><a href="copyright-notices.html">Copyright Notices</a></li> + </ul> + </div> diff --git a/src/imports/studio3d/q3dsstudio3ditem.cpp b/src/imports/studio3d/q3dsstudio3ditem.cpp index c1fa45b..2326d1f 100644 --- a/src/imports/studio3d/q3dsstudio3ditem.cpp +++ b/src/imports/studio3d/q3dsstudio3ditem.cpp @@ -52,6 +52,17 @@ QT_BEGIN_NAMESPACE +/*! + \qmltype Studio3D + \instantiates Q3DSStudio3DItem + \inqmlmodule QtStudio3D + \ingroup 3dstudioruntime2 + \inherits Item + \brief blah + + blah +*/ + static bool engineCleanerRegistered = false; static QSet<Q3DSEngine *> engineTracker; static void engineCleaner() @@ -508,4 +519,10 @@ void Q3DSStudio3DItem::hoverMoveEvent(QHoverEvent *event) m_engine->handleMouseMoveEvent(&e); } +void Q3DSStudio3DItem::touchEvent(QTouchEvent *event) +{ + if (!m_eventIgnoreFlags.testFlag(IgnoreMouseEvents) && m_engine) + m_engine->handleTouchEvent(event); +} + QT_END_NAMESPACE diff --git a/src/imports/studio3d/q3dsstudio3ditem_p.h b/src/imports/studio3d/q3dsstudio3ditem_p.h index 9263131..042691c 100644 --- a/src/imports/studio3d/q3dsstudio3ditem_p.h +++ b/src/imports/studio3d/q3dsstudio3ditem_p.h @@ -113,6 +113,7 @@ private: void wheelEvent(QWheelEvent *event) override; #endif void hoverMoveEvent(QHoverEvent *event) override; + void touchEvent(QTouchEvent *event) override; void updateEventMasks(); void createEngine(); diff --git a/src/runtime/api/q3dsdatainput.h b/src/runtime/api/q3dsdatainput.h index 6fa0c54..e685f78 100644 --- a/src/runtime/api/q3dsdatainput.h +++ b/src/runtime/api/q3dsdatainput.h @@ -39,6 +39,11 @@ QT_BEGIN_NAMESPACE class Q3DSDataInputPrivate; class Q3DSPresentation; +// hack. no clue why Cpp.ignoretokens does not work. +#ifdef Q_CLANG_QDOC +#define Q3DSV_EXPORT +#endif + class Q3DSV_EXPORT Q3DSDataInput : public QObject { Q_OBJECT diff --git a/src/runtime/api/q3dselement.h b/src/runtime/api/q3dselement.h index fab455c..ec62590 100644 --- a/src/runtime/api/q3dselement.h +++ b/src/runtime/api/q3dselement.h @@ -39,6 +39,11 @@ QT_BEGIN_NAMESPACE class Q3DSElementPrivate; class Q3DSPresentation; +// hack. no clue why Cpp.ignoretokens does not work. +#ifdef Q_CLANG_QDOC +#define Q3DSV_EXPORT +#endif + class Q3DSV_EXPORT Q3DSElement : public QObject { Q_OBJECT diff --git a/src/runtime/api/q3dspresentation.cpp b/src/runtime/api/q3dspresentation.cpp index fa48b12..0f0cf89 100644 --- a/src/runtime/api/q3dspresentation.cpp +++ b/src/runtime/api/q3dspresentation.cpp @@ -248,6 +248,22 @@ void Q3DSPresentation::wheelEvent(QWheelEvent *e) } #endif +void Q3DSPresentation::touchEvent(QTouchEvent *e) +{ + Q_D(Q3DSPresentation); + if (d->controller && !d->source.isEmpty()) + d->controller->handlePresentationTouchEvent(e); +} + +#if QT_CONFIG(tabletevent) +void Q3DSPresentation::tabletEvent(QTabletEvent *e) +{ + Q_D(Q3DSPresentation); + if (d->controller && !d->source.isEmpty()) + d->controller->handlePresentationTabletEvent(e); +} +#endif + void Q3DSPresentationPrivate::setController(Q3DSPresentationController *c) { if (controller == c) diff --git a/src/runtime/api/q3dspresentation.h b/src/runtime/api/q3dspresentation.h index e3a45a0..085ce89 100644 --- a/src/runtime/api/q3dspresentation.h +++ b/src/runtime/api/q3dspresentation.h @@ -41,6 +41,13 @@ class Q3DSPresentationPrivate; class QKeyEvent; class QMouseEvent; class QWheelEvent; +class QTouchEvent; +class QTabletEvent; + +// hack. no clue why Cpp.ignoretokens does not work. +#ifdef Q_CLANG_QDOC +#define Q3DSV_EXPORT +#endif class Q3DSV_EXPORT Q3DSPresentation : public QObject { @@ -89,6 +96,10 @@ public: #if QT_CONFIG(wheelevent) void wheelEvent(QWheelEvent *e); #endif + void touchEvent(QTouchEvent *e); +#if QT_CONFIG(tabletevent) + void tabletEvent(QTabletEvent *e); +#endif Q_SIGNALS: void sourceChanged(); diff --git a/src/runtime/api/q3dspresentation_p.h b/src/runtime/api/q3dspresentation_p.h index 73a5b37..32ccb36 100644 --- a/src/runtime/api/q3dspresentation_p.h +++ b/src/runtime/api/q3dspresentation_p.h @@ -77,6 +77,10 @@ public: #if QT_CONFIG(wheelevent) virtual void handlePresentationWheelEvent(QWheelEvent *e); #endif + virtual void handlePresentationTouchEvent(QTouchEvent *e); +#if QT_CONFIG(tabletevent) + virtual void handlePresentationTabletEvent(QTabletEvent *e); +#endif virtual void handleDataInputValue(const QString &name, const QVariant &value); virtual void handleFireEvent(const QString &elementPath, const QString &eventName); diff --git a/src/runtime/api/q3dspresentationcontroller.cpp b/src/runtime/api/q3dspresentationcontroller.cpp index 31b9f86..2672a3f 100644 --- a/src/runtime/api/q3dspresentationcontroller.cpp +++ b/src/runtime/api/q3dspresentationcontroller.cpp @@ -106,6 +106,20 @@ void Q3DSPresentationController::handlePresentationWheelEvent(QWheelEvent *e) } #endif +void Q3DSPresentationController::handlePresentationTouchEvent(QTouchEvent *e) +{ + if (m_pcEngine) + m_pcEngine->handleTouchEvent(e); +} + +#if QT_CONFIG(tabletevent) +void Q3DSPresentationController::handlePresentationTabletEvent(QTabletEvent *e) +{ + if (m_pcEngine) + m_pcEngine->handleTabletEvent(e); +} +#endif + void Q3DSPresentationController::handleDataInputValue(const QString &name, const QVariant &value) { if (m_pcEngine) diff --git a/src/runtime/api/q3dssceneelement.cpp b/src/runtime/api/q3dssceneelement.cpp index 31a85b7..f8b3e23 100644 --- a/src/runtime/api/q3dssceneelement.cpp +++ b/src/runtime/api/q3dssceneelement.cpp @@ -153,13 +153,13 @@ void Q3DSSceneElementPrivate::_q_onSlideEntered(const QString &contextElemPath, currentSlideName = name; if (notifyPrevious) { - emit q->previousSlideIndexChanged(); - emit q->previousSlideNameChanged(); + emit q->previousSlideIndexChanged(previousSlideIndex); + emit q->previousSlideNameChanged(previousSlideName); } if (notifyCurrent) { - emit q->currentSlideIndexChanged(); - emit q->currentSlideNameChanged(); + emit q->currentSlideIndexChanged(currentSlideIndex); + emit q->currentSlideNameChanged(currentSlideName); } } diff --git a/src/runtime/api/q3dssceneelement.h b/src/runtime/api/q3dssceneelement.h index 0ac48ed..d8eba18 100644 --- a/src/runtime/api/q3dssceneelement.h +++ b/src/runtime/api/q3dssceneelement.h @@ -37,6 +37,11 @@ QT_BEGIN_NAMESPACE class Q3DSSceneElementPrivate; +// hack. no clue why Cpp.ignoretokens does not work. +#ifdef Q_CLANG_QDOC +#define Q3DSV_EXPORT +#endif + class Q3DSV_EXPORT Q3DSSceneElement : public Q3DSElement { Q_OBJECT @@ -63,10 +68,10 @@ public Q_SLOTS: void goToTime(float timeSeconds); Q_SIGNALS: - void currentSlideIndexChanged(); - void previousSlideIndexChanged(); - void currentSlideNameChanged(); - void previousSlideNameChanged(); + void currentSlideIndexChanged(int currentSlideIndex); + void previousSlideIndexChanged(int previousSlideIndex); + void currentSlideNameChanged(const QString ¤tSlideName); + void previousSlideNameChanged(const QString &previousSlideName); protected: Q3DSSceneElement(Q3DSSceneElementPrivate &dd, QObject *parent); diff --git a/src/runtime/api/q3dssurfaceviewer.h b/src/runtime/api/q3dssurfaceviewer.h index 6bda0c0..648df33 100644 --- a/src/runtime/api/q3dssurfaceviewer.h +++ b/src/runtime/api/q3dssurfaceviewer.h @@ -43,6 +43,11 @@ class QOpenGLContext; class Q3DSPresentation; class Q3DSViewerSettings; +// hack. no clue why Cpp.ignoretokens does not work. +#ifdef Q_CLANG_QDOC +#define Q3DSV_EXPORT +#endif + class Q3DSV_EXPORT Q3DSSurfaceViewer : public QObject { Q_OBJECT diff --git a/src/runtime/api/q3dsviewersettings.h b/src/runtime/api/q3dsviewersettings.h index 5a17aef..de64393 100644 --- a/src/runtime/api/q3dsviewersettings.h +++ b/src/runtime/api/q3dsviewersettings.h @@ -38,6 +38,11 @@ QT_BEGIN_NAMESPACE class Q3DSViewerSettingsPrivate; +// hack. no clue why Cpp.ignoretokens does not work. +#ifdef Q_CLANG_QDOC +#define Q3DSV_EXPORT +#endif + class Q3DSV_EXPORT Q3DSViewerSettings : public QObject { Q_OBJECT diff --git a/src/runtime/api/q3dswidget.cpp b/src/runtime/api/q3dswidget.cpp index d6af21c..6fb6d3e 100644 --- a/src/runtime/api/q3dswidget.cpp +++ b/src/runtime/api/q3dswidget.cpp @@ -42,6 +42,16 @@ QT_BEGIN_NAMESPACE +/*! + \class Q3DSWidget + + \inmodule 3dstudioruntime2 + + \brief Widget + + blah +*/ + Q3DSWidget::Q3DSWidget(QWidget *parent) : QOpenGLWidget(parent), d_ptr(new Q3DSWidgetPrivate(this)) diff --git a/src/runtime/api/q3dswidget.h b/src/runtime/api/q3dswidget.h index 183b03c..e5540ef 100644 --- a/src/runtime/api/q3dswidget.h +++ b/src/runtime/api/q3dswidget.h @@ -39,6 +39,11 @@ class Q3DSWidgetPrivate; class Q3DSPresentation; class Q3DSViewerSettings; +// hack. no clue why Cpp.ignoretokens does not work. +#ifdef Q_CLANG_QDOC +#define Q3DSV_EXPORT +#endif + class Q3DSV_EXPORT Q3DSWidget : public QOpenGLWidget { Q_OBJECT diff --git a/src/runtime/behaviorapi/q3dsbehaviorobject.cpp b/src/runtime/behaviorapi/q3dsbehaviorobject.cpp index 7534e25..75ac946 100644 --- a/src/runtime/behaviorapi/q3dsbehaviorobject.cpp +++ b/src/runtime/behaviorapi/q3dsbehaviorobject.cpp @@ -260,62 +260,6 @@ void Q3DSBehaviorObject::unregisterForEvent(const QString &handle, const QString } } -QVector2D Q3DSBehaviorObject::getMousePosition() -{ - const QPoint p = m_engine->lastMousePressPos(); - return QVector2D(p.x(), p.y()); -} - -QMatrix4x4 Q3DSBehaviorObject::calculateGlobalTransform() -{ - return calculateGlobalTransform(QString()); -} - -QMatrix4x4 Q3DSBehaviorObject::calculateGlobalTransform(const QString &handle) -{ - Q3DSGraphObject *obj = m_engine->findObjectByHashIdOrNameOrPath(m_behaviorInstance->parent(), m_presentation, handle); - if (!obj || !obj->isNode()) { - qWarning("calculateGlobalTransform: Invalid node reference %s", qPrintable(handle)); - return QMatrix4x4(); - } - - auto d = obj->attached<Q3DSNodeAttached>(); - if (!d) - return QMatrix4x4(); - - return d->globalTransform; -} - -QVector3D Q3DSBehaviorObject::lookAt(const QVector3D &target) -{ - const float mag = qSqrt(target.x() * target.x() + target.z() * target.z()); - const float pitch = -qAtan2(target.y(), mag); - const float yaw = qAtan2(target.x(), target.z()); - return QVector3D(pitch, yaw, 0); -} - -QVector3D Q3DSBehaviorObject::matrixToEuler(const QMatrix4x4 &matrix) -{ - // ### check if this gives results comparable to what 3DS1 does - const float *p = matrix.constData(); - const float rowMajor3x3[] = { p[0], p[4], p[8], - p[1], p[5], p[9], - p[2], p[6], p[10] }; - return QQuaternion::fromRotationMatrix(QMatrix3x3(rowMajor3x3)).toEulerAngles(); -} - -QString Q3DSBehaviorObject::getParent() -{ - return getParent(QString()); -} - -QString Q3DSBehaviorObject::getParent(const QString &handle) -{ - // highly sophisticated implementation. this function should not exist. - const QString parentStr = QLatin1String("parent"); - return handle.isEmpty() ? parentStr : handle + QLatin1Char('.') + parentStr; -} - void Q3DSBehaviorObject::setDataInputValue(const QString &name, const QVariant &value) { m_engine->setDataInputValue(name, value); diff --git a/src/runtime/behaviorapi/q3dsbehaviorobject_p.h b/src/runtime/behaviorapi/q3dsbehaviorobject_p.h index 94521a1..661e09f 100644 --- a/src/runtime/behaviorapi/q3dsbehaviorobject_p.h +++ b/src/runtime/behaviorapi/q3dsbehaviorobject_p.h @@ -79,13 +79,6 @@ public: const QJSValue &function); Q_INVOKABLE void unregisterForEvent(const QString &event); Q_INVOKABLE void unregisterForEvent(const QString &handle, const QString &event); - Q_INVOKABLE QVector2D getMousePosition(); - Q_REVISION(2) Q_INVOKABLE QMatrix4x4 calculateGlobalTransform(); - Q_INVOKABLE QMatrix4x4 calculateGlobalTransform(const QString &handle); - Q_INVOKABLE QVector3D lookAt(const QVector3D &target); - Q_INVOKABLE QVector3D matrixToEuler(const QMatrix4x4 &matrix); - Q_REVISION(2) Q_INVOKABLE QString getParent(); - Q_INVOKABLE QString getParent(const QString &handle); Q_REVISION(1) Q_INVOKABLE void setDataInputValue(const QString &name, const QVariant &value); signals: diff --git a/src/runtime/q3dsanimationmanager.cpp b/src/runtime/q3dsanimationmanager.cpp index 756ecfc..474a54d 100644 --- a/src/runtime/q3dsanimationmanager.cpp +++ b/src/runtime/q3dsanimationmanager.cpp @@ -496,16 +496,6 @@ void Q3DSAnimationManager::updateAnimationHelper(const AnimationTrackListMap<T * data->animationDataMap[slide]->animationCallbacks.append(cb); mapping->setCallback(type, cb, 0); mapper->addMapping(mapping.take()); - - // Save the current value of the animated property. - if (chIt->meta.getter && (!chIt->dynamic || data->animationRollbacks.isEmpty())) { - Q3DSGraphObjectAttached::AnimatedValueRollbackData rd; - rd.obj = target; - rd.name = chIt->meta.name; - rd.value = chIt->meta.getter(target, chIt->meta.name); - rd.setter = chIt->meta.setter; - data->animationRollbacks.append(rd); - } } Q_ASSERT(animator); @@ -538,7 +528,7 @@ private: Q3DSSlidePlayer *m_slidePlayer; }; -void Q3DSAnimationManager::clearAnimations(Q3DSSlide *slide, bool editorMode) +void Q3DSAnimationManager::clearAnimations(Q3DSSlide *slide) { qCDebug(lcAnim, "Clearing animations for slide (%s)", qPrintable(slide->name())); @@ -566,8 +556,7 @@ void Q3DSAnimationManager::clearAnimations(Q3DSSlide *slide, bool editorMode) if (!hasAnimationData) return; - const auto clearAndRollback = [this, editorMode](const QVector<Q3DSAnimationTrack> &anims, Q3DSSlide *slide) { - // Rollback properties + const auto cleanUpAnimationData = [this](const QVector<Q3DSAnimationTrack> &anims, Q3DSSlide *slide) { for (const Q3DSAnimationTrack &track : anims) { if (!m_activeTargets.contains(track.target())) continue; @@ -575,23 +564,6 @@ void Q3DSAnimationManager::clearAnimations(Q3DSSlide *slide, bool editorMode) Q3DSGraphObjectAttached *data = track.target()->attached(); Q3DSGraphObjectAttached::AnimationData *animationData = data->animationDataMap.value(slide); if (animationData) { - // Properties that were animated before have to be reset to their - // original value, otherwise things will flicker when switching between - // slides since the animations we build may not update the first value - // in time for the next frame. - if ((!track.isDynamic() || editorMode) && !data->animationRollbacks.isEmpty()) { - for (const auto &rd : qAsConst(data->animationRollbacks)) { - Q3DSAnimationManager::AnimationValueChange change; - change.value = rd.value; - change.name = rd.name; - change.setter = rd.setter; - queueChange(rd.obj, change); - } - // Set the values right away, do not wait until the next frame. - // This is important since updateAnimations() may query some of the - // now-restored values from the object. - applyChanges(); - } // Cleanup previous animation callbacks qDeleteAll(animationData->animationCallbacks); animationData->animationCallbacks.clear(); @@ -614,18 +586,8 @@ void Q3DSAnimationManager::clearAnimations(Q3DSSlide *slide, bool editorMode) Q_ASSERT(slideAttached->animators.isEmpty()); }; - // Handle unlinked properties (this is similart to the buildTrackListMap() pair in updateAnimations()). - // TODO: Make this more efficient - QVector<Q3DSAnimationTrack> tracks = masterSlide->animations(); - for (const auto &track : slide->animations()) { - auto foundIt = std::find_if(tracks.begin(), tracks.end(), [&track](const Q3DSAnimationTrack &t) { return (t.target() == track.target()) && (t.property() == track.property()); }); - if (foundIt != tracks.end()) - *foundIt = track; - else - tracks.push_back(track); - } - - clearAndRollback(tracks, slide); + cleanUpAnimationData(masterSlide->animations(), slide); + cleanUpAnimationData(slide->animations(), slide); } // Dummy animator for keeping track of the time line for the current slide @@ -724,6 +686,7 @@ void Q3DSAnimationManager::updateAnimations(Q3DSSlide *slide, bool editorMode) const QVector<Q3DSAnimationTrack> &anims = slide->animations(); for (const Q3DSAnimationTrack &animTrack : anims) { Q3DSGraphObject *target = animTrack.target(); + switch (target->type()) { case Q3DSGraphObject::DefaultMaterial: { diff --git a/src/runtime/q3dsanimationmanager_p.h b/src/runtime/q3dsanimationmanager_p.h index 47fa1d9..47ec31e 100644 --- a/src/runtime/q3dsanimationmanager_p.h +++ b/src/runtime/q3dsanimationmanager_p.h @@ -53,7 +53,7 @@ public: Q3DSAnimationManager(Q3DSSlidePlayer *slidePlayer) : m_slidePlayer(slidePlayer) {} void updateAnimations(Q3DSSlide *slide, bool editorMode = false); - void clearAnimations(Q3DSSlide *slide, bool editorMode = false); + void clearAnimations(Q3DSSlide *slide); void applyChanges(); void clearPendingChanges(); void objectAboutToBeRemovedFromScene(Q3DSGraphObject *obj); diff --git a/src/runtime/q3dsbehavior.cpp b/src/runtime/q3dsbehavior.cpp index 45a35b8..e480ac9 100644 --- a/src/runtime/q3dsbehavior.cpp +++ b/src/runtime/q3dsbehavior.cpp @@ -29,6 +29,7 @@ #include "q3dsbehavior_p.h" #include "q3dsutils_p.h" +#include "q3dslogging_p.h" #include "q3dsabstractxmlparser_p.h" #include <QFile> @@ -130,7 +131,6 @@ Q3DSBehavior Q3DSBehaviorParser::parse(const QString &filename, bool *ok) return Q3DSBehavior(); Q3DSBehavior behavior; - behavior.m_qmlCode = contents; behavior.m_qmlSourceUrl = QUrl::fromLocalFile(filename); // Find the metadata looking like this: @@ -157,6 +157,20 @@ Q3DSBehavior Q3DSBehaviorParser::parse(const QString &filename, bool *ok) } } + if (contents.indexOf(QLatin1String("\nimport QtQuick 2.")) < 0) { + // As a workaround for not getting QtQuick imported implicitly (unlike in + // 3DS1), insert "import QtQuick 2.0" before the first import (which is likely + // to be QtStudio3D.Behavior) + const QString quickImport = QLatin1String("import QtQuick 2.0\n"); + const int firstImportIdx = contents.indexOf(QLatin1String("\nimport ")); + if (firstImportIdx >= 0) { + qCDebug(lcUip, "Inserting import QtQuick 2.0 statement into %s", qPrintable(filename)); + contents.insert(firstImportIdx + 1, quickImport); + } + } + + behavior.m_qmlCode = contents; + if (ok) *ok = true; diff --git a/src/runtime/q3dsengine.cpp b/src/runtime/q3dsengine.cpp index fbb5233..30c7a44 100644 --- a/src/runtime/q3dsengine.cpp +++ b/src/runtime/q3dsengine.cpp @@ -150,6 +150,11 @@ Q3DSEngine::Q3DSEngine() // (since we want to see qCDebugs in release builds etc.) but there's // no need since that's the default since our category names do not // start with qt.* + + // q3ds.uipprop (data input value changes for ex.) is enabled only when + // Q3DS_DEBUG is set to 1 or higher. + const bool logValueChanges = qEnvironmentVariableIntValue("Q3DS_DEBUG") >= 1; + const_cast<QLoggingCategory &>(lcUipProp()).setEnabled(QtDebugMsg, logValueChanges); } } @@ -646,6 +651,9 @@ void Q3DSEngine::finalizePresentations() else m_aspectEngine->setRootEntity(Qt3DCore::QEntityPtr(m_uipPresentations[0].q3dscene.rootEntity)); + m_uipPresentations[0].q3dscene.renderSettings->setRenderPolicy(m_onDemandRendering ? + Qt3DRender::QRenderSettings::OnDemand : Qt3DRender::QRenderSettings::Always); + if (m_autoStart) { for (const UipPresentation &pres : m_uipPresentations) pres.sceneManager->prepareAnimators(); @@ -1116,6 +1124,9 @@ Qt3DCore::QEntity *Q3DSEngine::rootEntity() const void Q3DSEngine::setOnDemandRendering(bool enabled) { + if (m_onDemandRendering == enabled) + return; + m_onDemandRendering = enabled; m_uipPresentations[0].q3dscene.renderSettings->setRenderPolicy(enabled ? Qt3DRender::QRenderSettings::OnDemand : Qt3DRender::QRenderSettings::Always); } @@ -1214,8 +1225,6 @@ void Q3DSEngine::handleKeyReleaseEvent(QKeyEvent *e) void Q3DSEngine::handleMousePressEvent(QMouseEvent *e) { - m_lastMousePressPos = e->pos(); - if (isProfileUiVisible()) { QCoreApplication::sendEvent(&m_profileUiEventSource, e); return; @@ -1244,8 +1253,6 @@ void Q3DSEngine::handleMouseMoveEvent(QMouseEvent *e) void Q3DSEngine::handleMouseReleaseEvent(QMouseEvent *e) { - m_lastMousePressPos = e->pos(); - if (isProfileUiVisible()) { QCoreApplication::sendEvent(&m_profileUiEventSource, e); return; @@ -1292,6 +1299,20 @@ void Q3DSEngine::handleWheelEvent(QWheelEvent *e) } #endif +void Q3DSEngine::handleTouchEvent(QTouchEvent *e) +{ + Q_UNUSED(e); + // not much to do now, the touch-to-mouse synthesization of QtGui is good enough + // but will become relevant when multi-touch etc. +} + +#if QT_CONFIG(tabletevent) +void Q3DSEngine::handleTabletEvent(QTabletEvent *e) +{ + Q_UNUSED(e); +} +#endif + void Q3DSEngine::requestGrab() { if (m_capture) { diff --git a/src/runtime/q3dsengine_p.h b/src/runtime/q3dsengine_p.h index 478bd9e..946f7a1 100644 --- a/src/runtime/q3dsengine_p.h +++ b/src/runtime/q3dsengine_p.h @@ -56,6 +56,8 @@ QT_BEGIN_NAMESPACE class QKeyEvent; class QMouseEvent; class QWheelEvent; +class QTouchEvent; +class QTabletEvent; class QQmlEngine; class QQmlComponent; class Q3DSInlineQmlSubPresentation; @@ -162,6 +164,10 @@ public: #if QT_CONFIG(wheelevent) void handleWheelEvent(QWheelEvent *e); #endif + void handleTouchEvent(QTouchEvent *e); +#if QT_CONFIG(tabletevent) + void handleTabletEvent(QTabletEvent *e); +#endif void setAutoToggleProfileUi(bool enabled) { m_autoToggleProfileUi = enabled; } void setProfileUiVisible(bool visible); @@ -178,8 +184,6 @@ public: void unloadBehaviorInstance(Q3DSBehaviorInstance *behaviorInstance); const BehaviorMap &behaviorHandles() const { return m_behaviorHandles; } - QPoint lastMousePressPos() const { return m_lastMousePressPos; } - // These two functions are the only place where the elementPath concept is // present in the engine (so that mappings can be made for the 3DS1-style // APIs). Proper objects must be used everywhere else. @@ -275,7 +279,7 @@ private: bool m_ownsBehaviorQmlEngine = false; BehaviorMap m_behaviorHandles; - QPoint m_lastMousePressPos; + bool m_onDemandRendering = false; }; Q_DECLARE_OPERATORS_FOR_FLAGS(Q3DSEngine::Flags) diff --git a/src/runtime/q3dsinputmanager.cpp b/src/runtime/q3dsinputmanager.cpp index 068f4c6..774ad14 100644 --- a/src/runtime/q3dsinputmanager.cpp +++ b/src/runtime/q3dsinputmanager.cpp @@ -47,14 +47,14 @@ Q3DSInputManager::Q3DSInputManager(Q3DSSceneManager *sceneManager, QObject *pare void Q3DSInputManager::handleMousePressEvent(QMouseEvent *e) { m_currentState.mousePressed = true; - PickRequest req(e->pos(), m_currentState); + PickRequest req(e->pos() * m_sceneManager->m_guiData.outputDpr, m_currentState); m_pickRequests.append(req); } void Q3DSInputManager::handleMouseReleaseEvent(QMouseEvent *e) { m_currentState.mousePressed = false; - PickRequest req(e->pos(), m_currentState); + PickRequest req(e->pos() * m_sceneManager->m_guiData.outputDpr, m_currentState); m_pickRequests.append(req); } @@ -63,7 +63,7 @@ void Q3DSInputManager::handleMouseMoveEvent(QMouseEvent *e) if (!m_isHoverEnabled && !m_currentState.mousePressed) return; - PickRequest req(e->pos(), m_currentState); + PickRequest req(e->pos() * m_sceneManager->m_guiData.outputDpr, m_currentState); m_pickRequests.append(req); } diff --git a/src/runtime/q3dsmeshloader.cpp b/src/runtime/q3dsmeshloader.cpp index 1bda3a0..4b6f9fc 100644 --- a/src/runtime/q3dsmeshloader.cpp +++ b/src/runtime/q3dsmeshloader.cpp @@ -375,6 +375,7 @@ static const char *getTexTanAttrName() { return "attr_textan"; } //static const char *getTexBinormalAttrName() { return "attr_binormal"; } //static const char *getWeightAttrName() { return "attr_weight"; } //static const char *getBoneIndexAttrName() { return "attr_boneid"; } +static const char *getColorAttrName() { return "attr_color"; } struct MeshDataHeader { @@ -693,6 +694,19 @@ MeshList loadMeshData(const QByteArray &meshData, quint32 flags, bool useQt3DAtt stride); attributes.append(tangentsAttribute); } + + // Vertex Color + if (entryBufferMap.contains(QString::fromLocal8Bit(getColorAttrName()))) { + auto vertexColorEntry = entryBufferMap[QString::fromLocal8Bit(getColorAttrName())]; + auto colorAttribute = new Qt3DRender::QAttribute(vertexBuffer, + Qt3DRender::QAttribute::defaultColorAttributeName(), + convertRenderComponentToVertexBaseType(vertexColorEntry.m_ComponentType), + vertexColorEntry.m_NumComponents, + vertexCount, + vertexColorEntry.m_FirstItemOffset, + stride); + attributes.append(colorAttribute); + } } // Index Buffer auto indexBuffer = new Qt3DRender::QBuffer; diff --git a/src/runtime/q3dsscenemanager.cpp b/src/runtime/q3dsscenemanager.cpp index fddb1e0..85356e7 100644 --- a/src/runtime/q3dsscenemanager.cpp +++ b/src/runtime/q3dsscenemanager.cpp @@ -4451,9 +4451,9 @@ void Q3DSSceneManager::retagSubMeshes(Q3DSModelNode *model3DS) auto defaultMaterial = static_cast<Q3DSDefaultMaterial *>(sm.resolvedMaterial); opacity *= defaultMaterial->opacity() / 100.0f; // Check maps for transparency as well - hasTransparency = ((defaultMaterial->diffuseMap() && defaultMaterial->diffuseMap()->hasTransparency()) || - (defaultMaterial->diffuseMap2() && defaultMaterial->diffuseMap2()->hasTransparency()) || - (defaultMaterial->diffuseMap3() && defaultMaterial->diffuseMap3()->hasTransparency()) || + hasTransparency = ((defaultMaterial->diffuseMap() && defaultMaterial->diffuseMap()->hasTransparency(m_presentation)) || + (defaultMaterial->diffuseMap2() && defaultMaterial->diffuseMap2()->hasTransparency(m_presentation)) || + (defaultMaterial->diffuseMap3() && defaultMaterial->diffuseMap3()->hasTransparency(m_presentation)) || defaultMaterial->opacityMap() || defaultMaterial->translucencyMap() || defaultMaterial->displacementmap() || @@ -4462,7 +4462,7 @@ void Q3DSSceneManager::retagSubMeshes(Q3DSModelNode *model3DS) } else if (sm.resolvedMaterial->type() == Q3DSGraphObject::CustomMaterial) { auto customMaterial = static_cast<Q3DSCustomMaterialInstance *>(sm.resolvedMaterial); const Q3DSCustomMaterial *matDesc = customMaterial->material(); - sm.hasTransparency = matDesc->materialHasTransparency() || matDesc->materialHasRefraction(); + sm.hasTransparency = opacity < 1.0f || matDesc->materialHasTransparency() || matDesc->materialHasRefraction(); } Qt3DRender::QLayer *newTag = sm.hasTransparency ? layerData->transparentTag : layerData->opaqueTag; @@ -5040,6 +5040,11 @@ QVector<Qt3DRender::QParameter *> Q3DSSceneManager::prepareCustomMaterial(Q3DSCu data->params.insert(propKey, Q3DSCustomPropertyParameter(param, v, propMeta)); }); + + data->objectOpacityParam = new Qt3DRender::QParameter; + data->objectOpacityParam->setName(QLatin1String("object_opacity")); + paramList.append(data->objectOpacityParam); + // Lightmaps // check for referencedMaterial Overrides Q3DSImage *lightmapIndirect = nullptr; @@ -5129,6 +5134,8 @@ void Q3DSSceneManager::updateCustomMaterial(Q3DSCustomMaterialInstance *m, Q3DSR } }); + data->objectOpacityParam->setValue(data->opacity); + // Lightmaps Q3DSImage *lightmapIndirect = nullptr; if (rm && rm->lightmapIndirectMap()) @@ -6598,28 +6605,54 @@ void Q3DSSceneManager::handleSlideChange(Q3DSSlide *prevSlide, // Find properties on targets that has dynamic properties. // TODO: Find a better solution (e.g., there can be duplicate updates for e.g., xyz here). - QHash<Q3DSGraphObject *, Q3DSPropertyChangeList *> propertyChanges; + QHash<Q3DSGraphObject *, Q3DSPropertyChangeList *> dynamicPropertyChanges; + QVector<Q3DSPropertyChangeList *> ephemeralObjects; const auto &tracks = currentSlide->animations(); - std::find_if(tracks.cbegin(), tracks.cend(), [&propertyChanges](const Q3DSAnimationTrack &track) { + std::find_if(tracks.cbegin(), tracks.cend(), [&dynamicPropertyChanges, &ephemeralObjects](const Q3DSAnimationTrack &track) { if (track.isDynamic()) { - auto foundIt = propertyChanges.find(track.target()); - Q3DSPropertyChangeList *changesList = (foundIt != propertyChanges.end()) + auto foundIt = dynamicPropertyChanges.find(track.target()); + const bool propertyFound = (foundIt != dynamicPropertyChanges.end()); + Q3DSPropertyChangeList *changesList = propertyFound ? *foundIt : new Q3DSPropertyChangeList; + if (!propertyFound) + ephemeralObjects.push_back(changesList); const QString property = track.property().split('.')[0]; const auto value = track.target()->propertyValue(property); changesList->append(Q3DSPropertyChange::fromVariant(property, value)); - if (foundIt == propertyChanges.end()) - propertyChanges.insert(track.target(), changesList); + if (foundIt == dynamicPropertyChanges.end()) + dynamicPropertyChanges.insert(track.target(), changesList); } return false; }); - m_presentation->applySlidePropertyChanges(currentSlide); - // Now re-apply the original values for those dynamic keyframes. + const auto &propertyChanges = currentSlide->propertyChanges(); + + // Filter out properties that we needs to be marked dirty, i.e., eyeball changes. + QHash<Q3DSGraphObject *, Q3DSPropertyChangeList *> notifyPropertyChanges; + for (auto it = propertyChanges.cbegin(); it != propertyChanges.cend(); ++it) { + std::find_if((*it)->cbegin(), (*it)->cend(), [it, ¬ifyPropertyChanges, &ephemeralObjects](const Q3DSPropertyChange &propChange) { + if (propChange.name() == QLatin1String("eyeball")) { + Q3DSPropertyChangeList *propChangeList = new Q3DSPropertyChangeList; + propChangeList->append(propChange); + ephemeralObjects.push_back(propChangeList); + notifyPropertyChanges[it.key()] = propChangeList; + return true; + } + return false; + }); + } + // We avoid triggering notifications (i.e., setting dirty flags) just yet, as we + // want to defer that until we're ready. m_presentation->applyPropertyChanges(propertyChanges); + // notify about visibility changes. + m_presentation->notifyPropertyChanges(notifyPropertyChanges); + // Now re-apply the original values for those dynamic keyframes. + m_presentation->applyPropertyChanges(dynamicPropertyChanges); + // Now clean-up the objects we created. + qDeleteAll(ephemeralObjects); } void Q3DSSceneManager::prepareNextFrame() @@ -7207,6 +7240,9 @@ void Q3DSSceneManager::goToTime(Q3DSGraphObject *sceneOrComponent, float millise slidePlayer->pause(); slidePlayer->seek(milliseconds); + + if (!pause) + slidePlayer->play(); } void Q3DSSceneManager::setDataInputValue(const QString &dataInputName, const QVariant &value) diff --git a/src/runtime/q3dsscenemanager_p.h b/src/runtime/q3dsscenemanager_p.h index 7c3851a..fc494aa 100644 --- a/src/runtime/q3dsscenemanager_p.h +++ b/src/runtime/q3dsscenemanager_p.h @@ -522,6 +522,7 @@ class Q3DSCustomMaterialAttached : public Q3DSMaterialAttached { public: QHash<QString, Q3DSCustomPropertyParameter> params; + Qt3DRender::QParameter *objectOpacityParam = nullptr; // Lightmaps Q3DSTextureParameters lightmapIndirectParams; Q3DSTextureParameters lightmapRadiosityParams; diff --git a/src/runtime/q3dsslideplayer.cpp b/src/runtime/q3dsslideplayer.cpp index 96c73b2..fee148c 100644 --- a/src/runtime/q3dsslideplayer.cpp +++ b/src/runtime/q3dsslideplayer.cpp @@ -546,24 +546,19 @@ void Q3DSSlidePlayer::handleCurrentSlideChanged(Q3DSSlide *slide, qCDebug(lcSlidePlayer, "Handling current slide change: from slide \"%s\", to slide \"%s\"", qPrintable(getSlideName(previousSlide)), qPrintable(getSlideName(slide))); - // Disconnect monitors from the old slide if (previousSlide && slideDidChange) { if (parentChanged) setSlideTime(static_cast<Q3DSSlide *>(previousSlide->parent()), -1.0f); setSlideTime(previousSlide, -1.0f); Q3DSSlideAttached *data = previousSlide->attached<Q3DSSlideAttached>(); if (data && data->animator) { - Qt3DAnimation::QClipAnimator *animator = data->animator; // TODO: We probably want to be a bit less brute. if (slide) Q_ASSERT(previousSlide->parent() == slide->parent()); - animator->clearPropertyTrackings(); - animator->disconnect(); - updateAnimators(previousSlide, false, true, 1.0f); - m_animationManager->clearAnimations(previousSlide, (m_mode == PlayerMode::Editor)); + updateAnimators(previousSlide, false, false, 1.0f); + m_animationManager->clearAnimations(previousSlide); } } - // Connect to monitors to the new slide if (slide && slideDidChange && isSlideVisible(slide)) { m_sceneManager->handleSlideChange(previousSlide, slide); m_animationManager->updateAnimations(slide, (m_mode == PlayerMode::Editor)); @@ -696,7 +691,7 @@ void Q3DSSlidePlayer::sendPositionChanged(Q3DSSlide *slide, float pos) || (m_data.position == duration() && m_data.playbackRate > 0.0f)); if (onEOS) - QMetaObject::invokeMethod(this, "onSlideFinished", Qt::QueuedConnection, Q_ARG(void *, slide)); + onSlideFinished(slide); } void Q3DSSlidePlayer::updateNodeVisibility(Q3DSNode *node, bool shouldBeVisible) @@ -745,22 +740,11 @@ void Q3DSSlidePlayer::onDurationChanged(float duration) Q_EMIT durationChanged(duration); } -void Q3DSSlidePlayer::onSlideFinished(void *slide) +void Q3DSSlidePlayer::onSlideFinished(Q3DSSlide *slide) { Q_ASSERT(m_data.slideDeck); - - // The call to onSlideFinished is queued to avoid re-entrance issues, so make sure - // we're still operating and that the slide that finish is still current! - if (m_data.state != PlayerState::Playing) - return; - - Q3DSSlide *currentSlide = m_data.slideDeck->currentSlide(); - if (currentSlide != slide) { - qCDebug(lcSlidePlayer, "onSlideFinished called for \"%s\", but slide has already changed to \"%s!", - qPrintable(getSlideName(static_cast<Q3DSSlide *>(slide))), qPrintable(getSlideName(currentSlide))); - return; - } - + Q_ASSERT(m_data.state == PlayerState::Playing); + Q_ASSERT(slide == m_data.slideDeck->currentSlide()); // We don't change slides automatically in Editor mode if (m_mode == PlayerMode::Editor) { @@ -769,7 +753,7 @@ void Q3DSSlidePlayer::onSlideFinished(void *slide) } // Get the slide's play mode - const auto playMode = currentSlide->playMode(); + const auto playMode = slide->playMode(); PlayerState state = PlayerState::Stopped; @@ -779,12 +763,12 @@ void Q3DSSlidePlayer::onSlideFinished(void *slide) break; case Q3DSSlide::PlayThroughTo: { - if (currentSlide->playThrough() == Q3DSSlide::Next) { + if (slide->playThrough() == Q3DSSlide::Next) { m_data.slideDeck->nextSlide(); - } else if (currentSlide->playThrough() == Q3DSSlide::Previous) { + } else if (slide->playThrough() == Q3DSSlide::Previous) { m_data.slideDeck->previousSlide(); - } else if (currentSlide->playThrough() == Q3DSSlide::Value) { - const auto value = currentSlide->playThroughValue(); + } else if (slide->playThrough() == Q3DSSlide::Value) { + const auto value = slide->playThroughValue(); if (value.type() == QVariant::Int) { // Assume this is a fixed index value m_data.slideDeck->setCurrentIndex(value.toInt()); } else if (value.type() == QVariant::String) { // Reference to a slide? diff --git a/src/runtime/q3dsslideplayer_p.h b/src/runtime/q3dsslideplayer_p.h index 5ae5d70..11dd8c2 100644 --- a/src/runtime/q3dsslideplayer_p.h +++ b/src/runtime/q3dsslideplayer_p.h @@ -134,7 +134,7 @@ private: void reset(); void setInternalState(PlayerState state); void onDurationChanged(float duration); - Q_INVOKABLE void onSlideFinished(void *slide); + void onSlideFinished(Q3DSSlide *slide); void handleCurrentSlideChanged(Q3DSSlide *slide, Q3DSSlide *previousSlide, diff --git a/src/runtime/q3dsuippresentation.cpp b/src/runtime/q3dsuippresentation.cpp index 7779b63..5119b49 100644 --- a/src/runtime/q3dsuippresentation.cpp +++ b/src/runtime/q3dsuippresentation.cpp @@ -195,6 +195,10 @@ bool convertToFloat(const QStringRef &value, float *v, const char *desc, QXmlStr } bool ok = false; *v = value.toFloat(&ok); + // Adjust values that are "almost" zero values to 0.0, as we don't really expect values with + // more then 3-4 decimal points (note that qFuzzyIsNull does allow slightly higher resolution though). + if (ok && qFuzzyIsNull(*v)) + *v = 0.0f; if (!ok && reader) reader->raiseError(QObject::tr("Invalid %1 \"%2\"").arg(QString::fromUtf8(desc)).arg(value.toString())); return ok; @@ -1646,13 +1650,18 @@ namespace { } } -bool Q3DSImage::hasTransparency() +bool Q3DSImage::hasTransparency(Q3DSUipPresentation *presentation) { if (m_scannedForTransparency) return m_hasTransparency; // Do a pre-load of the texture to check for transparency - m_hasTransparency = scanForTransparency(sourcePath()); + if (presentation->imageTransparencyHash().contains(sourcePath())) { + m_hasTransparency = presentation->imageTransparencyHash()[sourcePath()]; + } else { + m_hasTransparency = scanForTransparency(sourcePath()); + presentation->imageTransparencyHash()[sourcePath()] = m_hasTransparency; + } m_scannedForTransparency = true; return m_hasTransparency; } @@ -1748,6 +1757,8 @@ void Q3DSDefaultMaterial::setProps(const V &attrs, PropSetFlags flags) parseProperty(attrs, flags, typeName, QStringLiteral("shaderlighting"), &m_shaderLighting); parseProperty(attrs, flags, typeName, QStringLiteral("blendmode"), &m_blendMode); + + parseProperty(attrs, flags, typeName, QStringLiteral("vertexcolors"), &m_vertexColors); parseProperty(attrs, flags, typeName, QStringLiteral("diffuse"), &m_diffuse); parseImageProperty(attrs, flags, typeName, QStringLiteral("diffusemap"), &m_diffuseMap_unresolved); @@ -1846,7 +1857,7 @@ int Q3DSDefaultMaterial::mapChangeFlags(const Q3DSPropertyChangeList &changeList QStringList Q3DSDefaultMaterial::propertyNames() const { QStringList s = Q3DSGraphObject::propertyNames(); - s << QLatin1String("shaderlighting") << QLatin1String("blendmode") << QLatin1String("diffuse") + s << QLatin1String("shaderlighting") << QLatin1String("blendmode") << QLatin1String("vertexcolors") << QLatin1String("diffuse") << QLatin1String("diffusemap") << QLatin1String("diffusemap2") << QLatin1String("diffusemap3") << QLatin1String("specularreflection") << QLatin1String("speculartint") << QLatin1String("specularamount") << QLatin1String("specularmap") << QLatin1String("specularmodel") @@ -1863,7 +1874,7 @@ QStringList Q3DSDefaultMaterial::propertyNames() const QVariantList Q3DSDefaultMaterial::propertyValues() const { QVariantList s = Q3DSGraphObject::propertyValues(); - s << m_shaderLighting << m_blendMode << m_diffuse << m_diffuseMap_unresolved << m_diffuseMap2_unresolved << m_diffuseMap3_unresolved + s << m_shaderLighting << m_blendMode << m_vertexColors << m_diffuse << m_diffuseMap_unresolved << m_diffuseMap2_unresolved << m_diffuseMap3_unresolved << m_specularReflection_unresolved << m_specularTint << m_specularAmount << m_specularMap_unresolved << m_specularModel << m_specularRoughness << m_roughnessMap_unresolved << m_fresnelPower << m_ior << m_bumpMap_unresolved << m_normalMap_unresolved << m_bumpAmount << m_displacementMap_unresolved << m_displaceAmount << m_opacity << m_opacityMap_unresolved << m_emissiveColor << m_emissivePower << m_emissiveMap_unresolved << m_emissiveMap2_unresolved @@ -3862,6 +3873,11 @@ void Q3DSUipPresentation::resolveAliases() } +QHash<QString, bool> &Q3DSUipPresentation::imageTransparencyHash() +{ + return m_imageTransparencyHash; +} + /*! Maps a raw XML filename ref like ".\Headphones\meshes\Headphones.mesh#1" onto a fully qualified filename that can be opened as-is (even if the uip @@ -4077,6 +4093,12 @@ void Q3DSUipPresentation::removeDataInputTarget(Q3DSGraphObject *obj) } } +void Q3DSUipPresentation::notifyPropertyChanges(const QHash<Q3DSGraphObject *, Q3DSPropertyChangeList *> &changeList) const +{ + for (auto it = changeList.cbegin(), ite = changeList.cend(); it != ite; ++it) + it.key()->notifyPropertyChanges(*it.value()); +} + void Q3DSUipPresentation::applyPropertyChanges(const QHash<Q3DSGraphObject *, Q3DSPropertyChangeList *> &changeList) const { for (auto it = changeList.cbegin(), ite = changeList.cend(); it != ite; ++it) { @@ -4085,9 +4107,6 @@ void Q3DSUipPresentation::applyPropertyChanges(const QHash<Q3DSGraphObject *, Q3 it.key()->applyPropertyChanges(*it.value()); } - - for (auto it = changeList.cbegin(), ite = changeList.cend(); it != ite; ++it) - it.key()->notifyPropertyChanges(*it.value()); } void Q3DSUipPresentation::applySlidePropertyChanges(Q3DSSlide *slide) const @@ -4095,6 +4114,7 @@ void Q3DSUipPresentation::applySlidePropertyChanges(Q3DSSlide *slide) const const auto &changeList = slide->propertyChanges(); qCDebug(lcUip, "Applying %d property changes from slide %s", changeList.count(), slide->id().constData()); applyPropertyChanges(changeList); + notifyPropertyChanges(changeList); } static void forAllObjectsInSubTree_helper(Q3DSGraphObject *obj, diff --git a/src/runtime/q3dsuippresentation_p.h b/src/runtime/q3dsuippresentation_p.h index 99bd11c..1f73a98 100644 --- a/src/runtime/q3dsuippresentation_p.h +++ b/src/runtime/q3dsuippresentation_p.h @@ -184,14 +184,6 @@ public: Qt3DCore::QEntity *entity = nullptr; Q3DSComponentNode *component = nullptr; - struct AnimatedValueRollbackData { - Q3DSGraphObject *obj; - QString name; - QVariant value; - Qt3DAnimation::SetterFunc setter; - }; - QVector<AnimatedValueRollbackData> animationRollbacks; - enum FrameDirtyFlag { GroupDirty = 0x01, LightDirty = 0x02, @@ -727,7 +719,7 @@ public: void calculateTextureTransform(); const QMatrix4x4 &textureTransform() const { return m_textureTransform; } - bool hasTransparency(); + bool hasTransparency(Q3DSUipPresentation *presentation); // Properties QString sourcePath() const { return m_sourcePath; } // already adjusted, can be opened as-is @@ -1562,6 +1554,7 @@ public: // Properties ShaderLighting shaderLighting() const { return m_shaderLighting; } BlendMode blendMode() const { return m_blendMode; } + bool vertexColors() const { return m_vertexColors; } QColor diffuse() const { return m_diffuse; } Q3DSImage *diffuseMap() const { return m_diffuseMap; } Q3DSImage *diffuseMap2() const { return m_diffuseMap2; } @@ -1637,6 +1630,7 @@ private: ShaderLighting m_shaderLighting = PixelShaderLighting; BlendMode m_blendMode = Normal; + bool m_vertexColors = false; QColor m_diffuse = Qt::white; QString m_diffuseMap_unresolved; Q3DSImage *m_diffuseMap = nullptr; @@ -2000,6 +1994,7 @@ public: static void forAllModels(Q3DSGraphObject *obj, std::function<void(Q3DSModelNode *)> f, bool includeHidden = false); void forAllImages(std::function<void(Q3DSImage *)> f); + void notifyPropertyChanges(const QHash<Q3DSGraphObject *, Q3DSPropertyChangeList *> &changeList) const; void applyPropertyChanges(const QHash<Q3DSGraphObject *, Q3DSPropertyChangeList *> &changeList) const; void applySlidePropertyChanges(Q3DSSlide *slide) const; @@ -2030,6 +2025,7 @@ public: obj->parent()->removeChildNode(obj); } void resolveAliases(); + QHash<QString, bool> &imageTransparencyHash(); private: Q_DISABLE_COPY(Q3DSUipPresentation) @@ -2042,6 +2038,7 @@ private: Q3DSGraphObject *getObjectByName(const QString &name) const; QScopedPointer<Q3DSUipPresentationData> d; + QHash<QString, bool> m_imageTransparencyHash; friend class Q3DSUipParser; }; diff --git a/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline.cpp b/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline.cpp index 7145510..5eb616d 100644 --- a/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline.cpp +++ b/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline.cpp @@ -417,6 +417,7 @@ struct ShaderGenerator : public Q3DSCustomMaterialShaderGenerator fragmentShader.append("\trgba = mix( vec4(0.0, 1.0, 0.0, 1.0), rgba, mixVal);"); } + fragmentShader << " rgba.a *= object_opacity;\n"; fragmentShader << " fragColor = rgba;\n"; } @@ -550,7 +551,7 @@ void Q3DSCustomMaterialVertexPipeline::beginFragmentGeneration() // Add "customMaterial.glsllib" because we dont apply it on load // like Qt3DStudio does. fragment().addInclude("customMaterial.glsllib"); - + fragment().addUniform("object_opacity", "float"); fragment() << "void main()" << "\n" << "{" << "\n"; } @@ -677,4 +678,10 @@ void Q3DSCustomMaterialVertexPipeline::doGenerateVarTangentAndBinormal() "\tvarObjBinormal = attr_binormal;\n"; } +void Q3DSCustomMaterialVertexPipeline::doGenerateVertexColor() +{ + vertex().addIncoming("attr_color", "vec3"); + vertex() << "\tvarColor = attr_color;"; +} + QT_END_NAMESPACE diff --git a/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline_p.h b/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline_p.h index 20b012e..f32b14d 100644 --- a/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline_p.h +++ b/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline_p.h @@ -66,6 +66,7 @@ public: void doGenerateObjectNormal() override; void doGenerateWorldPosition() override; void doGenerateVarTangentAndBinormal() override; + void doGenerateVertexColor() override; }; class Q3DSCustomMaterialShaderGenerator : public Q3DSAbstractMaterialGenerator diff --git a/src/runtime/shadergenerator/q3dsdefaultvertexpipeline.cpp b/src/runtime/shadergenerator/q3dsdefaultvertexpipeline.cpp index d860dcb..da532cd 100644 --- a/src/runtime/shadergenerator/q3dsdefaultvertexpipeline.cpp +++ b/src/runtime/shadergenerator/q3dsdefaultvertexpipeline.cpp @@ -522,6 +522,7 @@ struct ShaderGenerator : public Q3DSDefaultMaterialShaderGenerator { bool specularEnabled = m_CurrentMaterial->specularAmount() > 0.01f; bool fresnelEnabled = m_CurrentMaterial->fresnelPower() > 0.0f; + bool vertexColorsEnabled = m_CurrentMaterial->vertexColors(); bool hasLighting = m_CurrentMaterial->shaderLighting() != Q3DSDefaultMaterial::NoShaderLighting; bool hasLightmaps = false; @@ -647,6 +648,11 @@ struct ShaderGenerator : public Q3DSDefaultMaterialShaderGenerator if (includeSSAOSSDOVars || specularEnabled || hasIblProbe) vertexShader.generateVarTangentAndBinormal(); + if (vertexColorsEnabled) + vertexShader.generateVertexColor(); + else + fragmentShader.append("\tvec3 vertColor = vec3(1.0);"); + if (includeSSAOSSDOVars) { // You do bump or normal mapping but not both if (bumpImage != nullptr) { @@ -1099,7 +1105,7 @@ struct ShaderGenerator : public Q3DSDefaultMaterialShaderGenerator fragmentShader.append("\tglobal_diffuse_light.rgb += global_emission.rgb;"); // Ensure the rgb colors are in range. - fragmentShader.append("\tfragOutput = vec4( clamp( global_diffuse_light.xyz + " + fragmentShader.append("\tfragOutput = vec4( clamp( vertColor * global_diffuse_light.xyz + " "global_specular_light.xyz, 0.0, 65519.0 ), global_diffuse_light.a " ");"); @@ -1412,6 +1418,15 @@ void Q3DSVertexPipelineImpl::generateVarTangentAndBinormal() << "\tvec3 binormal = normalize(varBinormal);" << "\n"; } +void Q3DSVertexPipelineImpl::generateVertexColor() +{ + if (setCode(GenerationFlagValues::VertexColor)) + return; + addInterpolationParameter("varColor", "vec3"); + doGenerateVertexColor(); + fragment().append("\tvec3 vertColor = varColor;"); +} + bool Q3DSVertexPipelineImpl::hasActiveWireframe() { return m_Wireframe; diff --git a/src/runtime/shadergenerator/q3dsdefaultvertexpipeline_p.h b/src/runtime/shadergenerator/q3dsdefaultvertexpipeline_p.h index 40dd9f7..44aacf6 100644 --- a/src/runtime/shadergenerator/q3dsdefaultvertexpipeline_p.h +++ b/src/runtime/shadergenerator/q3dsdefaultvertexpipeline_p.h @@ -114,6 +114,7 @@ public: virtual void generateObjectNormal() = 0; // object_normal in both vert and frag shader virtual void generateWorldPosition() = 0; // model_world_position in both vert and frag shader virtual void generateVarTangentAndBinormal() = 0; + virtual void generateVertexColor() = 0; virtual bool hasActiveWireframe() = 0; // varEdgeDistance is a valid entity @@ -145,6 +146,7 @@ struct Q3DSVertexPipelineImpl : public Q3DSDefaultVertexPipeline WorldPosition = 1 << 5, TangentBinormal = 1 << 6, UVCoords1 = 1 << 7, + VertexColor = 1 << 8, }; }; @@ -204,6 +206,7 @@ struct Q3DSVertexPipelineImpl : public Q3DSDefaultVertexPipeline void generateVarTangentAndBinormal() override; + void generateVertexColor() override; bool hasActiveWireframe() override; @@ -241,6 +244,7 @@ struct Q3DSVertexPipelineImpl : public Q3DSDefaultVertexPipeline virtual void doGenerateObjectNormal() = 0; virtual void doGenerateWorldPosition() = 0; virtual void doGenerateVarTangentAndBinormal() = 0; + virtual void doGenerateVertexColor() = 0; }; QT_END_NAMESPACE diff --git a/src/runtime/shadergenerator/q3dsshadergenerators.cpp b/src/runtime/shadergenerator/q3dsshadergenerators.cpp index 78e02a9..5b80881 100644 --- a/src/runtime/shadergenerator/q3dsshadergenerators.cpp +++ b/src/runtime/shadergenerator/q3dsshadergenerators.cpp @@ -342,6 +342,12 @@ void Q3DSSubsetMaterialVertexPipeline::doGenerateVarTangentAndBinormal() } } +void Q3DSSubsetMaterialVertexPipeline::doGenerateVertexColor() +{ + vertex().addIncoming("attr_color", "vec3"); + vertex().append("\tvarColor = attr_color;"); +} + void Q3DSSubsetMaterialVertexPipeline::endVertexGeneration() { diff --git a/src/runtime/shadergenerator/q3dsshadergenerators_p.h b/src/runtime/shadergenerator/q3dsshadergenerators_p.h index 4b4f188..6ba5069 100644 --- a/src/runtime/shadergenerator/q3dsshadergenerators_p.h +++ b/src/runtime/shadergenerator/q3dsshadergenerators_p.h @@ -74,6 +74,8 @@ struct Q3DSSubsetMaterialVertexPipeline : public Q3DSVertexPipelineImpl void doGenerateVarTangentAndBinormal() override; + void doGenerateVertexColor() override; + void endVertexGeneration() override; void endFragmentGeneration() override; diff --git a/src/runtime/shadergenerator/q3dsshaderprogramgenerator.cpp b/src/runtime/shadergenerator/q3dsshaderprogramgenerator.cpp index 1ffb66c..eea49a0 100644 --- a/src/runtime/shadergenerator/q3dsshaderprogramgenerator.cpp +++ b/src/runtime/shadergenerator/q3dsshaderprogramgenerator.cpp @@ -520,7 +520,7 @@ public: return QStringLiteral("varying"); return QStringLiteral("in"); } - void addShaderOutgoingMap() + void addShaderOutgoingMap() override { // Do nothing } diff --git a/src/src.pro b/src/src.pro index 1b02d69..d1f86eb 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,7 +1,8 @@ TEMPLATE = subdirs SUBDIRS += \ - runtime + runtime \ + doc qtHaveModule(quick) { SUBDIRS += imports diff --git a/tools/q3dsviewer/main.cpp b/tools/q3dsviewer/main.cpp index 98438d5..1c1c15f 100644 --- a/tools/q3dsviewer/main.cpp +++ b/tools/q3dsviewer/main.cpp @@ -132,6 +132,7 @@ int main(int argc, char *argv[]) view->showFullScreen(); else view->show(); + engine->setOnDemandRendering(true); } else { #ifdef Q3DSVIEWER_WIDGETS mw = new Q3DStudioMainWindow(view.take(), remote.data()); diff --git a/tools/q3dsviewer/q3dsremotedeploymentmanager.cpp b/tools/q3dsviewer/q3dsremotedeploymentmanager.cpp index 5b47a38..557c067 100644 --- a/tools/q3dsviewer/q3dsremotedeploymentmanager.cpp +++ b/tools/q3dsviewer/q3dsremotedeploymentmanager.cpp @@ -93,6 +93,7 @@ void Q3DSRemoteDeploymentManager::stopServer() void Q3DSRemoteDeploymentManager::showConnectionSetup() { + startServer(); setupConnectionScene(); } diff --git a/tools/q3dsviewer/q3dsviewer.pro b/tools/q3dsviewer/q3dsviewer.pro index 8ee03da..dea32c3 100644 --- a/tools/q3dsviewer/q3dsviewer.pro +++ b/tools/q3dsviewer/q3dsviewer.pro @@ -1,6 +1,6 @@ QT += 3dstudioruntime2-private -qtHaveModule(widgets) { +qtHaveModule(widgets):!boot2qt { QT += widgets DEFINES += Q3DSVIEWER_WIDGETS SOURCES += q3dsmainwindow.cpp @@ -15,7 +15,12 @@ RC_ICONS = resources/images/3D-studio-viewer.ico ICON = resources/images/viewer.icns QMAKE_TARGET_DESCRIPTION = Qt 3D Studio Viewer -load(qt_app) +android { + TEMPLATE = app + TARGET = q3dsviewer +} else { + load(qt_app) +} CONFIG += app_bundle |