Qt Quick 3D - XR 3D 交互示例
演示如何使用Qt Quick 3D XR 操作三维对象。
该示例展示了如何创建可移动和调整场景中 3D 物体大小的组件。它使用了与xr_input示例相同的光线选取策略。
控制器输入
在本示例中,我们创建了一个名为AimController
的可重用组件。该组件可执行光线选取来选择模型,并允许用户抓取所选模型并进行移动。
AimController
该组件定义了信号,允许我们实现自定义交互:
property Model hoveredObject: null signal objectPressed(obj: Model, pos: vector3d, direction: vector3d) signal moved(pos: vector3d, direction: vector3d) signal released() signal objectGrabbed(obj: Model)
小工具
我们定义了一个抽象组件XrGadget
,它有两个函数:handleControllerPress
和handleControllerMove
。在 C++ 中,这些函数是虚拟的。由于本示例完全是用 QML 实现的,因此我们使用了可在子组件中处理的信号。
例如,TranslateGadget
根据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) }
可重复使用的组件
我们将AimController
和小工具放在单独的子项目xr_shared
中,以便在未来的示例中重复使用。(xr_shared
还包括自由形式传送示例中的FreeformTeleporter
组件)。
将所有组件连接在一起
我们定义了一个组件GadgetBox
,它可以跟踪被选中的对象,并在被选中的对象周围显示一个半透明框,此外还可以显示对象周围的小工具。按下选定对象时,GadgetBox
将在三种不同类型的小工具(平移、旋转和调整大小)之间循环。
在main.qml
中,我们对来自AimController
的信号做出反应,并调用GadgetBox
中的函数:
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 }
当悬停对象或小工具发生变化时,我们还会提供触觉反馈:
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.