Dreidimensional mit Qt 3D Studio

Seite 3: Interaktion mit Szenenelementen

Inhaltsverzeichnis

Das Anzeigen einer dreidimensionalen Szene mag komfortabel sein, ist aber nur wenig sinnvoll – stattdessen ließe sich auch ein Film rendern und per Mediaplayer abspielen. Wirklich interessant wird Qt 3D Studio erst durch die Möglichkeit, mit Szeneninhalten dynamisch zu interagieren. Dahinter verbirgt sich der Gedanke, beispielsweise die Auslenkung des Zeigers programmatisch zu beeinflussen oder zwischen verschiedenen Szenen hin- und her wechseln zu können.

Wie bei den meisten auf Generatoren basierenden Projekten gilt auch hier, dass das Implementieren eines neuen Features im grafischen Teil des Produkts beginnt. Um mit der Bearbeitung der Szenenelemente beginnen zu können, ist zunächst die .uip-Datei zu öffnen, die vom Ressourcensystem in Qt 3D Studio geladen wird.

Mit Version 2.0 von Qt 3D Studio erzeugte Szenen sind automatisch mit zwei Slides ausgestattet, zwischen denen – zumindest in der Theorie – gewechselt werden sollten. Zur Anpassung sind folgende Änderungen am Code erforderlich:

Studio3D{
. . .
Presentation {
id: myPresentation
source: "qrc:/uip/SampleProject.uia"
}
onRunningChanged: {
myPresentation.goToSlide("Angle",1);
}

}

Grundlegende Interaktion mit den in Qt 3D Studio erzeugten Inhalten erfolgt prinzipiell über die Presentation-Klasse, der zur Sicherstellung der Ansprechbarkeit im ersten Schritt eine ID zugewiesen wird. Das Attribut onRunningChanged erlaubt das Festlegen von Code, der nach dem erfolgreichen Laden zur Ausführung gelangt.

Mit der Funktion goToSlide erfolgt der Wechsel zur zweiten Szene. Relevant ist dabei vor allem, dass das im Master angelegte Objekt hier nicht erscheint – es wird von einem der anderen Elemente in der Angle-Szene überdeckt.

Interessanter ist die Parametrierung der Methode. Die Funktion übernimmt den Namen der Szene und die numerische Idee der anzusprechenden Folie. Es ist möglich, in einer .uip-Datei mehrere Szenen anzulegen, die komplett unterschiedliche Inhalte generieren. Dies könnte zum Beispiel in einem Luftfahrzeug angebracht sein, wo die verschiedenen Systeme jeweils in einem eigenen Bildschirm dargestellt werden.

Um das Hantieren mit dem QML-Layoutsystem zu minimieren, sollte der Slider mit Margins integriert werden. Bei Bewegungen des Steuerelements treten aktuell gelegentliche Renderingfehler auf. Das Problem ist dem Qt-Team bekannt, ein Bugfix in Arbeit:

import QtQuick.Controls 1.4
Window { . . .
Slider {
id: mySlide
height: 50
value: 0.7
width: 600
}
Studio3D{
anchors.topMargin:50

An dieser Stelle lässt sich ein erster Versuch zur Beeinflussung der Szene unternehmen. Die Qt-3D-Studio-API macht einzelne Attribute der Elemente über jene Referenznamen ansprechbar, die auch im Rest von QML zum Einsatz kommen.

Der folgende Code soll probeweise ausgeführt werden:

Slider {
. . .
onValueChanged: {
myPresentation.setAttribute("Scene.Road3D.QT-symbol", "rotation.y", mySlide.value*200 );
myPresentation.setAttribute("DateAndTime", "textstring", mySlide.value*200);
. . .

setAttribute übernimmt hierbei drei Parameter: Erstens den Pfad, der das anzusprechende Element beschreibt. Hierbei handelt es sich im Grunde genommen um die Struktur, die in der Timeline des Qt-3D-Studio-Editors angezeigt wird – ein Rechtsklick auf ein Element öffnet das Kontextmenü mit Zugriff auf den Pfad. Zweitens folgt der Referenzattributname, und zu guter Letzt der jeweilige Wert.

Wird das Programm ausgeführt, verändert sich der Wert des Labels. Leider trifft das nicht auf die Drehung des Logos zu. Die Ursache dieses Verhaltens liegt darin, dass die Qt-3D-Studio-Runtime Attribute sammelt, bis ein neuer Frame gerendert werden kann. Im Fall des Programmbeispiels bedeutet dies, dass der durch setAttribute eingetragene Wert nie in der Renderingpipeline ankommt: Das in Qt 3D Studio enthaltene Animationsframework mahlt zuerst.

Die Interaktion zwischen in QML und in Qt 3D Studio erzeugten Objekten soll über das Data-Inputs-Feature erfolgen. In der Version 1.0 war dies nicht komplett implementiert, Version 2 schafft Abhilfe.

Ein Klick auf File -> Data Inputs veranlasst Qt 3D Studio zur Anzeige aller im aktuellen Projekt deklarierten Inputs. Die generierte Szene enthält die in Abbildung 9 gezeigten Input-Felder.

Abb. 9: Die Beispielszene bringt eine Gruppe von Attributen mit.

Durch Klick auf das Plus-Symbol erscheint ein Dialog zum Anlegen eines neuen Eingabeobjekts auf dem Bildschirm. Zum Zeitpunkt der Veröffentlichung dieses Artikels kennt Qt 3D Studio zwei Eingabetypen: Erstens den Typ Ranged Number und zweitens einen String. Definierte Ressourcen lassen sich nach Belieben aus QML heraus ansprechen und im Editor mit Steuerelementen verdrahten:

DataInput {
id: animationInput
name: "animationInput"
value: 0
}

Um die Handhabung dieser API kompakt zu demonstrieren, soll eines der vorgegebenen Attribute angepasst werden.

Presentation {
property int howFast: 22
DataInput {
name: "speed"
value: myPresentation.howFast
}
id: myPresentation

DataInput-Elemente quartieren sich prinzipiell in der Präsentation ein, die die zu beeinflussenden Elemente enthält. Wichtig ist, dass das Value-Attribut in der Praxis immer in Form eines QML-Attributs vorliegen sollte – beim direkten Übergeben normaler Werte kam es in verschiedenen vom Autor durchgeführten Tests zu unerklärlichem Verhalten.

Zur Fertigstellung ist schließlich nur noch eine Änderung von howFast durchzuführen – eine Aufgabe, die der Slider übernehmen kann:

Slider {
id: mySlide
. . .
onValueChanged: {
myPresentation.howFast=mySlide.value*300;
}
}
Mehr Infos

Mehr Beispiele!

Die Qt Company bietet eine Gruppe von sehr komplizierten Beispielen an, die die Interaktion zwischen QML und 3D Studio illustrieren.

Wird der Slider während der Ausführung des Programms über den Bildschirm gezogen, erscheint der im Tachometer angezeigte Wert automatisch. Nach dem Loslassen des Sliders läuft die Bewegung weiter, da es zu einem Konflikt zwischen der in der Szene angelegten Animation und dem Attribut kommt. Werte größer 260 kappt die Runtime übrigens automatisch, da der DataInput in Qt 3D Studio mit einer Beschränkung ausgestattet wurde.