Skip to content

Kuesa Music Box QML Example

Demonstrates the use of the Kuesa API to import a glTF2 file and play animations.

music-box-example.jpg

QtQuick and Qt3D integration

The music-box example relies on the regular QtQuick and Qt 3D APIs to instantiate a QtQuick based application that combines Qt 3D based content with a 2D UI overlay.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import QtQuick 2.11
import QtQuick.Scene3D 2.0

Scene3D {
    id: scene3D
    anchors.fill: parent
    multisample: true
    aspects: ["input", "animation", "logic"]

    MainScene { }
}

Filename: music-box/qml/main.qml

SceneEntity

Kuesa provides the [SceneEntity ] element which holds collections of Qt 3D assets accessible by name.

1
2
3
4
5
6
import Kuesa 2.0 as Kuesa
import Kuesa.Effects 2.0 as KuesaFX
import MusicBox 1.0 as MusicBox

Kuesa.SceneEntity {
    id: scene

Filename: music-box/qml/MainScene.qml

Importing a glTF2 File

In order to load a glTF2 file, Kuesa provides the [GLTF2Importer ] element. If the sceneEntity property is set to a valid [SceneEntity ] instance, Qt 3D assets generated while parsing the file will be automatically added to the various asset collections.

1
2
3
4
    Kuesa.GLTF2Importer {
        id: importer
        sceneEntity: scene
        source: "file:" + _assetsDir + "models/music-box/RobotArm.gltf"

Filename: music-box/qml/MainScene.qml

Extracting and running Animations

We know in advance the name of the animations bundled in the glTF2 file. If you haven't authored the file yourself, you can use the Kuesa Studio gltfInspector to introspect it, list the animations and preview them.

Given a list of animation names:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    QtObject {
        id: d

        readonly property var robotArmAnimations: [
            'ArmTopAction',
            'FingerBase3Action',
            'armBottomBottomAction',
            'armBottomBottomGauge.001Action',
            'armBottomBottomGaugeAction',
            'armBottomTopAction',
            'cogAction',
            'elbowPivotAction',
            'elbowPivotBaseAction',
            'fingerBase2Action',
            'fingerKnuckle1Action',
            'fingerPivot1.001Action',
            'fingerPivot2Action',
            'fingerTop1Action',
            'fingerTop2Action',
            'fingerTop3Action',
            'handleAction.001',
            'handleCoverAction',
            'musicBarrelAction',
            'shoulderPivotAction',
            'shoulderPivotBaseAction',
            'thumbBaseBottomAction',
            'thumbKnuckleAction',
            'thumbPivotAction',
            'thumbTopAction',
            'wristPivotAction'
        ]

Filename: music-box/qml/MainScene.qml

We can generate [AnimationPlayer ] to control them.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    NodeInstantiator {
        id: actionPlayers
        model: []
        delegate: Kuesa.AnimationPlayer {
            sceneEntity: scene
            clip: modelData
            loops: Kuesa.AnimationPlayer.Infinite
            running: d.animationRunning
        }
    }

Filename: music-box/qml/MainScene.qml

Upon importing the glTF file, we can rely on the status change to trigger the animation playback.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
        onStatusChanged: {
            if (status == Kuesa.GLTF2Importer.Ready) {
                // start robot arm animation
                actionPlayers.model = d.robotArmAnimations;

                // get transforms for music barrel
                var musicBarrelTransform = scene.transformForEntity('musicBarrel');
                musicBarrelTransform.defaultPropertyTrackingMode = Node.TrackAllValues;

                d.animationRunning = true
            }
        }

Filename: music-box/qml/MainScene.qml


Updated on 2023-07-03 at 11:02:17 +0000