summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-07-28 12:03:49 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-07-28 10:16:50 +0000
commit35455497abecb111a881b71b70451f2f5bfa8d28 (patch)
tree42bb1c6c00677ec2237e68860616eb16c5469efd
parent90623e3ccbeba4f498b3ce5c1b6c88f1122df434 (diff)
Enhance assimp-cpp example with exploring the loaded scene tree
Finding and possibly modifying the named parts of the loaded scene is essential in many cases. Therefore it is highly beneficial to have an example showing how to do this from C++. Change-Id: I3fefb80103b7e2f631464460c95067d414e4819f Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--examples/qt3d/assimp-cpp/main.cpp73
1 files changed, 69 insertions, 4 deletions
diff --git a/examples/qt3d/assimp-cpp/main.cpp b/examples/qt3d/assimp-cpp/main.cpp
index d068f443e..4b4048c6c 100644
--- a/examples/qt3d/assimp-cpp/main.cpp
+++ b/examples/qt3d/assimp-cpp/main.cpp
@@ -47,6 +47,58 @@
#include <Qt3DRenderer/QRenderAspect>
#include <Qt3DRenderer/QForwardRenderer>
+class SceneWalker : public QObject
+{
+public:
+ SceneWalker(Qt3D::QSceneLoader *loader) : m_loader(loader) { }
+
+ void onStatusChanged();
+
+private:
+ void walkEntity(Qt3D::QEntity *e, int depth = 0);
+
+ Qt3D::QSceneLoader *m_loader;
+};
+
+void SceneWalker::onStatusChanged()
+{
+ qDebug() << "Status changed:" << m_loader->status();
+ if (m_loader->status() != Qt3D::QSceneLoader::Loaded)
+ return;
+
+ // The QSceneLoader instance is a component of an entity. The loaded scene
+ // tree is added under this entity.
+ QVector<Qt3D::QEntity *> entities = m_loader->entities();
+
+ // Technically there could be multiple entities referencing the scene loader
+ // but sharing is discouraged, and in our case there will be one anyhow.
+ if (entities.isEmpty())
+ return;
+ Qt3D::QEntity *root = entities[0];
+ // Print the tree.
+ walkEntity(root);
+
+ // To access a given node (like a named mesh in the scene), use QObject::findChild().
+ // The scene structure and names always depend on the asset.
+ Qt3D::QEntity *e = root->findChild<Qt3D::QEntity *>(QStringLiteral("PlanePropeller_mesh")); // toyplane.obj
+ if (e)
+ qDebug() << "Found propeller node" << e << "with components" << e->components();
+}
+
+void SceneWalker::walkEntity(Qt3D::QEntity *e, int depth)
+{
+ Qt3D::QNodeList nodes = e->childrenNodes();
+ for (int i = 0; i < nodes.count(); ++i) {
+ Qt3D::QNode *node = nodes[i];
+ Qt3D::QEntity *entity = qobject_cast<Qt3D::QEntity *>(node);
+ if (entity) {
+ QString indent;
+ indent.fill(' ', depth * 2);
+ qDebug().noquote() << indent << "Entity:" << entity << "Components:" << entity->components();
+ walkEntity(entity, depth + 1);
+ }
+ }
+}
int main(int ac, char **av)
{
@@ -90,12 +142,25 @@ int main(int ac, char **av)
// Scene loader
Qt3D::QEntity *sceneLoaderEntity = new Qt3D::QEntity(sceneRoot);
Qt3D::QSceneLoader *sceneLoader = new Qt3D::QSceneLoader(sceneLoaderEntity);
+ SceneWalker sceneWalker(sceneLoader);
+ QObject::connect(sceneLoader, &Qt3D::QSceneLoader::statusChanged, &sceneWalker, &SceneWalker::onStatusChanged);
sceneLoaderEntity->addComponent(sceneLoader);
- QWidget *container = new QWidget();
- QFileDialog dialog;
- dialog.setFileMode(QFileDialog::AnyFile);
- sceneLoader->setSource(dialog.getOpenFileUrl(container, QStringLiteral("Open a scene file")));
+ QStringList args = QCoreApplication::arguments();
+ QUrl sourceFileName;
+ if (args.count() <= 1) {
+ QWidget *container = new QWidget();
+ QFileDialog dialog;
+ dialog.setFileMode(QFileDialog::AnyFile);
+ sourceFileName = dialog.getOpenFileUrl(container, QStringLiteral("Open a scene file"));
+ } else {
+ sourceFileName = QUrl::fromLocalFile(args[1]);
+ }
+
+ if (sourceFileName.isEmpty())
+ return 0;
+
+ sceneLoader->setSource(sourceFileName);
engine.setRootEntity(sceneRoot);
view.show();