Skip to content

Kuesa Placeholders

Kuesa provides handling for mapping placeholders defined in glTF files to QObject or QQuickItem.

Kuesa 2.0

Often times, 3D artist will want to position 2D UI placeholders within the 3D scene. In turn, the developer will want to map some custom UI element, usually developed in QML to the area defined by the placeholder. In addition, the content should always remain facing the camera in use.

Kuesa provides handling for mapping placeholders defined in glTF files to QObject or QQuickItem. This is achieved by relying on a custom KDAB_placeholder glTF extension and the qmltype{Kuesa::Qt3D::PlaceholderTracker} objects.

Whereas qmltypeposition of an Entity in the scene,

beyong that by providing access to positioning as well as sizing information.

Adding Placeholders to a glTF scene

Using Blender

Adding a Placeholder

Placeholders can be added by opening the add menu in Blender (Shift + A) and selection Placeholder in the Kuesa entry.

blender_placeholder_step1.png

The placeholder is materialized as a 3D plane. It might be hidden by existing geometry in the scene. If that's the case, it can be selected from the Blender Scene outline and moved (G) or rotated (R) until it becomes visible.

blender_placeholder_step2.pngblender_placeholder_step3.png

With the placeholder selected in the outliner, it is possible to select the Camera it should be facing.

blender_placeholder_step4.pngblender_placeholder_step5.png

The placement and transformations of the placeholder can be fine tuned further by viewing the scene from the Camera's point of View (Num 0).

blender_placeholder_step6.pngblender_placeholder_step7.png

One thing to keep in mind is that Placeholders in Blender are 3D objects. For that reason, they can be hidden by other 3D objects placed in front. However once exported and used from the KuesaRuntime, Placeholders are merely a way of mapping 2D UI obects to the 3D scene. They have therefore no physical appearanced and given UI is usually rendered as an overlay, the target item will likely be drawn on top of any 3D object.

blender_placeholder_step8.png

Exporting Placeholders

Select the gltf 2.0 exporter.

blender_placeholder_step9.png

Make sure the KDAB_kuesa_placeholder extension is enabled.

blender_placeholder_step10.png

Retrieving and tracking Placeholders

C++

Upon loading of a gltf file, placeholder instances will have to be retrieved from their collection, and tracked to update the screen space location. This can be achieved though the use of the qmltype{Kuesa::Qt3D::PlaceholderTracker}. On the tracker, scene size and camera should be specified. Optionally a target can be set on which the x, y, width and height properties will be set automatically.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Kuesa::Qt3D::SceneEntity *sceneEntity = new Kuesa::Qt3D::SceneEntity();
Kuesa::Qt3D::GLTF2Importer *importer = new Kuesa::Qt3D::GLTF2Importer();

QObject *uiTarget = new QObject();

Kuesa::Qt3D::PlaceholderTracker *placeholderTracker = new Kuesa::Qt3D::PlaceholderTracker();
placeholderTracker->setSceneEntity(sceneEntity);
placeholderTracker->setName(QStringliteral("PlaceHolder"));
placeholderTracker->setSceneSize({view.width(), view.height()});
placeholderTracker->setTarget(uiTarget);
placeholderTracker->setCamera(camera);

importer->setSceneEntity(sceneEntity);
importer->setSource(QUrl("file:///placeholder.gltf"));

Alternatively a simpler approach when using qmltype{KuesaUtils::View3DScene} is to simply do:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
QObject *uiTarget = new QObject();

KuesaUtils::SceneConfiguration sceneConfiguration;
sceneConf.setSource(QUrl("file:///placeholder.gltf));
sceneConf.setCameraName("CameraName");

Kuesa::Qt3D::PlaceholderTracker *placeholderTracker = new Kuesa::Qt3D::PlaceholderTracker();
placeholderTracker->setTarget(uiTarget);
placeholderTracker->setName(QStringliteral("PlaceHolder"));

sceneConf.addPlaceholderTracker(placeholderTracker);

KuesaUtils::View3DScene view3d;
view3d.setActiveScene(&sceneConfiguration);
...

The qmltypecamera and viewport size.

This was intented to use with QQuickItems as targets. For widgets, this might not work as well as Qt 3D currently requires a window container to integrate into widget applications. Window containers do not allow overlapping widgets.

QML

Upon loading of a gltf file, placeholder instances will have to be retrieved from their collection, and tracked to update the screen space location. This can be achieved though the use of the qmltype{Kuesa::Qt3D::PlaceholderTracker}. On the tracker, scene size and camera should be specified. Optionally a target can be set on which the x, y, width and height properties will be set automatically.

 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
import QtQuick 2.0
import Kuesa 2.0

Item {
    id: sceneRoot

    Rectangle {
        id: myItem
    }

    ...

    Kuesa.SceneEntity {
        id: scene
        ...
        Kuesa.GLTF2Importer {
            id: gltf2importer
            sceneEntity: scene
            source: "file:///placeholder.gltf"
        }
        PlaceholderTracker {
            name: "PlaceHolder"
            camera: camera
            screenSize: Qt.size(512, 512)
            target: uiTarget
        }
    }
}

Alternatively a simpler approach when using qmltype

 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
import QtQuick 2.0
import Kuesa 2.0
import Kuesa.Utils 2.0 as KuesaUtils

Item {
    id: sceneRoot

    Rectangle {
        id: myItem
    }

    KuesaUtils.View3D {
        id: scene3D
        anchors.fill: parent
        multisample: true

        source: "qrc:/placeholder.gltf"
        camera: "CameraName"
        placeholderTrackers: [
            Kuesa.PlaceholderTracker {
                name: "PlaceHolder"
                target: myItem
            }
        ]
    }
}

The qmltypeviewport size.


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