Qt Quick 3D - XR Einfaches Eingabebeispiel

Demonstriert die Controller-Eingabe in Qt Quick 3D XR.

Dieses Beispiel zeigt, wie man die Low-Level-Eingabe-APIs in Qt Quick 3D XR verwendet, um mit 2D- und 3D-Objekten in der Szene zu interagieren. Es folgt der Grundstruktur des xr_simple Beispiels.

Controller-Eingabe

In diesem Beispiel machen wir ray picking von der Position des XrController aus:

XrController {
    id: rightController
    controller: XrController.ControllerRight
    poseSpace: XrController.AimPose

    property QtObject hitObject

    onRotationChanged: {
        const pickResult = xrView.rayPick(scenePosition, forward)
        if (pickResult.hitType !== PickResult.Null) {
            pickRay.hit = true
            pickRay.length = pickResult.distance
            hitObject = pickResult.objectHit
        } else {
            pickRay.hit = false
            pickRay.length = 50
            hitObject = null
        }
    }

    Node {
        id: pickRay
        property real length: 50
        property bool hit: false

        z: -length/2
        Model {
            eulerRotation.x: 90
            scale: Qt.vector3d(0.02, pickRay.length/100, 0.02)
            source: "#Cylinder"
            materials: PrincipledMaterial { baseColor: pickRay.hit ? "green" : "gray" }
            opacity: 0.5
        }
    }

    Node {
        z: 5
        Model {
            eulerRotation.x: 90
            scale: Qt.vector3d(0.05, 0.10, 0.05)
            source: "#Cylinder"
            materials: PrincipledMaterial {
                baseColor: "black"
                roughness: 0.2
            }
        }
    }

}

Dies führt zwei Funktionen aus:

  1. Wenn wir etwas treffen, ändern wir die Farbe von pickRay auf grün, und wir stellen seine Länge so ein, dass er das getroffene Objekt berührt. Der pickRay ist ein halbtransparenter Zylinder, der anzeigt, wohin der Benutzer zielt.
  2. Wir setzen die Eigenschaft hitObject auf das Objekt, das wir getroffen haben.

Wir verwenden auch einen schwarzen Zylinder als generische Darstellung des Controllers.

Für dieses Beispiel haben wir einen einfachen 3D-Druckknopf in der Datei ExampleButton.qml erstellt. (Die Einzelheiten der Funktionsweise des Knopfes werden hier nicht erläutert.) Wir erstellen eine XrInputAction, um auf das Drücken des Auslösers zu reagieren:

XrInputAction {
    id: rightTrigger
    hand: XrInputAction.RightHand
    actionId: [XrInputAction.TriggerPressed, XrInputAction.TriggerValue, XrInputAction.IndexFingerPinch]
    onTriggered: {
        const button = rightController.hitObject as ExampleButton
        if (button && button !== panel.activeButton) {
            panel.activeButton = button
        }
    }
}

Die Aktion rightTrigger reagiert auf mehrere verschiedene IDs, um sowohl Hand-Tracking als auch verschiedene Arten von Controllern zu unterstützen. Wenn die Aktion ausgelöst wird, prüft sie, ob die hitObject, die wir oben festgelegt haben, vom Typ ExampleButton ist. Ist dies der Fall, wird die Schaltfläche aktiviert.

Damit ein 3D-Controller mit 2D-Inhalten interagieren kann, müssen wir eine XrVirtualMouse hinzufügen, um zwischen ihnen abzubilden:

XrInputAction {
    id: rightThumbstickX
    hand: XrInputAction.RightHand
    actionId: [XrInputAction.ThumbstickX]
}
XrInputAction {
    id: rightThumbstickY
    hand: XrInputAction.RightHand
    actionId: [XrInputAction.ThumbstickY]
}

XrVirtualMouse {
    view: xrView
    source: rightController
    leftMouseButton: rightTrigger.pressed
    scrollWheelX: rightThumbstickX.value
    scrollWheelY: rightThumbstickY.value
}

Zuerst fügen wir zwei weitere Aktionen hinzu, um die horizontale und vertikale Position des Daumensticks zu erkennen. Dann erstellen wir eine XrVirtualMouse, die die XrController als Positionsquelle verwendet. Wir verwenden die rightTrigger Aktion, die wir zuvor erstellt haben, um Mausdrücke und -freigaben zu erzeugen, und verwenden die Thumbstick-Aktionen, um Mausrad-Ereignisse zu erzeugen.

XrItem

Der normale Weg, 2D-Benutzeroberflächen in 3D-Szenen einzubetten, funktioniert auch in XR, aber da die Einheitsgröße ein Zentimeter ist, müssen diese Benutzeroberflächen skaliert werden, um nützlich zu sein. Der Typ XrItem bietet eine bequeme Möglichkeit, die Skalierung automatisch vorzunehmen, indem die physische Größe des 3D-Elements und die logische Größe der 2D-Oberfläche festgelegt werden.

XrItem {
    width: 75
    height: 100
    x: -100
    y: height + table.height + 5
    z: 40
    eulerRotation.y: 45
    color: "transparent"
    contentItem: Rectangle {
        color: Qt.rgba(1, 1, 1, 0.5)
        border.width: 5
        border.color: "lightblue"
        height: 400
        width: 300
        radius: 25
    ...
        }
    }

Wir positionieren die XrItem in drei Dimensionen und stellen sie auf 75 cm Breite und 100 cm Höhe ein. Dann fügen wir ein Rechteck als Inhaltselement hinzu und stellen es auf 300 x 400 Einheiten ein. Die übrigen Elemente der Benutzeroberfläche Qt Quick werden auf normale Weise als untergeordnete Elemente des Rechtecks hinzugefügt und werden hier nicht gezeigt. Der 2D-Inhalt wird automatisch so skaliert, dass er das XrItem füllt.

Beispielprojekt @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.