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 } }
© 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.