Qt Quick 3D - XR 3D Interaktionsbeispiel

Zeigt, wie 3D-Objekte mit Qt Quick 3D XR manipuliert werden können.

Dieses Beispiel zeigt, wie man Komponenten erstellt, die 3D-Objekte in einer Szene bewegen und in der Größe verändern. Es verwendet die gleiche Ray-Picking-Strategie wie das xr_input Beispiel.

Controller-Eingabe

In diesem Beispiel erstellen wir eine wiederverwendbare Komponente namens AimController. Diese führt Ray-Picking durch, um ein Modell auszuwählen, und ermöglicht es dem Benutzer optional, das ausgewählte Modell zu greifen und es zu bewegen.

AimController definiert Signale, die es uns ermöglichen, benutzerdefinierte Interaktionen zu implementieren:

property Model hoveredObject: null
signal objectPressed(obj: Model, pos: vector3d, direction: vector3d)
signal moved(pos: vector3d, direction: vector3d)
signal released()
signal objectGrabbed(obj: Model)

Gadgets

Wir definieren eine abstrakte Komponente, XrGadget, die über zwei Funktionen verfügt: handleControllerPress und handleControllerMove. In C++ wären diese Funktionen virtuell gewesen. Da dieses Beispiel vollständig in QML implementiert ist, geben wir stattdessen Signale aus, die in Unterkomponenten verarbeitet werden können.

Zum Beispiel bewegt TranslateGadget das kontrollierte Objekt entlang der Gadget-Achse, basierend auf dem Signal onMoved:

onMoved: (pos, dir) => {
    let moveDirection = delta.normalized()
    let mapped_axis = controlledObject.mapDirectionToScene(axisDirection).normalized()
    let dot = mapped_axis.dotProduct(moveDirection)
    let offset = mapped_axis.times(delta.length() * dot)
    controlledObject.position = originalPos.plus(offset)
}

Wiederverwendbare Komponenten

Wir haben AimController und die Gadgets in das separate Unterprojekt xr_shared aufgenommen, damit wir sie in zukünftigen Beispielen wiederverwenden können. (xr_shared enthält auch die Komponente FreeformTeleporter aus dem Freeform Teleportation Example).

Alles zusammenbinden

Wir definieren eine Komponente GadgetBox, die verfolgt, welches Objekt ausgewählt ist, und die einen durchsichtigen Kasten um das ausgewählte Objekt herum anzeigt, zusätzlich zu den Gadgets, die um das Objekt herum angezeigt werden. Wenn ein ausgewähltes Objekt gedrückt wird, wechselt GadgetBox zwischen den drei verschiedenen Arten von Gadgets (Übersetzen, Drehen und Größenänderung).

In main.qml reagieren wir auf die Signale von AimController und rufen die Funktionen in GadgetBox auf:

AimController {
    id: rightAim
    controller: XrController.RightController
    view: xrView
    enableVirtualMouse: true
    enableThumbstickMove: thumbCheckBox.checked

    onObjectPressed: (obj, pos, dir) => {
        gadgetBox.handlePress(obj, pos, dir)
    }
    onHoveredObjectChanged: {
        gadgetBox.handleHover(hoveredObject)
        hapticFeedback.handleHover(hoveredObject)
    }
    onMoved: (pos, dir) => {
        gadgetBox.handleMove(pos, dir)
    }
    onReleased: {
        gadgetBox.handleRelease()
    }
    onObjectGrabbed: (obj) => {
        if (!grabCheckBox.checked)
            return
        const gadget = obj as XrGadget
        if (!gadget)
            startGrab(obj)
        else if (gadget.grabbable)
            startGrab(gadget.controlledObject)
    }
    Model {
        source: "#Cylinder"
        scale: "0.05, 0.1, 0.05"
        z: 5
        eulerRotation.x: 90
        materials: PrincipledMaterial {
            baseColor: "black"
        }
    }
    xrCursor: cursor
}

Wir geben auch eine haptische Rückmeldung, wenn sich das Objekt oder Gadget, über dem man schwebt, ändert:

XrHapticFeedback {
    id: hapticFeedback
    controller: XrHapticFeedback.RightController
    hapticEffect: XrSimpleHapticEffect {
        amplitude: 0.5
        duration: 30
        frequency: 3000
    }
    property Model prevObj: null
    function handleHover(obj: Model) {
        if (obj && obj !== prevObj)
            start()
        prevObj = obj
    }
}

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.