Qt Quick 3D - XR 3D 상호 작용 예시
Qt Quick 3D XR로 3D 객체를 조작하는 방법을 보여줍니다.
이 예제에서는 장면에서 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)
가젯
handleControllerPress
과 handleControllerMove
라는 두 개의 함수가 있는 추상 컴포넌트인 XrGadget
를 정의합니다. 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.