diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-08-10 10:17:53 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-08-20 11:59:11 +0000 |
commit | 14bb6fb6d8e1fbde317111b57e42e3a380927d8b (patch) | |
tree | a7d85dd83aa8b72528c053733245df4a5fd5a723 /examples/qt3d/assimp | |
parent | 9bf2094621e3fba71710f47d7121f1182c3f3337 (diff) |
Create proper Quick extended classes in scene loaders
This allows exploring the loaded subtrees from QML/Javascript code. The
C++ classes are not suitable for this as they lack properties that involve
QML specifics.
The assimp (QML) example is updated to show how to do this (with the help
of some C++ code). Say hello to the pulsating torus and the rotating monkey!
Change-Id: I60401272105df5d72f4b7afebe26a3271e92f19e
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'examples/qt3d/assimp')
-rw-r--r-- | examples/qt3d/assimp/main.cpp | 41 | ||||
-rw-r--r-- | examples/qt3d/assimp/main.qml | 86 |
2 files changed, 125 insertions, 2 deletions
diff --git a/examples/qt3d/assimp/main.cpp b/examples/qt3d/assimp/main.cpp index d8fcbc269..8ada5287c 100644 --- a/examples/qt3d/assimp/main.cpp +++ b/examples/qt3d/assimp/main.cpp @@ -35,12 +35,46 @@ ****************************************************************************/ #include <window.h> -#include <Qt3DRenderer/qrenderaspect.h> +#include <Qt3DRenderer/QRenderAspect> +#include <Qt3DRenderer/QSceneLoader> +#include <Qt3DCore/QEntity> #include <Qt3DInput/QInputAspect> #include <Qt3DQuick/QQmlAspectEngine> #include <QGuiApplication> -#include <QtQml> +#include <qqml.h> + +class SceneHelper : public QObject +{ + Q_OBJECT + +public: + Q_INVOKABLE QObject *findEntity(Qt3D::QSceneLoader *loader, const QString &name); + Q_INVOKABLE void addListEntry(const QVariant &list, QObject *entry); +}; + +QObject *SceneHelper::findEntity(Qt3D::QSceneLoader *loader, const QString &name) +{ + // The QSceneLoader instance is a component of an entity. The loaded scene + // tree is added under this entity. + QVector<Qt3D::QEntity *> entities = loader->entities(); + + if (entities.isEmpty()) + return 0; + + // Technically there could be multiple entities referencing the scene loader + // but sharing is discouraged, and in our case there will be one anyhow. + Qt3D::QEntity *root = entities[0]; + + // The scene structure and names always depend on the asset. + return root->findChild<Qt3D::QEntity *>(name); +} + +void SceneHelper::addListEntry(const QVariant &list, QObject *entry) +{ + QQmlListReference ref = list.value<QQmlListReference>(); + ref.append(entry); +} int main(int argc, char* argv[]) { @@ -56,8 +90,11 @@ int main(int argc, char* argv[]) data.insert(QStringLiteral("eventSource"), QVariant::fromValue(&view)); engine.aspectEngine()->setData(data); engine.aspectEngine()->initialize(); + qmlRegisterType<SceneHelper>("Qt3D.Examples", 2, 0, "SceneHelper"); engine.setSource(QUrl("qrc:/main.qml")); view.show(); return app.exec(); } + +#include "main.moc" diff --git a/examples/qt3d/assimp/main.qml b/examples/qt3d/assimp/main.qml index ae6431476..e8819a51f 100644 --- a/examples/qt3d/assimp/main.qml +++ b/examples/qt3d/assimp/main.qml @@ -36,6 +36,8 @@ import Qt3D 2.0 import Qt3D.Renderer 2.0 +import Qt3D.Examples 2.0 +import QtQuick 2.0 as Quick Entity { @@ -62,6 +64,53 @@ Entity controlledCamera: camera } + // test_scene.dae contains three named nodes. Once the asynchronous loading of the + // scene completes, we look up some of them. + SceneHelper { + id: sceneHelper + } + + Quick.Component { + id: animParamComp + Quick.SequentialAnimation { + id: seqAnim + loops: Quick.Animation.Infinite + property variant target: null + Quick.ColorAnimation { + target: seqAnim.target + property: "value" + from: Qt.rgba(0, 0, 0, 1) + to: Qt.rgba(1, 1, 1, 1) + duration: 2000 + } + Quick.ColorAnimation { + target: seqAnim.target + property: "value" + from: Qt.rgba(1, 1, 1, 1) + to: Qt.rgba(0, 0, 0, 1) + duration: 1000 + } + } + } + + Quick.Component { + id: rot90Comp + Rotate { axis: Qt.vector3d(1, 0, 0); angle: 90 } + } + + Quick.Component { + id: animRotComp + Rotate { + axis: Qt.vector3d(0, 0, 1) + Quick.NumberAnimation on angle { + from: 0 + to: 360 + duration: 5000 + loops: Quick.Animation.Infinite + } + } + } + Entity { components : [ Transform { @@ -69,7 +118,44 @@ Entity }, SceneLoader { + id: sceneLoader source: "qrc:/assets/test_scene.dae" + onStatusChanged: { + console.log("SceneLoader status: " + status); + if (status == SceneLoader.Loaded) { + console.log("Scene is ready"); + + // Now find the torus and animate one of the material effect's parameters. + var e = sceneHelper.findEntity(sceneLoader, "Torus"); + console.log("Found entity: " + e + " its components are:"); + for (var i = 0; i < e.components.length; ++i) { + console.log(" " + e.components[i]); + if (e.components[i].effect !== undefined) { + var p = e.components[i].effect.parameters; + for (var j = 0; j < p.length; ++j) { + if (p[j].name === "kd") { + var anim = animParamComp.createObject(p[j]); + anim.target = p[j]; + anim.running = true; + break; + } + } + + } + } + + // Add an animated rotation transform. + e = sceneHelper.findEntity(sceneLoader, "Suzanne"); + for (var i = 0; i < e.components.length; ++i) { + if (e.components[i].transforms !== undefined) { + var t = e.components[i].transforms; + sceneHelper.addListEntry(t, rot90Comp.createObject()); + sceneHelper.addListEntry(t, animRotComp.createObject()); + break; + } + } + } + } }] } |