summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2018-11-15 15:00:09 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2018-11-16 10:19:47 +0000
commit0e5983e737abcd664e07f22da342f1ae41b52124 (patch)
treeb0d04b197bc46fff113192f87a88d01adaa4a524
parentb8e880e432e5cc640ba1cd95a85ca36c5a1a9a61 (diff)
Add a way to hook into the private API, with example and docsv2.2.0-beta1
Change-Id: Ib46f4e753964eaad02f455f80962321fb64496c4 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r--examples/3dstudioruntime2/3dstudioruntime2.pro3
-rw-r--r--examples/3dstudioruntime2/scenemanip/doc/images/scenemanip.pngbin0 -> 41349 bytes
-rw-r--r--examples/3dstudioruntime2/scenemanip/doc/src/scenemanip.qdoc46
-rw-r--r--examples/3dstudioruntime2/scenemanip/empty.uia15
-rw-r--r--examples/3dstudioruntime2/scenemanip/main.cpp155
-rw-r--r--examples/3dstudioruntime2/scenemanip/main.qml74
-rw-r--r--examples/3dstudioruntime2/scenemanip/presentations/empty.uip31
-rw-r--r--examples/3dstudioruntime2/scenemanip/scenemanip.pro14
-rw-r--r--examples/3dstudioruntime2/scenemanip/scenemanip.qrc7
-rw-r--r--src/runtime/api/q3dspresentation.cpp17
-rw-r--r--src/runtime/api/q3dspresentation.h3
-rw-r--r--src/runtime/api/q3dspresentation_p.h2
-rw-r--r--src/runtime/doc/src/examples.qdoc1
-rw-r--r--src/runtime/doc/src/index.qdoc1
-rw-r--r--src/runtime/doc/src/scenecppapi.qdoc247
15 files changed, 615 insertions, 1 deletions
diff --git a/examples/3dstudioruntime2/3dstudioruntime2.pro b/examples/3dstudioruntime2/3dstudioruntime2.pro
index 37e384d..d03ce05 100644
--- a/examples/3dstudioruntime2/3dstudioruntime2.pro
+++ b/examples/3dstudioruntime2/3dstudioruntime2.pro
@@ -7,7 +7,8 @@ SUBDIRS += \
qtHaveModule(quick) {
SUBDIRS += simpleqml \
qmldatainput \
- layersinquick
+ layersinquick \
+ scenemanip
}
qtHaveModule(widgets) {
diff --git a/examples/3dstudioruntime2/scenemanip/doc/images/scenemanip.png b/examples/3dstudioruntime2/scenemanip/doc/images/scenemanip.png
new file mode 100644
index 0000000..cdc5311
--- /dev/null
+++ b/examples/3dstudioruntime2/scenemanip/doc/images/scenemanip.png
Binary files differ
diff --git a/examples/3dstudioruntime2/scenemanip/doc/src/scenemanip.qdoc b/examples/3dstudioruntime2/scenemanip/doc/src/scenemanip.qdoc
new file mode 100644
index 0000000..871c57d
--- /dev/null
+++ b/examples/3dstudioruntime2/scenemanip/doc/src/scenemanip.qdoc
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the 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$
+**
+****************************************************************************/
+
+/*!
+ \example scenemanip
+ \title Qt 3D Studio Runtime: Dynamic Scene Manipulation C++ Example
+ \ingroup qt3dstudioruntime2-examples-cpp
+ \brief Demonstrates using the private C++ APIs to change the scene at run time
+
+ \image scenemanip.png
+
+ \e {This example demonstrates basic usage of the Qt 3D Studio runtime's
+ private C++ APIs in order to change the scene at run time.}
+
+ \include examples-run.qdocinc
+
+ This example uses the private C++ APIs from the Qt 3D Studio Runtime in
+ order to programatically create models and materials in a Qt 3D Studio
+ scene loaded from a \c{.uip} file into a Studio3D item inside a Qt Quick
+ scene. It also demonstrates connecting QML and C++ logic to events that
+ occur when an object is picked in the 3D scene.
+*/
diff --git a/examples/3dstudioruntime2/scenemanip/empty.uia b/examples/3dstudioruntime2/scenemanip/empty.uia
new file mode 100644
index 0000000..85e47c3
--- /dev/null
+++ b/examples/3dstudioruntime2/scenemanip/empty.uia
@@ -0,0 +1,15 @@
+<?xml version='1.0' encoding='utf-8'?>
+<application xmlns="http://qt.io/qt3dstudio/uia">
+ <assets initial="empty">
+ <presentation src="presentations/empty.uip" id="empty"/>
+ </assets>
+ <statemachine ref="#logic">
+ <visual-states>
+ <state ref="Initial">
+ <enter>
+ <goto-slide element="main:Scene" rel="next"/>
+ </enter>
+ </state>
+ </visual-states>
+ </statemachine>
+</application>
diff --git a/examples/3dstudioruntime2/scenemanip/main.cpp b/examples/3dstudioruntime2/scenemanip/main.cpp
new file mode 100644
index 0000000..a59c123
--- /dev/null
+++ b/examples/3dstudioruntime2/scenemanip/main.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGuiApplication>
+#include <QQmlContext>
+#include <QQuickView>
+#include <QTime>
+#include <QTimer>
+#include <Q3DSPresentation>
+
+#include <private/q3dsengine_p.h>
+#include <private/q3dsuippresentation_p.h>
+
+class SceneManipulator : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void doIt(Q3DSPresentation *pres);
+
+private:
+ QTimer m_timer;
+ int m_dynCount = 0;
+};
+
+void SceneManipulator::doIt(Q3DSPresentation *pres)
+{
+ Q3DSEngine *engine = pres->engine();
+ Q3DSUipPresentation *presentation = engine->presentation();
+ Q3DSSlide *slide1 = static_cast<Q3DSSlide *>(presentation->masterSlide()->firstChild());
+
+ Q3DSModelNode *prim = presentation->newObject<Q3DSModelNode>(QByteArrayLiteral("dynmodel") + QByteArray::number(m_dynCount));
+ switch (qrand() % 4) {
+ case 0:
+ prim->setMesh(QLatin1String("#Cube"));
+ break;
+ case 1:
+ prim->setMesh(QLatin1String("#Sphere"));
+ break;
+ case 2:
+ prim->setMesh(QLatin1String("#Cylinder"));
+ break;
+ case 3:
+ prim->setMesh(QLatin1String("#Cone"));
+ break;
+ }
+
+ Q3DSDefaultMaterial *primMat = presentation->newObject<Q3DSDefaultMaterial>(QByteArrayLiteral("dynmat") + QByteArray::number(m_dynCount));
+ prim->appendChildNode(primMat);
+
+ prim->setPosition(QVector3D((qrand() % 600) - 300, (qrand() % 600) - 300, 0));
+ prim->setRotation(QVector3D(30, 45, 0));
+ const float scale = ((qrand() % 100) + 1) / 100.0f;
+ prim->setScale(QVector3D(scale, scale, scale));
+
+ slide1->addObject(primMat);
+ slide1->addObject(prim);
+
+ ++m_dynCount;
+
+ // go live
+ presentation->objectByName<Q3DSLayerNode>(QLatin1String("Layer"))->appendChildNode(prim);
+
+ // Animations cannot be managed dynamically for now. However, nothing
+ // prevents us from changing properties as we see fit:
+ m_timer.setInterval(30);
+ connect(&m_timer, &QTimer::timeout, this, [prim] {
+ QVector3D v = prim->position();
+ v.setX(v.x() - 1);
+ QVector3D r = prim->rotation();
+ r.setY(r.y() + 1);
+ prim->notifyPropertyChanges({
+ prim->setPosition(v),
+ prim->setRotation(r)
+ });
+ });
+ m_timer.start();
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ qputenv("QSG_INFO", "1");
+ QGuiApplication app(argc, argv);
+
+ qsrand(QTime::currentTime().msec());
+
+ // Use the ideal format (i.e. OpenGL version and profile) recommended by
+ // the Qt 3D Studio runtime. Without this the format set on the QQuickView
+ // would be used instead.
+ QSurfaceFormat::setDefaultFormat(Q3DS::surfaceFormat());
+
+ QQuickView viewer;
+
+ SceneManipulator manip;
+ viewer.rootContext()->setContextProperty("sceneManipulator", &manip);
+
+ viewer.setSource(QUrl("qrc:/main.qml"));
+
+ viewer.setTitle(QStringLiteral("Qt 3D Studio Example"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.resize(1280, 720);
+ viewer.show();
+
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/examples/3dstudioruntime2/scenemanip/main.qml b/examples/3dstudioruntime2/scenemanip/main.qml
new file mode 100644
index 0000000..65d1412
--- /dev/null
+++ b/examples/3dstudioruntime2/scenemanip/main.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtStudio3D 2.2
+import QtQuick.Window 2.3
+
+Rectangle {
+ id: root
+ color: "lightGray"
+
+ Studio3D {
+ id: s3d
+ focus: true
+ anchors.margins: 20
+ anchors.fill: parent
+
+ Presentation {
+ id: s3dpres
+ source: "qrc:/empty.uia"
+ onCustomSignalEmitted: {
+ if (name === "doIt")
+ sceneManipulator.doIt(s3dpres);
+ }
+ }
+ }
+}
diff --git a/examples/3dstudioruntime2/scenemanip/presentations/empty.uip b/examples/3dstudioruntime2/scenemanip/presentations/empty.uip
new file mode 100644
index 0000000..3af7649
--- /dev/null
+++ b/examples/3dstudioruntime2/scenemanip/presentations/empty.uip
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<UIP version="4" >
+ <Project >
+ <ProjectSettings author="" company="" presentationWidth="1280" presentationHeight="720" maintainAspect="False" >
+ <CustomColors count="16" >#ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff</CustomColors>
+ </ProjectSettings>
+ <Graph >
+ <Scene id="Scene" >
+ <Layer id="Layer" >
+ <Camera id="Camera" />
+ <Light id="Light" />
+ <Text id="Text" />
+ </Layer>
+ </Scene>
+ </Graph>
+ <Logic >
+ <State name="Master Slide" component="#Scene" >
+ <Add ref="#Layer" />
+ <Add ref="#Camera" />
+ <Add ref="#Light" />
+ <State id="Scene-Slide1" name="Slide1" >
+ <Add ref="#Text" name="Text" font="TitilliumWeb-Regular" position="31.7543 285.788 0" textstring="Click this to dynamically change the scene" >
+ <Action id="Text-Action" eyeball="True" triggerObject="#Text" event="onPressureDown" targetObject="#Text" handler="Emit Signal" >
+ <HandlerArgument name="Signal Name" type="String" argtype="Signal" value="doIt" />
+ </Action>
+ </Add>
+ </State>
+ </State>
+ </Logic>
+ </Project>
+</UIP>
diff --git a/examples/3dstudioruntime2/scenemanip/scenemanip.pro b/examples/3dstudioruntime2/scenemanip/scenemanip.pro
new file mode 100644
index 0000000..0e462e5
--- /dev/null
+++ b/examples/3dstudioruntime2/scenemanip/scenemanip.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+
+QT += quick 3dstudioruntime2-private
+
+SOURCES += \
+ main.cpp
+
+RESOURCES += scenemanip.qrc
+
+OTHER_FILES += \
+ main.qml
+
+target.path = $$[QT_INSTALL_EXAMPLES]/3dstudioruntime2/$$TARGET
+INSTALLS += target
diff --git a/examples/3dstudioruntime2/scenemanip/scenemanip.qrc b/examples/3dstudioruntime2/scenemanip/scenemanip.qrc
new file mode 100644
index 0000000..1c1313a
--- /dev/null
+++ b/examples/3dstudioruntime2/scenemanip/scenemanip.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>empty.uia</file>
+ <file>presentations/empty.uip</file>
+ </qresource>
+</RCC>
diff --git a/src/runtime/api/q3dspresentation.cpp b/src/runtime/api/q3dspresentation.cpp
index 3a8e37e..db2f77a 100644
--- a/src/runtime/api/q3dspresentation.cpp
+++ b/src/runtime/api/q3dspresentation.cpp
@@ -633,6 +633,23 @@ void Q3DSPresentation::tabletEvent(QTabletEvent *e)
}
#endif
+/*!
+ Returns the underlying Q3DSEngine. See \l{Advanced Scene Manipulation via
+ the Qt 3D Studio Runtime Private C++ Classes} for details on using such
+ private APIs.
+
+ The engine is only available when a presentation is loaded, the return
+ value is \c null otherwise.
+ */
+Q3DSEngine *Q3DSPresentation::engine() const
+{
+ Q_D(const Q3DSPresentation);
+ if (d->controller && !d->source.isEmpty())
+ return d->controller->pcEngine();
+
+ return nullptr;
+}
+
void Q3DSPresentationPrivate::setController(Q3DSPresentationController *c)
{
if (controller == c)
diff --git a/src/runtime/api/q3dspresentation.h b/src/runtime/api/q3dspresentation.h
index 898eef8..3ee3aaf 100644
--- a/src/runtime/api/q3dspresentation.h
+++ b/src/runtime/api/q3dspresentation.h
@@ -43,6 +43,7 @@ class QMouseEvent;
class QWheelEvent;
class QTouchEvent;
class QTabletEvent;
+class Q3DSEngine;
// hack. no clue why Cpp.ignoretokens does not work.
#ifdef Q_CLANG_QDOC
@@ -105,6 +106,8 @@ public:
void tabletEvent(QTabletEvent *e);
#endif
+ Q3DSEngine *engine() const;
+
Q_SIGNALS:
void sourceChanged();
void profilingEnabledChanged();
diff --git a/src/runtime/api/q3dspresentation_p.h b/src/runtime/api/q3dspresentation_p.h
index 63c0f9a..56859a5 100644
--- a/src/runtime/api/q3dspresentation_p.h
+++ b/src/runtime/api/q3dspresentation_p.h
@@ -95,6 +95,8 @@ public:
bool compareElementPath(const QString &a, const QString &b) const;
+ Q3DSEngine *pcEngine() const { return m_pcEngine; }
+
protected:
Q3DSEngine *m_pcEngine = nullptr; // don't want clashes with commonly used m_engine members
QVector<QPair<QString, QVariant> > m_pendingDataInputSets;
diff --git a/src/runtime/doc/src/examples.qdoc b/src/runtime/doc/src/examples.qdoc
index 209f34d..e054410 100644
--- a/src/runtime/doc/src/examples.qdoc
+++ b/src/runtime/doc/src/examples.qdoc
@@ -48,6 +48,7 @@
\li \l {Qt 3D Studio Runtime: Simple Window Example}
\li \l {Qt 3D Studio Runtime: Simple Widget Example}
\li \l {Qt 3D Studio Runtime: Simple Offscreen Example}
+ \li \l {Qt 3D Studio Runtime: Dynamic Scene Manipulation C++ Example}
\endlist
\section1 More Examples
diff --git a/src/runtime/doc/src/index.qdoc b/src/runtime/doc/src/index.qdoc
index 387e86f..8ca579a 100644
--- a/src/runtime/doc/src/index.qdoc
+++ b/src/runtime/doc/src/index.qdoc
@@ -37,6 +37,7 @@
\li \l {Qt 3D Studio Runtime C++ Classes}
\li \l {Qt 3D Studio Runtime QML Types}
\li \l {Attribute Names}{Scene Object Attribute List}
+ \li \l {Advanced Scene Manipulation via the Qt 3D Studio Runtime Private C++ Classes}
\li \l {Using the In-Scene Debug and Profile views}
\li \l {Examples}
\li \l {Copyright Notices}
diff --git a/src/runtime/doc/src/scenecppapi.qdoc b/src/runtime/doc/src/scenecppapi.qdoc
new file mode 100644
index 0000000..4c0b622
--- /dev/null
+++ b/src/runtime/doc/src/scenecppapi.qdoc
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** 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-scenecppapi.html
+ \title Advanced Scene Manipulation via the Qt 3D Studio Runtime Private C++ Classes
+
+ In addition to the \l {Qt 3D Studio Runtime C++ Classes}}{public C++ API},
+ applications needing direct access to the scenegraph of the presentations
+ loaded from \c{.uip} files can use the runtime's private C++ classes.
+
+ \note These classes offer no source or binary compatibility guarantees.
+
+ \note There is no documentation provided for the private classes. Refer to
+ the examples, this page, and the header files instead.
+
+ To link against the module, add this line to your \l qmake \c .pro file:
+
+ \badcode
+ QT += 3dstudioruntime2-private
+ \endcode
+
+ Then add the following include statement to the application sources:
+
+ \badcode
+ #include <private/q3dsengine_p.h>
+ #include <private/q3dsuippresentation_p.h>
+ \endcode
+
+ To access the Q3DSEngine instance, call Q3DSPresentation::engine(). This
+ applies also to Qt Quick applications: the Presentation item in the QML
+ code is an instance of a subclass of Q3DSPresentation, so once it gets
+ passed to C++ code, it can be used as a Q3DSPresentation. Accessing the
+ engine is only possible when a presentation is loaded. If the code needing
+ access to the scene is not invoked by some user interaction but rather has
+ to be done at startup, connect the execution of the C++ logic to a signal
+ like Studio3D::presentationLoaded().
+
+ Check out the \l{Qt 3D Studio Runtime: Dynamic Scene Manipulation C++
+ Example}{scenemanip example} for a demonstration of manipulating the Qt 3D
+ Studio scene from C++ in a Qt Quick application.
+
+ The next step is to get access to the Qt 3D Studio object tree. Query the
+ Q3DSUipPresentation via Q3DSEngine::presentation(). There is a separate
+ object tree for each subpresentation. Q3DSEngine::presentationCount()
+ allows iterating through all of them:
+
+ \badcode
+ int presentationCount() const;
+ Q3DSUipPresentation *presentation(int index = 0) const;
+ Q3DSUipPresentation *presentationByName(const QString &name) const;
+ \endcode
+
+ The Q3DSUipPresentation instance owns two object trees: one for the scene
+ (that maps mostly 1:1 to the scene, layer, camera, light, model, etc. tree
+ in the left side of the Timline in the Qt 3D Studio editor) and one for the
+ slides.
+
+ To access these, use the following accessors:
+
+ \badcode
+ Q3DSScene *scene() const;
+ Q3DSSlide *masterSlide() const;
+ \endcode
+
+ Support for dynamically manipulating the slide structure is limited as of
+ now. Certain related operations, like adding or removing animation tracks
+ at runtime is also limited for the time being. For the rest of this
+ document, we will focus on the scene itself.
+
+ The scenegraph is quite similar to the Qt Quick scenegraph and QSGNode when
+ it comes to the management of child and sibling nodes. Adding and removing
+ child nodes happens using a very similar API. The equivalent of QSGNode in
+ the Qt 3D Studio world is Q3DSGraphObject. For application purposes the
+ most important member functions are:
+
+ \badcode
+ Type type() const
+ Q3DSGraphObject *parent() const
+ Q3DSGraphObject *firstChild() const
+ Q3DSGraphObject *lastChild() const
+ Q3DSGraphObject *nextSibling() const
+ Q3DSGraphObject *previousSibling() const
+ int childCount() const;
+ Q3DSGraphObject *childAtIndex(int idx) const;
+ void removeChildNode(Q3DSGraphObject *node);
+ void removeAllChildNodes();
+ void prependChildNode(Q3DSGraphObject *node);
+ void appendChildNode(Q3DSGraphObject *node);
+ void insertChildNodeBefore(Q3DSGraphObject *node, Q3DSGraphObject *before);
+ void insertChildNodeAfter(Q3DSGraphObject *node, Q3DSGraphObject *after);
+ void reparentChildNodesTo(Q3DSGraphObject *newParent);
+
+ virtual void applyPropertyChanges(const Q3DSPropertyChangeList &changeList);
+ void notifyPropertyChanges(const Q3DSPropertyChangeList &changeList, int changeFlags = -1);
+
+ QVector<QByteArray> propertyNames() const;
+ QVector<QVariant> propertyValues() const;
+
+ QVariant property(const char *name);
+ bool setProperty(const char *name, const QVariant &v);
+ QVector<QByteArray> dynamicPropertyNames() const;
+ QVector<QVariant> dynamicPropertyValues() const;
+
+ QVariantMap dynamicProperties() const;
+ void clearDynamicProperties();
+ Q3DSPropertyChangeList applyDynamicProperties(const QVariantMap &v);
+ \endcode
+
+ Q3DSLayerNode, Q3DSCameraNode, Q3DSLightNode, Q3DSModelNode, Q3DSGroupNode,
+ Q3DSTextNode are all subclasses of Q3DSNode which in turn is a
+ Q3DSGraphObject. The common base (Q3DSNode) provides common properties like
+ the transformation (position, rotation, scale).
+
+ To change a property at runtime, first find out the correct name for the
+ property from the \l {Attribute Names}{Scene Object Attribute List}.
+
+ Then do either
+
+ \badcode
+ node->notifyPropertyChanges({ node->setPosition(QVector3D(1.0f, 0.5f, 3.0f)) });
+ \endcode
+
+ or
+
+ \badcode
+ Q3DSPropertyChangeList cl { Q3DSPropertyChange::fromVariant("position", QVector3D(1.0f, 0.5f, 3.0f) };
+ node->applyPropertyChanges(cl);
+ node->notifyPropertyChanges(cl);
+ \endcode
+
+ The former is more efficient, while the latter allows constructing change
+ lists dynamically with the property names given as strings instead of
+ having to call C++ setter functions.
+
+ To get access to an object, for example, the Q3DSModelNode corresponding to
+ a Model in the editor, use the Q3DSUipPresentation's object() or
+ objectByName() functions. The latter is more useful for applications since
+ it works based on the Name (that is defined by the designer in the editor),
+ while the former uses the object id that is unique, but invisible to the
+ designer in the editor.
+
+ \note Names do not have to be unique. This can cause confusion because some
+ names the editor assigns by default are shared between multiple objects. To
+ prevent this, rename the objects in the tree view to something unique.
+
+ \badcode
+ auto car = presentation->objectByName<Q3DSModelNode>(QLatin1String("FancySportsCar"));
+ \endcode
+
+ Besides changing properties, adding or removing objects at runtime is also
+ possible. This will lead to the corresponding graphics objects appearing or
+ disappearing. For example, to spawn a new model object with the built-in
+ cube as its mesh:
+
+ \badcode
+ Q3DSModelNode *cube = presentation->newObject<Q3DSModelNode>(QByteArrayLiteral("newCube"));
+ cube->setMesh(QLatin1String("#Cube"));
+ Q3DSDefaultMaterial *cubeMat = presentation->newObject<Q3DSDefaultMaterial>(QByteArrayLiteral("cubeMaterial"));
+ cube->appendChildNode(cubeMat);
+ group->appendChildNode(cube);
+ \endcode
+
+ appendChildNode() takes ownership and inserts the given object in the
+ parent's child list. This is similar to QObject::setParent() but note that
+ QSGNode and Q3DSGraphObject are more powerful since they allow not just
+ appending but also inserting at arbitrary positions in the child list.
+
+ When a newly created object gets added to a parent that itself is already
+ part of a hierarchy under a Q3DSScene, the object becomes active, which
+ triggers creating the graphics and 3D resources that are necessary to
+ render the object in the associated layer's texture. In the above example
+ this point is the last appendChildNode() call, assuming \c group is an
+ object already parented into a live Q3DSScene tree.
+
+ To properly disconnect an object from the scene, use
+ Q3DSUipPresentation::unlinkObject():
+
+ \badcode
+ presentation->unlinkObject(cube);
+ delete cube;
+ \endcode
+
+ Due to the unlinkObject() call, the cube will disappear from the screen.
+ Note that the Q3DSDefaultMaterial child object is unlinked and destroyed as
+ well, just like a child QObject is destroyed together with its parent.
+
+ Being part of the scenegraph is not enough to get displayed, however. The
+ concept of slides has a great effect on visibility as well. To associate a
+ newly created object with a slide, call Q3DSSlide::addObject(). For
+ example, assuming the \c{.uip} file loaded has one slide under the master
+ slide:
+
+ \badcode
+ Q3DSSlide *slide = static_cast<Q3DSSlide *>(presentation->masterSlide()->firstChild());
+ slide->addObject(cubeMat);
+ slide->addObject(cube);
+ \endcode
+
+ The children of the new object have to be managed manually here, hence the
+ separate addObject(cubeMat) call. It is not required that all descendants
+ of an object belong to the same slide as the object.
+
+ When removing objects, make sure to disconnect them from the slide as well.
+ To do this recursively for all objects in the subtree that is about to
+ removed, one can do the following:
+
+ \badcode
+ Q3DSUipPresentation::forAllObjectsInSubTree(cube, [slide](Q3DSGraphObject *obj) {
+ slide->removeObject(obj);
+ });
+ \endcode
+
+ There are many more possibilities with the Q3DSGraphObject API. Refer to
+ the header files for more insight. It is worth nothing that it is also
+ possible to build Qt 3D Studio scenes completely from C++, without using
+ any \c{.uip} files. Check the demo application under
+ \c{tests/manual/standalone} in the runtime's source tree for an example of
+ creating and managing interactive scenes this way. It is also a good
+ example for performing advanced tasks via the private API, like reacting on
+ input events, providing custom mesh data, and dynamically generating
+ texture maps.
+*/