Skip to content

Kuesa Drill-Experience QML Example

Demonstrates the use of the Kuesa Runtime API to create a real world application

of the Application

This demo is structured around a single screen Depending on the user actions, we enter one of 3 modes

  • A interactive manual
  • A guide to drilling
  • An idling mode

Architecture of the Application

The demo has a strong split between the UI defined in QML and logic handling done in C++.

The UI is provided through a dedicated QML file.

When it comes to the logic handling, it's implemented through a dedicated controller. The controller takes care of providing a KuesaUtils::SceneConfiguration defining which glTF file to load, which camera to use for rendering as well as the a list of AnimationPlayers to control animations or TransformTrackers to retrieve the screen positions of 3D entities.

Additionally, the controller relies on KuesaUtils::SceneConfiguration::loadingDone and KuesaUtils::SceneConfiguration::unloadingDone to retrieve Kuesa assets from the SceneEntity collections upon loading and clearing any reference to such object upon unloading.

Through the use of properties and upon those being modified by the UI, the controller will react and might launch animations

Implementation

main.qml

This is the entry point of our Application.

First we instantiate an ApplicationWindow

 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
32
ApplicationWindow {
    id: mainRoot
    title: "Drill-Experience"
    visible: true
    visibility: ApplicationWindow.Maximized

    Material.theme: Material.Dark
    Material.accent: Material.Blue

    menuBar: ToolBar {
        Label {
            text: mainRoot.title
            font.pixelSize: 20
            anchors.centerIn: parent
        }
    }

    Item {
        id: contentItem
        anchors.fill: parent

        DrillScene {
            id: view3D
            anchors.fill: parent
        }

        UserManualUI {
            controller: view3D.controller
            anchors.fill: parent
        }
    }
}

Filename: drill-experience/qml/main.qml

QtQuick and Qt3D integration

The Drill-Experience example relies on the new simplified [View3D ] API introduced in Kuesa 2.0

 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
View3D {
    id: view3D
    focus: true
    asynchronous: true
    backgroundColor: "transparent"
    opacity: ready ? 1.0 : 0.0


    // Controllers
    // Readonly properties to expose controllers for external access
    readonly property ScreenController controller: _controller

    ScreenController {
        id: _controller
    }

    // We rely on the controller providing the scene configuration
    // This provides the source, camera, trackers, animation players...
    activeScene: controller.sceneConfiguration

    Entity {
        components: [
            MouseHandler {
                id: mouseHandler
                sourceDevice: MouseDevice {}
                // Use progress to control the orbit animation when in user manual mode
                property real progressOffset
                property bool isPressed: false

                onPressed: {
                    isPressed = true;
                    idleDetectionTimer.restart()
                    // Switch to the User Manual mode when pressing the screen
                    // while on the status screen
                    if (controller.mode === ScreenController.StatusMode) {
                        controller.mode = ScreenController.UserManualMode
                    } else if (controller.mode === ScreenController.UserManualMode){
                        // Record camera curve offset
                        progressOffset = controller.positionOnCameraOrbit + mouse.x / view3D.width
                    } else { // GuidedDrillingMode
                        controller.nextStep();
                    }
                }

                onReleased: isPressed = false;

                onPositionChanged: {
                    // Move camera along orbit curve
                    if (isPressed)
                        controller.positionOnCameraOrbit = Math.min(1.0, Math.max(0, progressOffset - (mouse.x / view3D.width)))
                }
            }
        ]
    }

    QQ2.Timer {
        id: idleDetectionTimer
        running: controller.mode !== ScreenController.StatusMode
        interval: 5 * 60 * 1000 // 5 minutes
        onTriggered: controller.mode = ScreenController.StatusMode
    }
}

Filename: drill-experience/qml/DrillScene.qml

DrillScene

This is the QML file in charge of setting up the 3D View.

[View3D ] is a subclass of the [SceneEntity ] element which holds collections of Qt 3D assets accessible by name.

This elements acts as the root elements of our DrillScene element. The [QML::Kuesa::Utils::View3D::activeScene] property is bound to the sceneConfiguration instanced returned by the controller. This ensure that when we switch screen and controller, we automatically switch to another SceneConfiguration.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
    // Controllers
    // Readonly properties to expose controllers for external access
    readonly property ScreenController controller: _controller

    ScreenController {
        id: _controller
    }

    // We rely on the controller providing the scene configuration
    // This provides the source, camera, trackers, animation players...
    activeScene: controller.sceneConfiguration

Filename: drill-experience/qml/DrillScene.qml

It is instantiated in the main.qml file

1
2
3
4
        DrillScene {
            id: view3D
            anchors.fill: parent
        }

Filename: drill-experience/qml/main.qml


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